Eu tenho um conjunto de polígonos representando grandes áreas, digamos bairros da cidade. Quero identificar as grandes áreas sobrepostas entre elas.
Mas há um problema: às vezes esses polígonos se sobrepõem ao longo de seus perímetros (porque foram desenhados com pouca precisão). Isso irá gerar sobreposições longas e estreitas com as quais não me importo.
Outras vezes, porém, haverá grandes sobreposições de polígonos robustos, o que significa grandes áreas em que o polígono de um bairro se sobrepõe a outro. Eu quero selecionar apenas estes.
Veja a figura abaixo apenas das sobreposições. Imagine que eu queria selecionar apenas o polígono azul no canto inferior esquerdo.
Eu podia olhar para as áreas, mas às vezes as estreitas são tão longas que acabam tendo áreas tão grandes quanto o polígono azul. Eu tentei fazer uma proporção de área / perímetro, mas isso também produziu resultados mistos.
Eu até tentei usar ST_MinimumClearance
, mas às vezes as grandes áreas terão uma parte estreita anexada a ela, ou dois vértices muito próximos.
Alguma idéia de outras abordagens?
No final, o que funcionou melhor para mim foi usar um buffer negativo, conforme sugerido por @Cyril e @FGreg abaixo.
Eu usei algo como:
ST_Area(ST_Buffer(geom, -10)) as neg_buffer_area
No meu caso, as unidades eram metros, portanto 10 m de buffer negativo.
Para polígonos estreitos, essa área retornou zero (também, a geometria estaria vazia). Então usei essa coluna para filtrar os polígonos estreitos.
Respostas:
Eu tentaria criar um buffer negativo, se ele come polígonos finos, então é bom, se não comer o polígono, então é meu ... :-)
execute este script, tendo previamente definido 2/3 da largura dos polígonos lineares ...
OS: -) ...
fonte
ST_Area(ST_Buffer(geom, -10))
-10 sendo -10 metros no meu caso. Se alguma coisa retornasse 0 dessa expressão, eu poderia filtrá-la.Em vez de área / perímetro, é melhor usar a área dividida pelo quadrado do perímetro (ou seu inverso).
Isso também é chamado de "índice de forma". O quadrado do perímetro dividido pela área tem um valor mínimo de 4 * Pi () (no caso de um disco, que é a geometria 2D mais compacta), para que possa ser normalizado por 4 * Pi () para facilitar interpretação (valores normalizados próximos a 1 significam que você tem objetos muito compactos e quadrados têm valores de aproximadamente 1,27).
EDIT: Um limite na área seria útil para remover os artefatos muito pequenos, que poderiam ser compactos. Em seguida, o índice de forma mostraria melhor contraste. EDIT: além desta resposta, o uso do ST_Snap pode ajudá-lo a resolver o problema antes que ele ocorra.
fonte
(o.overlap_perimeter^2 / o.overlap_area) / (4 * Pi()) as overlap_ratio
? Isso está tendo resultados piores para mim do que apenas área / perímetro.o.overlap_perimeter / (4 * sqrt(o.overlap_area)) as overlap_ratio
acordo com este artigo, mas resultados ainda piores (embora seja difícil quantificar o que quero dizer com pior) é: prs-ann-photogramm-remote-sens-spatial-inf-sci.net/I-7/135/… , página 183.Uma opção seria usar a proporção da área do polígono para a linha mais longa que pode ser desenhada usando suas extremidades. Identificando polígonos estreitos e longos.
select * from polygons where ST_Length(ST_LongestLine(geom, geom)) < ST_Area(geom) * 4
Isso funciona muito bem para polígonos de fita. Você pode ajustar a proporção (com a qual você multiplica a área) para atender às suas necessidades e projeção.
fonte
Parece que isso pode corresponder ao seu caso de uso: Eliminar polígonos selecionados
Parece que você deseja experimentar a opção "Maior limite comum".
fonte
Isso me parece um caso de uso perfeito para a extensão de topologia PostGIS . O parâmetro de tolerância da topologia determinará até que ponto você permite que os vértices se ajustem a outros polígonos existentes, para lidar com a baixa precisão dos dados de origem e limpá-los.
Em suma, a estratégia é:
1. Habilite a extensão de topologia
2. Crie uma nova topologia vazia
O terceiro parâmetro é a tolerância, nas unidades do SRC; escolha sabiamente. Idealmente, você deseja um CRS em que a unidade é metros. Se a unidade CRS não tiver medidores, como no WGS 84 aka 4326, use
ST_Transform
para reprojetar seus polígonos.3. Adicione uma coluna TopoGeometry à tabela de polígonos
Isso retorna um novo
layer_id
. Salve, será necessário mais tarde. Será uma camada1
se você começar do zero e incrementado a cada nova chamada.4. Adicione todos os polígonos à topologia
Isso pode levar várias horas para um grande conjunto de dados, seja paciente.
1
é o layer_id retornado anteriormente.5. Encontre rostos aparecendo em vários bairros
Encontre todas as faces da topologia presentes em 2 ou mais topogeometrias. Vou deixar a consulta como um exercício. O mais fácil é provavelmente com a
GetTopoGeomElements
função, em seguida, agrupe por ID do rosto e observe os com uma contagem de 2 ou mais. Como alternativa, você pode criar uma nova tabela com a geometria limpa da coluna topogeom, apenas convertê-la na geometria padrãotopogeom::geometry
e repetir o que você já tem agora, mas agora com um conjunto de dados limpo sem a sobreposição da tira.fonte