Este 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:
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.



Deja un comentario