archivo

Archivo de la etiqueta: scripting

dialogPDF01

El otro día salió publicado en el Blog de gvSIG un post de Joaquin del Cerro sobre como abrir un PDF en un visor dentro de gvSIG desde el módulo de scripting. Así que aprovechando la nueva opción de Dialog de la nueva build de gvSIG he decidido hacer un pequeño ejemplo que lo junte todo. También gracias a la ayuda de unos ejemplos realizados por Victor Acevedo.

Los que os lo habéis perdido podéis echar un vistazo a mi anterior post donde explico todo este nuevo apartado paso a paso.

El script consiste en una ventana que al seleccionar una entidad en la capa y hacer click sobre el botón de “Info” nos sacará toda la información de esa entidad en la caja de texto. Podéis ver que el botón de PDF se encuentra desactivado por ahora.

dialogPDF02

Además, si existe un campo llamado “PDF” haremos que se active el botón de PDF, y al presionarlo, nos abrirá el visor que os comentaba al PDF enlazado. Está todo muy simplificado para hacerlo más entendible.

dialogPDF03

El código correspondiente al dialog es:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- generated by ThinG, the Thinlet GUI editor -->
<panel colspan="0" columns="1" gap="1" height="156" rowspan="3" scrollable="true" width="300">
    <panel columns="2">
        <label text="Info"/>
    </panel>
    <panel colspan="2" columns="2" rowspan="0" weightx="1" weighty="1">
        <textarea colspan="2" columns="36" editable="false" halign="center" height="1" name="txtArea" rows="6" valign="center"/>
    </panel>
    <panel>
        <button action="verInfo" name="btnInfo" text="Info"/>
        <button action="verPDF" enabled="false" name="btnPDF" rowspan="2" text="PDF"/>
    </panel>
</panel>

Y el código que ejecuta es:

from gvsig import *
from org.gvsig.tools import ToolsLocator
from org.gvsig.tools.swing.api import ToolsSwingLocator
from java.net import URI

def onload(*args):
    """Dialog info de entidad y abrir pdf"""

    global rutapdf
    rutapdf = "C://gvsig/testpuntos/"
    pass

def verInfo():
    #Accion del boton Info

    feature = iter(currentLayer().getSelection()).next()

    info = currentLayer().name
    schema = currentLayer().getSchema().getAttrNames()
    for sch in schema:
        info += "\n" + str(sch) + "    " + str(feature.get(sch))

    btnPDF = dialog.find("btnPDF")

    try:
         if feature.get("PDF"): dialog.setBoolean(btnPDF, "enabled", True)
    except:
         dialog.setBoolean(btnPDF, "enabled", False)

    txt = dialog.find("txtArea")
    dialog.setString(txt, "text", info)

def verPDF():
    #Accion del boton PDF
    feature = iter(currentLayer().getSelection()).next()
    name = feature.get("PDF")
    ruta = rutapdf + name
    visorPDF(ruta)

def visorPDF(rutaAbsoluta):
    formatManagers = ToolsLocator.getExtensionPointManager().get("HyperLinkAction")
    pdfManager = formatManagers.get("PDF_format").create()
    panel = pdfManager.createPanel(URI("file:/"+rutaAbsoluta))
    windowManager = ToolsSwingLocator.getWindowManager()
    windowManager.showWindow(panel,"Visor PDFs",windowManager.MODE.WINDOW)

Para cualquier duda me la podéis consultar en los comentarios o por email.

dialog00

Te permite crear ventanas a medida

Acaba de salir una nueva build para  gvSIG 2.1.0.2217 en fase de desarrollo en la que se han realizado grandes mejoras en el módulo de Scripting y tiene varias novedades que iremos anunciando próximamente. Al estar en fase de desarrollo se agradece que reportéis todos los bugs que podáis encontrar.

Una nueva característica (que ya estaba implementada pero no funcionaba correctamente) que podemos encontrar es el módulo de diálogos. Este módulo dentro del apartado de scripting nos permitirá crear fácilmente ventanas interactivas con etiquetas, cajas de texto, opciones, botones, etc. Las posibilidades son infinitas. Esto aumenta en gran medida la forma de interactuar con nuestro script, así como aumentar las capacidades del mismo.

·

Cómo crear un script de tipo Dialog

Para empezar a probar estos scripts lo que necesitamos es:

  • Nueva build en desarrollo de gvsig, minimo la versión 2.1.0.2217
  • Instalar el módulo de Scripting en el Administrador de complementos
Dentro de: Herramientas - Administrador de complementos

Dentro de: Herramientas – Administrador de complementos

dialog02

Con esto ya podemos ir a Herramientas – Scripting – Scripting Composer.

Al crear un nuevo script, lo que debemos de cambiar ahora es el Type y seleccionar Dialog en vez de Script que es lo que estamos acostumbrados.

Nos aparecerá un nuevo script en la pantalla en blanco, parece todo similar aunque podemos ver que existen un par de diferencias. Si nos fijamos existen unas pestañas extras a los que no estamos acostumbrados. Estos scripts constan de dos partes (cuando se almacenan también constan de dos archivos), una parte se encarga de la creación de la ventana y de las características que tiene, y otra parte es el código que ejecuta este script.

dialog03

Podemos ver un Menu (#1) nuevo arriba que nos servirá para editar, cargar, etc, este tipo nuevo de scripts. Podemos ver la lista de objetos (#2) que contiene el formulario , aquí iremos añadiendo los nuevos botones y demás. En las pestañas (#3) podemos encontrar dos, una pestaña XML que nos sirve para ver nuestro diálogo en texto plano, también para pegar uno que nos pasen hecho, y la pestaña de Preview, que nos sirve para previsualizar directamente nuestro formulario. En las pestañas de código (#4) podemos cambiar entre Dialog (edición de la parte de diálogo) y Code (edición del código que ejecuta).

Nuestro primer Dialog

El siguiente paso es dar click sobre el Panel que nos aparece en la lista de objetos del formulario (#2). Al hacer click sobre este se nos cambia la barra de herramientas y nos aparecen un grupo nuevo con todas las opciones que tenemos, desde botones, combobox, cajas de text, listas…

dialog04

dialog05Para hacer un pequeño script de prueba, vamos a empezar por añadir un nuevo dialog a nuestro panel (es el segundo botón de la lista), esto va a crear una ventana (dialog) donde aparecerán todos los objetos que queramos. Para crear una etiqueta dentro de esta nueva ventana, hacemos click en el dialog que nos acaba de aparecer en la lista, y ahora damos click al boton que pone label. Nos aparecerá un nuevo objeto en la lista, y si hacemos click podemos acceder a sus propiedades como podemos ver en la imagen.

Podemos ir al campo text y cambiar el texto que contendrá. Al presionar Enter nos modificará el valor de la etiqueta, y la podremos ver ya en la pestaña de Preview. También en la propiedad name podemos escribir etiqueta1, esto nos permitirá más tarde poder encontrar y modificarla desde el botón.

Ahora siguiendo el mismo paso vamos a crear un botón que nos permitirá ejecutar acciones. Haciendo click primero en el dialog, y luego sobre “Create new button” a la derecha del botón de label. Editaremos sus propiedades y iremos a text = “Consola” y la propiedad de action o acción escribiremos “abrirConsola”, esto lo veremos ahora.

Escribir el código a ejecutar

Una diferencia con los scripts normales, es que el código de este tiene una estructura algo diferente, y es obligado que conste de una función onload(), al contrario que en los scripts normal que se denomina main().

Así que podemos borrar el código que nos aparece y sustituirlo por este:

from gvsig import *

def onload():
    pass

Este sería el código mínimo para lanzar un script de tipo dialog.

Esto que vamos a hacer es solo un ejemplo, pero las posibilidades son muy grandes, podemos crear botones que nos muestren información de las capas que tengamos, botones que nos modifiquen los valores de cajas de texto para mostrar información, que nos permitan lanzar filtros para hacer selecciones fácilmente ajustando barras que creemos, etc.

Para editar lo que hará nuestro botón tenemos que crear una función “abrirConsola”, esta se lanzará al presionar el botón tal y como indicamos en su propiedad de action.

Para que abra la consola desde el botón tenemos que importar una librería console. Así que el código podría quedar algo así:

from gvsig import *
from console import console

def onload():
    pass

def abrirConsola():
    #Abre la consola de Jython
    console.main()

    #Modifica el valor text de la etiqueta
    lblEtiqueta = dialog.find("etiqueta1")
    texto = "Consola abierta!"
    dialog.setString(lblEtiqueta,"text", texto)

También podéis pegar el XML (para la configuración del dialogo) directamente desde su pestaña. Si copias este de ejemplo y vais a la pestaña del XML, en el menú nuevo que nos aparece podemos hacer click en Edit – Paste from System Clipboard y ya tendremos el dialog que he creado aquí.

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- generated by ThinG, the Thinlet GUI editor -->
<panel>
    <dialog>
        <label name="etiqueta1" text="Script de prueba"/>
        <button action="abrirConsola" text="Consola"/>
    </dialog>
</panel>

El resultado como podéis ver al ejecutar este script es el siguiente, primero nos aparece una pantallita..

dialog06

…y al presionar el botón se nos cambia la etiqueta y se nos abre la consola.

dialog07

Próximamente realizaré algún ejemplo más elaborado y más aplicado a nuestro proyecto, pero lo básico está explicado, podéis crear un dialog y modificar sus propiedades, acepto sugerencias para scripts y no olvidéis que está en fase de desarrollo así que si veis algún bug podéis reportarlo a la página de gvsig.

gmailpythonsimple

Merodeando por Internet encontré una página con contenido muy interesante “Pythin, GIS and Stuff”, en ella vi un código que ya había pensado en buscar y es la opción de poder enviar un email con los resultados a nuestra cuenta desde el propio script. Y esto se hace de una forma muy sencilla. He simplificado un poco el de su web para que podáis pegar y copiar directamente sea cual sea la plataforma que vais a usar (en su web ejemplo de uso con ArcGIS).

Al ser una librería de Python, este código funciona desde cualquier sitio donde lo ejecutes, puedes agregarlo a scripts de OGR/GDAL desde editores externos,o a tus scripts en gvSIG, PyQGIS o ArcPy. En todos funciona perfectamente por lo que he podido probar.

Lo único que necesitamos introducir es la información una cuenta Gmail, la contraseña, y la cuenta destinatario. (Cuidado si le mandáis a alguien el script con eliminar la contraseña).

La función aceptará dos variables, el mensaje (una variable tipo string) y una variable booleana (True/False) por si queremos modificar el contenido de alguna forma, en este caso solo indica un supuesto de si se han procesado bien o mal los cálculos, cambiando el encabezado del email.

·

pythonemail

·

Además se ha añadido que la variable se cargue con los datos de un txt que hallamos podido crear. Esto se puede eliminar, solamente dejando que se asigne el valor de una variable string normal, asignar directamente a strResult un valor.

Copiando y pegando este bloque de código solamente deberéis de usarlo llamandolo de la forma:

sendResultEmail(strResult, success)

·

import smtplib

def sendResultEmail(msgContents, success_TF):
    '''sendResultEmail(msgContents, success_TF)'''

    #Info
    to = 'email@gmail.com'
    send_username = 'email@gmail.com'
    send_password = '*****'
    smtpserver = smtplib.SMTP("smtp.gmail.com",587)

    if success_TF:
        subject = 'Resultados de la prueba de email: script SUCCESS.'
    else:
        subject = 'Resultados de la prueba de email: script FAILURE.'
    smtpserver.ehlo()
    smtpserver.starttls()
    smtpserver.ehlo
    smtpserver.login(send_username, send_password)
    header = 'To:' + to + '\n' + 'From: ' + send_username + '\n' + 'Subject:' + subject + '\n'
    msg = header + '\nArcpy results: \n' + msgContents + '\n'
    smtpserver.sendmail(send_username, to, msg)
    smtpserver.close()

outTxt = "c:/gvsig/uni/dataInfo.txt"
txtFile = open(outTxt, "r")
strResult = txtFile.read()
txtFile.close()
success = True

sendResultEmail(strResult, success)

centrarvistas01Un script muy sencillo y que puede ser muy útil. Ejecutando el código nos recorrerá todo el proyecto que tengamos abierto, Vista a Vista, y hará un zoom o centrar vista a la primera capa que aparezca en cada una de ellas.

Así, de una tirada, podremos tener bien situadas todas las Vistas de un Proyecto.

from gvsig import *

def main():
    #Centrar todas las vistas de un proyecto
    #zoomViews.py / @masquesig

    views = currentProject().getViews()
    for view in views:
      vista = currentProject().getView(str(view))
      layer0 = vista.getLayers()[0]
      env = layer0.getFullEnvelope()
      centrarVistaEnv( vista, env)
      print vista.name," centrada en ", vista.getLayers()[0].name

def centrarVistaEnv(vista,env):
    vista.getMap().getViewPort().setEnvelope(env)

Inicial:

centrarvistas02

Final, después de ejecutarlo:

centrarvistas03

Si quieres realizar el zoom a la extensión total de las capas, en vez de a la primera capa, el código sería el siguiente:

from gvsig import *

def main():
    #Centrar todas las vistas de un proyecto
    #zoomViewsEnvelope.py / @masquesig

    views = currentProject().getViews()
    for view in views:
      vista = currentProject().getView(str(view))
      centrarEnvelope(vista)
      print vista.name," centrada."

def centrarEnvelope(vista):
    envelope = vista.getMap().getLayers().getMapContext().getFullEnvelope()
    vista.getMap().getLayers().getMapContext().zoomToEnvelope(envelope)

Ya está publicada el vídeo de la Conferencia que realicé durante las 9as Jornadas de gvSIG que se realizaron en Valencia durante el mes de Noviembre/2013. No soy el mejor del mundo explicando, pero os podéis hacer una buena idea de lo que es el módulo de Scripting ,que puedes hacer con él y en que consiste el proyecto que voy a realizar. También puedes verla en ingles.

Dar las gracias a todos por vuestro apoyo durante las Jornadas! Tanto al equipo de gvSIG como a todos los que colaboran con el proyecto.

 

Y aquí el pase de diapositivas que utilicé:

cargarCapaHoy vamos a comentar un par de lineas de código muy útiles para poder añadir una capa existente de nuestro ordenador a nuestra Vista desde el módulo de Scripting, de una forma sencilla seleccionando el archivo en un cuadro dialogo, y de paso sacar algo de información sobre la nueva capa agregada.

La función que permite cargar una capa ya existente a nuestra Vista actual es loadShapeFile. Esta función consta de dos parámetros, la ruta y la proyección. Lo recomendable sería utilizar, como en el ejemplo de abajo, la proyección utilizada en la Vista donde queremos añadir la capa, sino, por defecto nos añadirá la capa como si su proyección fuera WGS84:

layer = loadShapeFile(<rutaCapa>,[CRS=WGS84])

cargarCapa2

Nosotros, para facilitar la obtenención de la ruta al archivo que queremos, hemos utilizado un ventana de diálogo. En la función introducir el título y la ruta inicial que queramos por defecto, el resultado lo pasaremos como ruta a la función anterior:

openFileDialog("Titulo","C:/gvsig/")

Y el script que hemos hecho, y que permite agregar una capa que seleccionemos a la vista actual es:

from gvsig import *
from commonsdialog import *

def main():
    """Cargar una capa existente"""

    ruta = openFileDialog("Ruta","C:/gvsig/")
    capa = list(ruta)[0]
    CRS = currentView().getProjection()
    layer = loadShapeFile(capa,CRS=CRS)

    print "\nCapa cargada con exito!"
    print "Nombre: ",layer.name
    print "Tipo: ",layer.getTypeVectorLayer().name
    print "Entidades: ", layer.features().getCount()
    print "Proyeccion: ", layer.getProjectionCode()