Scripting en gvSIG: Disolver polígonos hasta que cumplan una condición

disolucion04Este post viene de una sugerencia de script realizada por @LaTorpeda. Lo que estamos buscando es un comando que disuelva polígonos hasta que se cumpla una condición, en este caso es una suma de valores de una de sus columnas. Esta solución aún está inacabada, pero por ahora ya sería útil por alguien que necesitara algo parecido. Imagino que la solución no es exactamente lo que necesitaba pero poco a poco se puede ir sacando.

Ahora mismo, este script lo que hace es, a partir de un polígono seleccionado, coge los de alrededor y los añade a la geometría inicial solo si van cumpliendo la condición de que no superen un limite que podremos fijar en el script que vendrá de la suma de los valores de la columna que hemos comentado. Mientras tanto va haciendo varias iteraciones (que podemos limitar con ‘limiteiteraciones’) de los polígonos de alrededor (cuanto más grande más probabilidades de que el polígono resultante tenga huecos, etc).

El resultado es una nueva capa con el polígono resultante de la unión de los anteriores que cumplen la condición o que han llegado al límite te iteraciones.

Tal vez mejor una explicación gráfica:

disolucion03 disolucion02 disolucion01


from gvsig import *
from geom import *

def main():

    """De un poligono seleccionado, coger poligonos de alrededor 
        hasta que sume cierta cantidad"""
    #INPUT: capa de poligonos con un campo para sumar
    #OUTPUT: capa nueva con el nuevo poligono
    
    features = currentLayer().features()
    #solo una seleccion o varios poligonos
    selection = currentLayer().getSelection()
    output = crearShape()
    global xlimite
    global limite
    xlimite = 0
    limite = 2000
    #cantidad de veces que analiza el contorno del poligono
    limiteiteraciones = 2
    
    #poligono inicial
    if not(selection.getCount() == 1): return
    for fs in selection:
        xlimite += fs.POB_TOTAL
        newGeo = fs.geometry()
    
    if xlimite >= limite: 
        print "Poblacion ya es mayor que el limite"
        return
        
    Stop = 0
    ite = 0
    while Stop == 0:
    #seleccionar alrededores
        candidatos = list()
        for f in features:
            candidatos = alrededorGeo(newGeo,f,candidatos)
            
        global count
        count = 0
        candidatos = currentLayer().getSelection()
        countlimite = candidatos.getCount()
        
        for candi in candidatos:
            newGeo = disolver(newGeo,candi)
        #Si añadimos or (count !=0) solo itere si contiene todas
        #las de alrededor, ayuda en poligonos complicados
        if not (count == 0)  : Stop = 0
        else: 
            print "Stop a 1!"
            Stop = 1
        ite += 1
        if ite == limiteiteraciones: break
        
    values = dict()
    values["ID"] = 1
    values["POB_TOTAL"] = xlimite
    values["GEOMETRY"] = newGeo
    output.append(values)
        
    output.commit()
    currentView().addLayer(output)
    
def alrededorGeo(newGeo,f,candidatos):
    buf = newGeo.touches(f.geometry())
    if newGeo.within(f.geometry()):
        print "la contiene la descartamos"
    elif buf: 
        currentLayer().select(f)
    return candidatos

    
def disolver(newGeo,alre):
    #calcula los poligonos de alrededor
    global xlimite
    global limite
    global Stop
    global count
    campo = alre.POB_TOTAL
    
    exp = xlimite + campo
    if exp < limite:
            newGeo = newGeo.union(alre.geometry())
            xlimite += campo
            count += 1
    return newGeo

    
def crearShape():
    ruta = "C:/gvsig/dissolve/disolucion_01.shp"
    CRS = currentLayer().getProjectionCode()
    schema = createSchema()
    schema.append("GEOMETRY", "GEOMETRY")
    schema.append("ID", "INTEGER", size = 10)
    schema.append("POB_TOTAL", "INTEGER", size = 20)
    output = createShape( schema, ruta, CRS = CRS,
      geometryType=SURFACE)
    return output

Este código lo hice algo rápido, puede que contenga algún error o no me halla explicado bien, para cualquier duda no dudéis en consultarme.

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: