Encontrando programaticamente polígonos que são> 90% sobrepostos por outra camada de polígono vetorial usando QGIS?

9

Camadas de exemplo

Estou tentando descobrir como usar python para extrair os polígonos em um vetor que se sobrepõem> 90% por outro vetor. Eu gostaria de ter um vetor / mapa que mostre apenas esses polígonos. A imagem de exemplo mostra minhas camadas. Quero todos os polígonos cinza> 90% vermelhos.

Eu preciso fazer isso tudo via python (ou métodos automatizados da mesma forma). Eu tenho ~ 1000 mapas para processar da mesma maneira.

anormal
fonte
Você deseja fazer uma sobreposição de 'união' (consulte infogeoblog.wordpress.com/2013/01/08/geo-processing-in-qgis para obter alguns princípios básicos) e, para cada polígono original, calcule as estatísticas 'dentro' e 'fora' gis.stackexchange.com/questions/43037/... para determinar a sobreposição por cento ... dica: você precisa ter uma medição da área gis.stackexchange.com/questions/23355/...
Michael Stimson
Obrigado pelas dicas. Essa é a mesma abordagem que eu estava apenas tentando. Eu posso fazer a união através do console python com bastante facilidade. Já adicionado nos valores de atributo da área. É o próximo passo que não tenho certeza. Como uso o python para calcular as estatísticas 'dentro' e 'fora' para que eu possa identificar / selecionar / recortar etc. os polígonos> 90%?
dnormous 30/05
Eu acho que é possível sem python. Você precisa absolutamente de python ou uma solução com camadas virtuais é boa para você?
Pierma 30/05
As áreas 'in' terão atributos de ambos os polígonos, as áreas 'out' terão apenas atributos de um conjunto de polígonos. Obtenha os dois conjuntos de estatísticas de área e retorne aos polígonos originais, adicione um campo para 'in', 'out' e cobertura, calcule os valores para 'in' e 'out' da soma das áreas e divida 'in' por a área original (ou 'in' + 'out') para calcular a porcentagem.
Michael Stimson
11
Pierma - Eu só preciso de um método automatizado para encontrar os polígonos.
dnormous 30/05

Respostas:

3

O próximo código funciona no meu console Python do QGIS. Produz uma camada de memória com polígonos que são> 90% sobrepostos por áreas vermelhas.

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)

Eu tentei o código com essas duas camadas de vetor:

insira a descrição da imagem aqui

Após a execução do código no Python Console do QGIS, para corroborar os resultados, foram impressos os índices i, j dos recursos envolvidos, áreas de interseção, atributo de campo em polygons_intersects (1 para áreas vermelhas e 2 para áreas cinza) e o critério de sobreposição .

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

A camada de memória criada (recursos verdes) pode ser observada na próxima imagem. Foi como esperado.

insira a descrição da imagem aqui

xunilk
fonte
5

Aqui uma solução que não requer python.

Adicione uma nova camada virtual com uma 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

Com:

  • Basins800 como sua camada, você deseja filtrar com polígonos cinza

  • Gravidade: sua camada vermelha se sobrepõe.

O resultado será uma nova camada com apenas todos os plolígonos cinza> 90% sobrepostos por polígonos vermelhos, com um novo campo contendo a porcentagem de sobreposição.

insira a descrição da imagem aqui

Espero que isso funcione. Posso adicionar mais detalhes sobre a consulta, se necessário.

Nota: Seus dados contêm polígonos muito pequenos (provenientes do processamento de varredura e correspondentes a um pixel de varredura (na imagem, podemos ver 4 polígonos, mas existem outros 25 polígonos pequenos), o que torna a consulta muito lenta de executar (função de interseção) gera um recurso para cada par de recursos das duas camadas).

Pierma
fonte
Estou recebendo um erro ao executar a consulta através do botão 'criar uma camada virtual'. "Erro de execução de consulta no comando CREATE TEMP VIEW _tview AS WITH r AS (" .... restante do código aqui ... seguido por: "1 - próximo a" WITH ": erro de sintaxe" Eu sou bastante novo no QGIS. Posso criar esta camada virtual programaticamente Obrigado por sua ajuda!
dnormous
Aqui está um link para baixar os shapefiles: ligação
dnormous
Desculpe, uma cópia ruim entre cinza e cinza (desculpe pelo meu inglês aproximado). Eu editei a consulta. Deve funcionar agora. Por que você deseja criar a camada de forma programática? As vantagens da camada virtual é que ela não é destrutiva e, se você editar seus dados (polígonos cinza ou vermelho), a camada virtual será atualizada automaticamente.
Pierma 30/05
Este é apenas um pequeno pedaço do processo. Eu tenho ~ 1000 desses mapas para fazer, portanto, automatizar o processo será extremamente útil.
dnormous 30/05
Ainda estou recebendo o mesmo erro -> "1 - próximo a" WITH ": erro de sintaxe". Liguei os nomes locais de cada camada para o grayLayer e redLayer. O nome local é o que devo usar? ou seja: a camada cinza é rotulada como "Basins_800", então eu tenho um código como "Basins_800.geometry"
dnormous
2

Depois de ver o link para os shapefiles de Gravidade e Basins800 , eu pude entender o geoprocesso necessário. Eu modifiquei o código em:

Encontrando programaticamente polígonos que são> 90% sobrepostos por outra camada de polígono vetorial usando QGIS?

para obter 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)

Após executar o código, com esses shapefiles no Python Console do QGIS, em alguns minutos obtive um resultado semelhante ao Pierma ; onde a camada de memória tinha 31 características (diferentes de 29 polígonos obtidas por ele).

insira a descrição da imagem aqui

Não vou depurar os resultados porque existem 1901 * 3528 = 6706728 interações para recursos. No entanto, o código parece promissor.

xunilk
fonte