¿Encuentra polígonos programáticamente que se superponen> 90% por otra capa de polígonos vectoriales usando QGIS?

9

Capas de ejemplo

Estoy tratando de descubrir cómo usar Python para extraer los polígonos en un vector que se superponen en> 90% por otro vector. Entonces me gustaría tener un vector / mapa que solo muestre esos polígonos. La imagen de ejemplo muestra mis capas. Quiero todos los polígonos grises que son> 90% rojos.

Necesito hacer todo esto a través de Python (o métodos automatizados similares). Tengo ~ 1000 mapas para procesar de la misma manera.

terrible
fuente
Desea hacer una 'unión' de superposición (consulte infogeoblog.wordpress.com/2013/01/08/geo-processing-in-qgis para algunos conceptos básicos) y luego, para cada polígono original, calcule las estadísticas 'adentro' y 'afuera' gis.stackexchange.com/questions/43037/… para determinar el porcentaje de superposición ... sugerencia: debe tener una medición de área gis.stackexchange.com/questions/23355/…
Michael Stimson
Gracias por los consejos. Ese es el mismo enfoque que estaba intentando. Puedo hacer la unión a través de la consola de Python lo suficientemente fácil. Ya agregado en el área de valores de atributo. Es el siguiente paso del que no estoy seguro. ¿Cómo uso Python para calcular las estadísticas de 'entrada' y 'salida' para poder identificar / seleccionar / recortar, etc. los> 90% de polígonos?
2016
Creo que es posible sin python. ¿Necesita absolutamente Python o una solución con capas virtuales es buena para usted?
Pierma
Las áreas 'adentro' tendrán atributos de ambos polígonos, las áreas 'afuera' solo tienen atributos de un conjunto de polígonos. Obtenga ambos conjuntos de estadísticas de área y vuelva a unirse a los polígonos originales, agregue un campo para 'entrada', 'salida' y cobertura, calcule los valores para 'entrada' y 'salida' de la suma de áreas y luego divida 'entrada' por el área original (o 'dentro' + 'fuera') para calcular el porcentaje.
Michael Stimson
1
Pierma: solo necesito un método automatizado para encontrar los polígonos.
2016

Respuestas:

3

El siguiente código funciona en mi consola Python de QGIS. Produce una capa de memoria con polígonos que están> 90% superpuestos por áreas rojas.

mapcanvas = iface.mapCanvas()

layers = mapcanvas.layers()

#for polygon_intersects
feats_lyr1 = [ feat for feat in layers[0].getFeatures() ]

#for xwRcl
feats_lyr2 = [ feat for feat in layers[1].getFeatures() ]

selected_feats = []

for i, feat1 in enumerate(feats_lyr1):
    area1 = 0
    area2 = 0
    for j, feat2 in enumerate(feats_lyr2):
        if feat1.geometry().intersects(feat2.geometry()):
            area = feat1.geometry().intersection(feat2.geometry()).area()
            print i, j, area, feat2.attribute('class')
            if feat2.attribute('class') == 1:
                area1 += area
            else:
                area2 += area
    crit = area1/(area1 + area2)
    print crit
    if crit > 0.9:
        selected_feats.append(feat1)

epsg = layers[0].crs().postgisSrid()

uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           "mem_layer",
                           "memory")

prov = mem_layer.dataProvider()

for i, feat in enumerate(selected_feats):
    feat.setAttributes([i])

prov.addFeatures(selected_feats)

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

Probé el código con estas dos capas vectoriales:

ingrese la descripción de la imagen aquí

Después de ejecutar el código en la Consola Python de QGIS, para corroborar los resultados, se imprimieron los índices i, j de características involucradas, áreas de intersección, atributo de campo en polygons_intersects (1 para áreas rojas y 2 para áreas grises) y el criterio de superposición .

0 0 9454207.56892 1
0 1 17429206.7906 2
0 2 10326705.2376 2
0 4 40775341.6814 1
0 5 26342803.0964 2
0 7 11875753.3216 2
0.432253120382
1 6 1198411.02558 2
1 7 1545489.96614 2
1 10 27511427.9909 1
0.90930850584
2 7 750262.940888 2
2 8 12012343.5859 1
0.941213972294
3 6 23321277.5158 2
0.0

La capa de memoria creada (características verdes) se puede observar en la siguiente imagen. Fue como se esperaba.

ingrese la descripción de la imagen aquí

xunilk
fuente
6

Aquí una solución que no requiere python.

Agregue una nueva capa virtual con una consulta como:

WITH r AS (
SELECT 
    Basins800.rowid AS idGray, 
    area(Basins800.geometry) AS areaGray, 
    area(Intersection(Basins800.geometry, Severity.geometry)) AS aeraInter, 
    Basins800.geometry AS geomGray 
  FROM Basins800, Severity
)

SELECT *, areaInterSum/areaGray  AS overlap , geomGray 
    FROM (
        SELECT 
           idGray, 
           areaGray, 
           sum(areaInter) AS areaInterSum, 
           geomGray 
        FROM r 
        GROUP BY idGray) 
     WHERE areaInterSum/areaGray > 0.9

Con :

  • Basins800 como su capa que desea filtrar con polígonos grises

  • Gravedad: la superposición de su capa roja.

El resultado será una nueva capa con solo todos los polígonos grises> 90% superpuestos por polígonos rojos, con un nuevo campo que contiene el porcentaje de superposición.

ingrese la descripción de la imagen aquí

Espero que esto funcione. Puedo agregar más detalles sobre la consulta si es necesario.

Nota: sus datos contienen polígonos muy pequeños (provenientes de su procesamiento ráster y correspondientes a un píxel ráster (en la imagen, podemos ver 4 polígonos pero hay otros 25 polígonos pequeños). Esto hace que la consulta sea muy lenta de ejecutar (función de intersección genera una entidad para cada par de entidades de las dos capas).

Pierma
fuente
Recibo un error cuando ejecuto la consulta a través del botón 'crear una capa virtual'. "Error de ejecución de consulta en CREATE TEMP VIEW _tview AS WITH r AS (" .... resto del código aquí ... seguido de: "1 - cerca de" WITH ": error de sintaxis" Soy bastante nuevo en QGIS. ¿Puedo crear esta capa virtual mediante programación Gracias por su ayuda?!
dnormous
Aquí hay un enlace para descargar los archivos de forma: enlace
dnormous
Lo siento, una mala copia entre gris y gris (perdón por mi inglés aproximado). Edité la consulta. Debería funcionar ahora. ¿Por qué quieres crear la capa progamáticamente? Las ventajas de la capa virtual es que no es destructiva, y si edita sus datos (los polígonos grises o rojos), la capa virtual se actualizará automáticamente.
Pierma
Esta es solo una pequeña parte del proceso. Tengo ~ 1000 de estos mapas para hacer, por lo que automatizar el proceso será extremadamente útil.
2016
Todavía recibo el mismo error -> "1 - cerca de" WITH ": error de sintaxis". Conecté los nombres locales para cada capa en grayLayer y redLayer. ¿Es el nombre local lo que debería estar usando? es decir: la capa gris está etiquetada como "Basins_800", por lo que tengo un código como "Basins_800.geometry"
2016
2

Después de ver el enlace a los archivos de forma Severity y Basins800 , pude entender el geoprocesamiento necesario. Modifiqué el código en:

¿Encuentra polígonos programáticamente que se superponen> 90% por otra capa de polígonos vectoriales usando QGIS?

por conseguir este:

mapcanvas = iface.mapCanvas()

layers = mapcanvas.layers()

#for Severity
feats_lyr1 = [ feat for feat in layers[0].getFeatures() ]

#for Basins800
feats_lyr2 = [ feat for feat in layers[1].getFeatures() ]

selected_feats = []

print "processing..."

for i, feat1 in enumerate(feats_lyr1):
    for j, feat2 in enumerate(feats_lyr2):
        if feat1.geometry().intersects(feat2.geometry()):
            area1 = feat1.geometry().intersection(feat2.geometry()).area()
            area2 = feat1.geometry().area()
            print i, j, area1, area2
    crit = area1/area2
    print crit
    if crit > 0.9:
        selected_feats.append(feat1)

epsg = layers[0].crs().postgisSrid()

uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           "mem_layer",
                           "memory")

prov = mem_layer.dataProvider()

for i, feat in enumerate(selected_feats):
    feat.setAttributes([i])

prov.addFeatures(selected_feats)

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

Después de ejecutar el código, con estos archivos de forma en la Consola Python de QGIS, en unos minutos obtuve un resultado similar al de Pierma ; donde la capa de memoria tenía 31 características (diferentes de 29 polígonos obtenidos por él).

ingrese la descripción de la imagen aquí

No voy a depurar los resultados porque hay 1901 * 3528 = 6706728 interacciones para las características. Sin embargo, el código parece prometedor.

xunilk
fuente