Dividindo muitos polígonos em partes (quase) iguais por meio de um simples script no PyQGIS, o Console Python do QGIS
Colegas pesquisadores e entusiastas do GIS de código-livre,
Primeiramente, bem-vindos ao meu blog!
Gostaria de começar com um aviso - posso ser uma pesquisadora desta área, mas isso não quer dizer que tudo o que faço ou escrevo aqui funcionará para você, em suas próprias configurações de desktop e versões de packages. Não assumo responsabilidade nenhuma se você perder dados ou bagunçar sua instalação. Eu também não autorizo nenhum tipo de cópia do meu conteúdo. Exceto pelos gists no GitHub, que são disponibilizados com a licença do MIT.
Seja qual for o seu geo-trabalho, você pode ter trabalhado com um polígono que precisava ser dividido ao meio, em três partes, em cinco partes (ou em cem partes, talvez?). Duas possíveis aplicações para estes polígonos divididos são o cálculo de estatísticas zonais e parcelamento do terreno (agricultura).
Já existe um pipeline conhecido usado para dividir polígonos no software GIS. Foi desenvolvido por Darafei Praliaskouski para PostGIS e testado por Paul Ramsey (Obrigada!), e está disponível no site do Paul Ramsey. O mesmo pipeline também foi adaptado por Ujaval Gandhi para ser usado no QGIS (através da Interface do Usuário QGIS) e pode ser encontrado no blog dele. Se você está lidando com um pequeno número de polígonos a serem divididos no QGIS, o post recém-mencionado do Ujaval Gandhi pode ser útil para você, especialmente se você não estiver familiarizado com o Console Python do QGIS (PyQGIS).
Você também pode conferir este vídeo no canal do YouTube da Geoaplicada, no qual Jocilene Barros usa o plugin Polygon Divider.
Por que usar o PyQGIS?
Ah, tantas opções! Mas se você ainda está aqui, acho que você quer usar o PyQGIS para esta tarefa. Por que você quereria isso? Listei quatro motivos abaixo:
Você tem muitos polígonos para dividir cada um em partes iguais. Fazer o processo um por um é uma perda de tempo. Honestamente, este foi o meu motivo.
Você não quer instalar mais plugins, mas também não quer gastar muito tempo dividindo polígonos.
Você é um novato/intermediário/avançado em Python e deseja ver um exemplo funcional de como usar o PyQGIS.
Você quer usar apenas ferramentas nativas do QGIS. Este pipeline aqui usa apenas ferramentas nativas.
Um aviso sobre o uso da palavra “Igual”
Os polígonos resultantes gerados por pipelines que envolvem clustering do tipo K-means e polígonos de Voronoi/Thiessen (como o meu pipeline, por exemplo) na maioria das vezes não geram uma divisão perfeita em termos de área. Há um erro associado a cada divisão, que iremos explorar mais adiante, na seção “Verificação dos resultados e erros associados”. Não use meu pipeline se você precisa de polígonos resultantes perfeitamente iguais em termos de área.
Meu pipeline
Para este desenvolvimento, eu estou usando um pipeline ligeiramente diferente do descrito no site do Paul Ramsey, mas eu me inspirei naquele pipeline para construir este.
Meu pipeline, em linhas gerais:
Pré-processamento: Divida o arquivo vetorial original em N outros arquivos, cada um com um polígono.
No PyQGIS: obtenha as extensões da camada vetorial
Gere pontos de espaçamento regulares dentro dessas extensões
Recorte os pontos regulares na área do polígono
Agrupe seus pontos usando o algoritmo K-Means, use o número de clusters igual ao número de divisões pretendidas
Calcule as coordenadas médias para cada agrupamento de pontos
Calcule os polígonos de Voronoi para as coordenadas médias
Recorte o polígono original com base nos polígonos de Voronoi
Pós-processamento: confira os resultados
Exemplo
Eu começo com este Shapefile:
Esta é a tabela de atributos:
E, neste exemplo, quero dividir cada um dos polígonos em três partes.
Estou usando o QGIS 3.22 Bialowieza para este tutorial.
Detalhes sobre o pré-processamento
Para garantir que os polígonos sejam divididos em partes iguais (ou quase iguais), é importante conhecer previamente a área de cada um deles. Na tabela de atributos, abra a calculadora de campo e crie um novo campo chamado área. Dei ao novo campo o tipo “Decimal number (real)”. A expressão a ser calculada é simplesmente “$area”. Gere esta coluna, salve e desative o modo de edição. Minha tabela de atributos agora está assim:
Importante: use um sistema de coordenadas projetado ao realizar cálculos de área.
Outra etapa importante de pré-processamento. Para executar o código PyQGIS fornecido neste post, eu preciso ter cada polígono em um shapefile diferente. Se você tiver todos os polígonos que deseja dividir no mesmo shapefile, use “Split Vector Layer” (native:splitvectorlayer) para separar os polígonos. No meu caso, usei a coluna id para dividi-los.
Salve-os em uma pasta, de preferência, permanente.
Os shapefiles resultantes são:
Rodando a rotina no PyQGIS
Este é o gist, hospedado no GitHub e disponibilizado sob a licença do MIT.
Faça as adaptações necessárias para cada caso, a saber, sistema de coordenadas, número de divisões, espaçamento dos pontos regulares usados para dividir os polígonos, localização dos arquivos no sistema e nome da coluna da tabela de atributos usada para dividir os polígonos em diferentes arquivos.
E… execute o código!
Esta é a divisão resultante para os polígonos do exemplo:
Verificação dos resultados e erros associados
Para o polígono 4, tenho que a área total é: 7080260,638, o que significa que um terço dela é 2360086,879.
Na tabela de atributos do polígono dividido, faço o cálculo “$area” (o mesmo que fiz antes). Resulta nos valores: 2050355.0129558295, 2675185.5178783312 e 2354716.308374524.
Portanto, podemos notar que há uma variação na área entre as partes divididas. Isso acontece principalmente porque os clusters gerados pelo K-Means Clustering possuem tamanhos diferentes. Usar pontos aleatórios em vez de pontos regulares não ajuda nisso e pode até introduzir erros maiores, em alguns casos (ex: se você usar um número muito pequeno de pontos aleatórios). Se você encontrar uma maneira de driblar este problema, por favor, me informe.
Extras
- Quando NÃO devo usar este script para dividir meus polígonos?
Você não deve usar este script, ou qualquer pipeline que envolva clusters de tamanhos diferentes, se for necessária precisão na divisão dos polígonos.
- Se já existem pipelines para dividir polígonos em pedaços menores, o que exatamente você fez aqui?
A automatização de um processo potencialmente tedioso, sem a necessidade de instalar nenhum plugin.
- A-há! Você disse que não usa nenhum plugin, mas o Python Console é um plugin!
Você está certo, “Python Console” é um plugin, assim como “Processing” e “GRASS GIS Provider” também são plugins. Mencionei que não há a necessidade de instalar plugins extras para executar o script.