Mostrar un formulario de una capa, navegando entre los registros seleccionados, usando scripting en gvSIG 2.1

Hola a todos…

Ayer preguntaron por la lista de usuarios de gvSIG una duda sobre como hacer una cosilla con scripting.

Básicamente lo que se pretendía era presentar un formulario personalizado usando un script que mostrase los datos del registro seleccionado de una capa, y si habían varios registros seleccionados, con botones de primero/anterior/siguiente/último ir presentando los distintos registros seleccionados.

Le ha añadido alguna cosilla extra y aquí dejo una posible implementación de ello. Lo que he añadido es que si no hay registros seleccionados te permita moverte por todos los registros de la capa.

La idea es que cuando cargamos el formulario, cogemos los registros seleccionados y nos los guardamos en una lista para poder ir recorriéndolos luego fácilmente. Esto que con los registros seleccionados puede ser mas o menos aceptable, si estamos recorriendo todos los registros de una tabla puede resultar inviable, ya que la tabla puede tener muchísimos registros y no los vamos a cargar todos en memoria. También podría pasarnos lo mismo si seleccionamos miles de registros, aunque no suele ser tan usual.

Voy a comentar solo el trozo que se encarga de trabajar con toda la tabla ya que es el más “oscuro“, por decirlo de alguna manera. Como he dicho cargar todos los registros de una tabla en una lista puede no ser viable por tamaño de la tabla, así que en gvSIG tenemos la posibilidad de usar un mecanismo de paginación sobre la tabla y que nos la muestre como una lista continua, a pesar de que este “paginador” se encargara de cargar y descargar los registros que precise en función del tamaño de página que hallamos indicado. El código sería el correspondiente a la función CargarTodaLaTabla.

def cargarTodaLaTabla(tabla):
  # Obtengo un paginador basado en la tabla de datos, paginando de 200 en 200 registros.
  paginador = DALLocator.getDataManager().createFeaturePagingHelper(tabla,200)
  # Obtengo una lista paginada a partir del paginador.
  return paginador.asList()

El código al final es muy simple. Llamamos a una función a la que le pasamos la tabla y el numero máximo de registros que queremos que estén cargados simultáneamente de ella en memoria:

paginador = DALLocator.getDataManager().createFeaturePagingHelper(tabla,200)

y luego le decimos al paginador que hemos obtenido que nos devuelva una lista basada en él.

return paginador.asList()

Esta lista ya podemos manejarla como si se tratase de una lista normal, solo que el paginador se encargará de recuperar los registros de disco según los vaya necesitando.

No voy a contar muchas más cosas, creo que el resto del código es suficientemente claro si ya se ha estado trasteando con python y el entorno de scripting de gvSIG.

Para el ejemplo he utilizado la capa zonas_basicas_salud, que podéis descargar de:

http://downloads.gvsig.org/download/geodata/vector/SHP2D/zonas_basicas_salud.navarra.zip

Y para no enredarme con mas cosas he asumido que es la capa seleccionada cuando se lanza el script.
El resultado del script seria algo parecido al de la siguiente captura

resultado

Y el script completo sería:


from gvsig import *

from org.gvsig.fmap.dal import DALLocator

tabla = None
datos = None
registroActual=0

def cargarRegistro():
  codzona = dialog.find("codzona")
  area = dialog.find("area")
  zona = dialog.find("zona")
  sector = dialog.find("sector")
  actual = dialog.find("actual")
 
  registro = datos[registroActual]
 
  dialog.setString(codzona,"text", "%s" % registro.get("CodZona"))
  dialog.setString(area,"text", registro.get("Area"))
  dialog.setString(zona,"text", registro.get("Zona"))
  dialog.setString(sector,"text", registro.get("Sector"))

  dialog.setString(actual,"text", "%d / %d" %(registroActual+1, len(datos)) )

  #seleccionarRegistro(registro)

def seleccionarRegistro(registro):
  seleccion = tabla.getFeatureSelection()
  seleccion.deselectAll()
  seleccion.select(registro)

def cargarTodaLaTabla(tabla):
  # Obtengo un paginador basado en la tabla de datos, paginando de 200 en 200 registros.
  paginador = DALLocator.getDataManager().createFeaturePagingHelper(tabla,200)
  # Obtengo una lista paginada a partir del paginador.
  return paginador.asList()

def cargarLaSeleccion(tabla):
  datos = list()
  seleccion = tabla.getFeatureSelection()
  for registro in seleccion.iterator():
     datos.append(registro)
  return datos
 
def onload(*args):
  global datos
  global tabla
  # Por comodidad asumo que la capa corriente es la de zonas_basicas_salud
  layer = currentLayer()
  # Obtengo la tabla asociada a la capa
  tabla = layer().getFeatureStore()

  seleccion = tabla.getFeatureSelection()
  if seleccion.isEmpty():
    datos = cargarTodaLaTabla(tabla)
  else:
    datos = cargarLaSeleccion(tabla)
  registroActual=0  
  cargarRegistro()
 
def siguiente():
  global registroActual
 
  if registroActual<len(datos)-1 :
    registroActual +=1
    cargarRegistro()
    
def anterior():
  global registroActual
 
  if registroActual>0 :
    registroActual -=1
    cargarRegistro()
    
def primero():
  global registroActual
 
  registroActual = 0
  cargarRegistro()
        
def ultimo():
  global registroActual
 
  registroActual = len(datos)-1
  cargarRegistro()
    

Os dejo también aquí el xml del formulario para que sepáis a que hacen referencia los nombres que uso en el código:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- generated by ThinG, the Thinlet GUI editor -->
<panel columns="1" gap="4">
    <panel columns="2" gap="2">
        <label text="Codigo de zona"/>
        <textfield name="codzona" weightx="1"/>
        <label text="Area"/>
        <textfield name="area"/>
        <label text="Zona"/>
        <textfield name="zona"/>
        <label text="Sector"/>
        <textfield name="sector"/>
    </panel>
    <panel gap="2">
        <label text="  "/>
        <button action="primero" name="primero" text="Primero"/>
        <button action="anterior" name="anterior" text="Anterior"/>
        <textfield editable="false" end="3" name="actual" start="3" text="0/0"/>
        <button action="siguiente" name="siguiente" text="Siguiente"/>
        <button action="ultimo" name="ultimo" text="Ultimo"/>
        <label text="  "/>
    </panel>
</panel>

Un saludo a todos y espero que os sea de utilidad

About Joaquin del Cerro

Development and software arquitecture manager at gvSIG Team. gvSIG Association
This entry was posted in development, gvSIG Association, gvSIG Desktop, gvSIG development, scripting, spanish. Bookmark the permalink.

5 Responses to Mostrar un formulario de una capa, navegando entre los registros seleccionados, usando scripting en gvSIG 2.1

  1. Pingback: Mostrar un formulario de una capa, navegando entre los registros seleccionados, usando scripting … | Geo-How-To News

  2. german says:

    Lo siento, pero no me va el script. De verdad es correcto? Descargué incluso el zip de ejemplo pero al seleccionar algún elemento del shp y hacer correr el script no me abre el formulario

    • Joaquin del Cerro says:

      hola german,
      en el articulo he asumido que estas familiarizado con el plugin de scripting de gvSIG
      y no he contado algunas cosas.
      He supuesto que sabes crear formularios desde scriptig. Para que esto funcione
      debes crear un script de tipo dialog, y pegar el codigo en la pestaña de codigo,
      pero el formulario deberas cearlo tu desde el editor. No lo puedes copiar/pegar
      desde el texto del artiulo.
      He incluido el xml para que puedas ver los componentes que he credo yo
      en el formulario, que nombres les he dado y que acciones les he asociado,
      pero el formulario deberas crearlo tu con al menos esos btones y cajas de texto.

      un saludo
      Joaquin

  3. Pingback: How to work with a form, browsing selected records using scripting in gvSIG 2.1 | gvSIG blog

Leave a comment