Resumindo valores de polígonos vizinhos usando QGIS?


11

Espero que você possa me ajudar com o seguinte problema: Eu tenho uma camada de vetor (polígono). Gostaria de adicionar um atributo à camada que - para cada polígono - some os valores de um campo específico de todos os seus polígonos vizinhos.

Para dar um exemplo mais concreto: tenho uma camada poligonal de distritos que contém informações sobre população. Agora, para cada distrito, gostaria de saber quantas pessoas vivem em todos os distritos vizinhos.

Como tenho mais de 300 distritos, não posso fazer isso manualmente para cada distrito.

Existe alguma maneira de fazer isso de forma mais eficiente no QGIS?

Respostas:


8

Esse tipo de coisa é melhor feito com Spatialite e SQL.

Primeiro, você precisará carregar seus dados em um banco de dados Spatialite, o que pode ser feito usando o plug-in DBManager que acompanha o QGIS. Clique no botão Importar Layer/File button.

Com seus dados em um banco de dados, você pode executar a seguinte consulta usando o SQLbotão Você apenas precisará alterar os nomes das colunas e tabelas para se adequar aos seus dados.

SELECT COALESCE(SUM(a2.pop),0) as pop_neighbours, 
        a1.pop, 
        a1.name, 
        a1.id, 
        a1.geomm FROM areas a1
LEFT OUTER JOIN areas a2 ON NOT a1.id = a2.id 
                            AND intersects(a2.geomm, a1.geomm)
GROUP BY a1.id

Informe a ferramenta de consulta sobre sua coluna de identificação exclusiva (id) e a coluna de geometria (geomm) e clique em carregar.

Você deveria ter algo assim, depois de rotular, é claro

insira a descrição da imagem aqui

A divisão da consulta

Estamos juntando a camada a ela mesma usando:

LEFT OUTER JOIN areas a2 ON NOT a1.id = a2.id 
                            AND intersects(a2.geomm, a1.geomm)

mas apenas onde as geometrias se cruzam e os IDs não são os mesmos; caso contrário, terminamos com o mesmo registro duas vezes para cada polígono. Também estamos usando um LEFT OUTER JOINpara incluir os registros que não se juntam, ou seja, não têm vizinhos.

Na parte selecionada:

SELECT COALESCE(SUM(a2.pop),0) as pop_neighbours, 
            a1.pop, 
            a1.name, 
            a1.id, 
            a1.geomm

estamos usando COALESCEpara converter NULLS(sem vizinhos) em um 0caso contrário eles simplesmente ficam NULL.

Então, apenas GROUP BY a1.idobtemos um único registro para cada polígono.


Nathan, muito obrigado pela sua resposta e explicações úteis. Ele funcionou mesmo para um iniciante espacial e sql total!
28412 Alex

+1 A seção "quebra de consulta" é bem feita e muito útil.
whuber

@ Alex coisas boas. Não se esqueça de marcar o botão Aceitar.
Nathan W

2

Outra maneira de fazer isso é no GRASS (usando a caixa de ferramentas GRASS ou diretamente no GRASS). No exemplo abaixo, a camada EA é uma camada vetorial com países e, na tabela de atributos, uma coluna com a população por país. Veja este post para uma explicação mais detalhada.

Etapa 1) Crie uma nova camada com a tabela de atributos vinculada aos limites, com duas colunas com IDs de polígonos que delimitam a linha do limite à esquerda e à direita, respectivamente

v.category EA out=EAc layer=2 type=boundary option=add
v.db.addtable EAc layer=2 col="left integer,right integer"
v.to.db EAc option=sides col=left,right layer=2 type=boundary

Etapa 2) Execute um SQL para criar uma tabela que vincule os IDs do país à soma da população de todos os países vizinhos:

db.execute sql="CREATE TABLE tmp AS
SELECT ID, sum(pop) as population FROM (
SELECT DISTINCT EAc_2.left as ID, EAc.pop as pop
FROM EAc_2
LEFT JOIN EAc ON EAc_2.right = EAc.cat
WHERE EAc_2.left > -1 AND EAc_2.right > -1
UNION
SELECT DISTINCT EAc_2.right as ID, EAc.pop as pop
FROM EAc_2
LEFT JOIN EAc ON EAc_2.left = EAc.cat
WHERE EAc_2.left > -1 AND EAc_2.right > -1
) GROUP BY ID"

Etapa 3) Associe a nova tabela tmp à tabela de atributos original.

v.db.join map=EA@ConsStat layer=1 column=cat otable=tmp ocolumn=ID

A tabela de atributos da sua camada vetorial agora deve ter uma coluna extra com a população resumida de todos os países vizinhos.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.