Scripting en gvSIG: Auto-Arrenge, ordena tus capas

autoarrange3Quedan pocos días para las 9as Jornadas de gvSIG y el Taller de Scripting y aquí un script más.

Al preparar el taller me ocurría que haciendo pruebas a veces agregaba muchas capas a una vista y para ordenarlas bien era un poco locura, no sabía bien donde poner una capa si delante o detrás.

autoarrange1Me parece que para ArcPy existe un comando auto-arrenge que organiza la capa en su mejor posición al insertarlas, así que he hecho este script que nos recomiende una forma de ordenarlas. Tendría que ser posible ordenar estas capas desde el módulo de Scripting pero aún no conozco como, más adelante espero actualizar este script para que realmente lo haga todo automáticamente, por ahora solo nos dará una sugerencia por consola, no organizara las capas.

El funcionamiento del script es separar las capas por su tipo según sean superficies, lineas o puntos, dando prioridad en ese orden. En superficies o lineas da prioridad a las de mayor tamaño ya sea área o longitud. También si algunas coinciden en valor o están en un rango que podemos elegir, lo que determinará su posición será por el número de entidades.

Por ejemplo, la capa provincias.shp, autonomia.shp, provincia.shp, comarcas.shp, municipios.shp pese a tener una superficie parecida, la capa de la autonomía estará debajo al disponer de solo una entidad y arriba la de municipios.

autoarrange4Simplemente agregamos todas las capas que queramos a nuestra vista y ejecutamos el script, nos dará una salida parecida a la de la imagen por consola. Muestra:

  • orden
  • tipo (1 – punto, 2 – linea, 3 – superficie)
  • nombre
  • valor (distancia o area, puntos es cero)
  • entidades

Como un pequeño cambio, he hecho que los puntos los recomiende al revés, situar las de mayores puntos debajo de las de menos puntos. Pensé que las capas de tipo punto con muchos puntos suelen tener menos importancia que las de menos por ser tal vez vértices o lugares más importantes. Si no piensas así se puede cambiar.

Ahora solo tendríamos que coger y arrastrar en el orden sugerido cada capa. El resultado sería:

autoarrange2

Y el script que hace esto es:

from gvsig import *
from geom import *

def main():
  """Auto-Arrenge"""
  #Organiza las capas segun las de mayor tamaño, distancia, y entidades
  #Las de tipo punto las organiza al reves, las de mayor tamaño debajo
  #@masquesig
  
  view = currentView()
  layers = view.getLayers()
  listaFinal = list()
  for layer in layers:
    listaFinal.append(ordena(layer))
  listaFinal.sort()
  index = len(listaFinal)
  while True:
      sal = 1
      for i in range(index-1):
        if listaFinal[i][0] == listaFinal[i+1][0]:
            valor = listaFinal[i][1] - listaFinal[i+1][1]
            #Rango de diferencia, da prioridad al numero entidades
            if -10000 < valor < 10000:
                #Podriamos añadir if segun el tipo de capa
                #Si es tipo punto ordenar al contrario
                #Capas con mas puntos debajo
                if not(listaFinal[i][0] == 1):
                   if listaFinal[i][2] < listaFinal[i+1][2]:
                      aux = listaFinal[i+1]
                      listaFinal[i+1] = listaFinal[i]
                      listaFinal[i] = aux
                      sal = 0
                else:
                   #Capas con menos superficies debajo
                   if listaFinal[i][2] > listaFinal[i+1][2]:
                      aux = listaFinal[i+1]
                      listaFinal[i+1] = listaFinal[i]
                      listaFinal[i] = aux
                      sal = 0
      if sal == 1: break
  print "\n"
  
  for lst in listaFinal:
      print index,lst[0], lst[3], lst[1], lst[2]
      index -= 1
  print "\n"
def ordena(layer):
    tipoName = layer.getTypeVectorLayer().name
    if tipoName == "MultiSurface2D" or tipoName == "MultiSurface3D": tipo = 3
    elif tipoName == "MultiCurve2D" or tipoName == "MultiCurve3D": tipo = 2
    elif tipoName == "Point2D" or tipoName == "MultiPoint2D" or tipoName=="MultiPoint3D" or tipoName=="Point3D": tipo = 1
    else: tipo = 0
    features = layer.features()
    numeroEntidades = int(features.getCount())
    dato = 0
    try:
       if tipo == 3:
          for feature in features:
             dato = dato + feature.geometry().area()
       if tipo == 2:
          for feature in features:
             dato = dato + feature.geometry().perimeter()
    except: print "+",
    return [tipo,dato,numeroEntidades,layer.name]
2 comentarios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: