Ajustando nós iniciais e finais das linhas para outras linhas no PostGIS
9
Existem muitos exemplos que mostram como ajustar linhas a pontos, mas não consegui encontrar nenhuma maneira (rápida!) De ajustar os nós de início e de fim das cadeias de linhas para os de outras linhas.
Essencialmente, quero "limpar" minha camada no postgis (2.0), juntando pontos quase semelhantes e costurando pequenas aberturas entre as linhas.
Não importa muito se eu adiciono outro nó, movo o primeiro / último nó de qualquer linha ou movo os dois pontos para o centro.
Encontrei duas opções, mas não sei como começar com uma delas:
Consegui resolver isso, sem usar as ferramentas GRASS ou funções topológicas mencionadas.
Basicamente, pego todos os nós de início e de fim, os coloco em uma nova tabela temporária, coloco um buffer em torno deles, uno os objetos de buffer e movo todos os nós encontrados em cada buffer para o centróide do buffer.
Quando isso é feito, movo os pontos inicial e final originais para o novo local.
Mais fácil do que o esperado e ainda rápido, mas eu esperava que o PostGIS tivesse alguma função interna para isso - isso seria ainda mais rápido.
Edit: no interesse de retribuir à comunidade, este é o meu código (bastante ruim) por enquanto.
droptableifexists nodes;droptableifexists nodes2;droptableifexists buffers;-- Get Start and End nodesselect ST_StartPoint(wkb_geometry) startnode, ST_EndPoint(wkb_geometry) endnode, ogc_fid into nodes from sourceTable;-- Combine all nodes into one table for easier queriesselect startnode node, ogc_fid into nodes2 from nodes;insertinto nodes2 select endnode node, ogc_fid from nodes;-- Some indexes to speed everything upCREATEINDEX nodesstart_idx ON nodes USING gist (startnode);CREATEINDEX nodesend_idx ON nodes USING gist (endnode);CREATEINDEX nodes2_idx ON nodes2 USING gist (node);CREATEINDEX nodes_ogcfid_idx ON nodes USING btree (ogc_fid ASC NULLS LAST);-- Create buffers, combine them, split combined objects againselect(ST_Dump(ST_Union(ST_Buffer(node,1)))).geom geom into buffers from nodes2;CREATEINDEX buffers_idx ON buffers USING gist (geom);-- Update start/end nodes tableUPDATE nodes SET startnode = ST_Centroid((select geom from buffers WHERE geom && startnode));UPDATE nodes SET endnode = ST_Centroid((select geom from buffers WHERE geom && endnode));-- Update original pointsupdate sourceTable set wkb_geometry = ST_SetPoint(
ST_SetPoint(wkb_geometry,0,(select startnode from nodes where ogc_fid=sourceTable.ogc_fid)),
ST_NumPoints(wkb_geometry)-1,(select endnode from nodes where ogc_fid=sourceTable.ogc_fid));DROPTABLE nodes;DROPTABLE nodes2;DROPTABLE buffers;
Essa resposta se parece bastante com a sugestão "não topológica" da minha resposta. Seria gentil se você desse um voto positivo ou selecionasse a resposta. São esses os alimentos que alimentam a comunidade aqui :) #
484
Você está certo. Votei sua resposta de forma positiva e editarei minha resposta para incluir meu código.
Jelmer Baas
4
Aqui estão três opções. Espero que alguém ajude.
v.clean
Usando as ferramentas GRASS no QGIS, você pode limpar a topologia de um objeto espacial. O usuário @RK fornece um bom conjunto de instruções sobre como fazer isso em resposta a uma pergunta diferente . A vantagem que o GRASS oferece é que ele inferirá a topologia do shapefile. A desvantagem da sua situação é que seus dados não estão em um shapefile. Obviamente, você pode exportar os dados do Postgres para um shapefile usando a ferramenta "Adicionar camada PostGIS", mas essa é uma etapa extra.
Funções PostGIS não topológicas
Em PostGIS você pode usar as ST_Endpoint e ST_StartPoint funções para obter o fim e começar a ponto para uma cadeia de linha. Em seguida, usando uma combinação de ST_DWithi n e ST_Distance , você pode encontrar o ponto inicial ou final mais próximo em uma geometria próxima. Se você tiver muitos pontos, o ST_DWithin acelerará bastante a consulta - supondo que você tenha um índice no lugar. A partir daí, você precisará estabelecer uma regra que defina quais pontos serão modificados e quais serão corrigidos.
A vantagem aqui é que você não precisa enviar seus dados ao GRASS para limpeza, mas existem algumas armadilhas a serem observadas.
Funções topológicas PostGIS
A questão referenciou as funções topológicas do PostGIS. Eles funcionam muito bem, mas, como o wiki descreve , é necessário definir explicitamente as arestas, nós e faces. Claramente, isso será um problema para o seu conjunto de dados, pois você conhece problemas com a topologia.
Obrigado, estou ciente dessas funções. ST_Snap encaixa TODOS os nós, só quero o nó inicial e final. ST_SnapToGrid não é realmente adequado porque modifica toda a geometria existente e tem a chance de mover nós que estão mais distantes, porque mal caem em outro segmento.
Aqui estão três opções. Espero que alguém ajude.
v.clean
Usando as ferramentas GRASS no QGIS, você pode limpar a topologia de um objeto espacial. O usuário @RK fornece um bom conjunto de instruções sobre como fazer isso em resposta a uma pergunta diferente . A vantagem que o GRASS oferece é que ele inferirá a topologia do shapefile. A desvantagem da sua situação é que seus dados não estão em um shapefile. Obviamente, você pode exportar os dados do Postgres para um shapefile usando a ferramenta "Adicionar camada PostGIS", mas essa é uma etapa extra.
Funções PostGIS não topológicas
Em PostGIS você pode usar as ST_Endpoint e ST_StartPoint funções para obter o fim e começar a ponto para uma cadeia de linha. Em seguida, usando uma combinação de ST_DWithi n e ST_Distance , você pode encontrar o ponto inicial ou final mais próximo em uma geometria próxima. Se você tiver muitos pontos, o ST_DWithin acelerará bastante a consulta - supondo que você tenha um índice no lugar. A partir daí, você precisará estabelecer uma regra que defina quais pontos serão modificados e quais serão corrigidos.
A vantagem aqui é que você não precisa enviar seus dados ao GRASS para limpeza, mas existem algumas armadilhas a serem observadas.
Funções topológicas PostGIS
A questão referenciou as funções topológicas do PostGIS. Eles funcionam muito bem, mas, como o wiki descreve , é necessário definir explicitamente as arestas, nós e faces. Claramente, isso será um problema para o seu conjunto de dados, pois você conhece problemas com a topologia.
fonte
O PostGIS possui funções de encaixe. Talvez elas ajudem?
ST_Snap
: Encaixe segmentos e vértices da geometria de entrada nos vértices de uma geometria de referência.ST_SnapToGrid
: Encaixe todos os pontos da geometria de entrada em uma grade regular.fonte