Eu fiz essa pergunta várias vezes no stackoverflow e no irc entre #qgis e #postgis e também tentei codificá-la ou implementá-la sozinha no postgis sem resposta real.
Usando a programação (mais preferencialmente python), eu gostaria de desenhar uma linha de uma camada pontual até sua projeção na linha mais próxima de uma camada de linha ou polígono.
A partir de agora, a maioria dos meus dados está no formato ESRI e postgis; no entanto, prefiro ficar longe de uma solução postgis, pois sou predominantemente um usuário shp + qgis.
Uma solução ideal seria implementar GDAL / OGR com bibliotecas python ou similares
- Usando as bibliotecas GDAL / OGR, por onde devo começar? seria possível dar um plano de solução?
- Posso usar o NetworkX para fazer a análise do vizinho mais próximo?
- Isso é realmente possível?
Se for mais fácil, os pontos podem se conectar ao ponto final do segmento em vez de um ponto projetado
Respostas:
Essa questão acabou sendo um pouco mais complicada do que eu pensava. Existem muitas implementações da menor distância propriamente dita, como a distância fornecida Shapely (do GEOS). Poucas das soluções fornecem o próprio ponto de interseção, mas apenas a distância.
Minha primeira tentativa limitou o ponto pela distância entre o ponto e o polígono e procurou por interseções, mas os erros de arredondamento impedem que isso dê uma resposta exata.
Aqui está uma solução completa usando Shapely, com base nessas equações :
Para a posteridade, parece que essa extensão do ArcView lida com esse problema muito bem, pena que esteja em uma plataforma morta, escrita em um idioma morto ...
fonte
pairs
isso é algoritmicamente O (n) ou algo assim. @eprand solução , talvez, pode ser modificado para usar KNN no entanto eu consegui viver sem PostGIS até agora ...Uma resposta PostGIS (para cadeia de linhas múltiplas, se cadeia de linhas, remova a função st_geometryn)
fonte
Isso é um pouco antigo, mas eu estava procurando soluções para esse problema hoje (ponto -> linha). A solução mais simples que me deparei para esse problema relacionado é:
fonte
Se eu entendi direito, a funcionalidade solicitada está embutida no PostGIS.
Para obter um ponto projetado em uma linha, você pode usar o ST_Closestpoint (no PostGIS 1.5)
Algumas dicas sobre como usá-lo, você pode ler aqui: http://blog.jordogskog.no/2010/02/07/how-to-use-the-new-distance-related-functions-in-postgis-part1/
Também é útil encontrar o ponto mais próximo de um polígono a outro polígono, por exemplo.
Se você deseja a linha entre os dois pontos mais próximos nas duas geometrias, pode usar ST_Shortestline. ST_Closestpoint é o primeiro ponto em ST_Shortestline
O comprimento de ST_Shortestline entre duas geometrias é o mesmo que ST_Distance entre as geometrias.
fonte
Veja o comentário abaixo sobre como minha resposta não deve ser considerada uma solução confiável ... Deixarei este post original aqui apenas para que outras pessoas possam examinar o problema.
Se eu entendi a pergunta, esse procedimento geral deve funcionar.
Para encontrar o caminho mais curto entre um ponto (conforme definido por x, y ou x, y, z) e uma polina (conforme definido por um conjunto de conexões de x, y ou x, y, z) no espaço euclidiano:
1) A partir de um determinado ponto definido pelo usuário (vou chamá-lo de pt0), encontre o vértice mais próximo da polilinha (pt1). O OGRinfo pode pesquisar os vértices de uma polilinha e, em seguida, cálculos de distância podem ser feitos por métodos padrão. Por exemplo, itere em uma distância calculada como: distance_in_radians = 2 * math.asin (math.sqrt (math.pow ((math.sin ((pt0_radians-ptx_radians) / 2)), 2) + math.cos (pt0_radians) * Math.cos (ptx_radians) * math.pow ((math.sin ((pt0_radians-ptx_radians) / 2)), 2)))
2) Armazene o valor da distância mínima associada (d1) e (pt1)
3) observe os dois segmentos que se afastam de pt1 (na cadeia de linhas ogrinfo, esses serão os vértices anteriores e subsequentes). Registre esses vértices (n2 e n3).
4) crie a fórmula y = mx + b para cada segmento
5) Relacione seu ponto (pt0) à perpendicular para cada uma dessas duas fórmulas
6) Calcular distância e interseções (d2 e d3; pt2, pt3)
7) Compare as três distâncias (d1, d2, d3) para a menor. Seu pt0 para o nó associado (pt1, pt2 ou pt3) é o link mais curto.
Essa é uma resposta da corrente da consciência - espero que minha imagem mental do problema e da solução se encaixe.
fonte
Aqui está um script python para QGIS> 2.0, feito a partir das dicas e soluções fornecidas acima. Funciona bem para uma quantidade razoável de pontos e linhas. Mas eu não tentei com uma quantidade enorme de objetos.
É claro que tinha que ser copiado em modo inativo ou qualquer outra "solução pitônica" e salvá-lo como "closest.point.py".
Na caixa de ferramentas QGIS, vá para script, ferramentas, adicione um script e escolha-o.
!!! ATENÇÃO !!! Preste atenção que alguns pontos projetados "estranhos" / incorretos podem ser produzidos devido a este comando de linha:
O
counterSelec
valor nele define quantos mais próximoNeighbor são retornados. De fato, cada ponto deve ser projetado na menor distância possível para cada objeto de linha; e a distância mínima encontrada daria a linha correta e o ponto projetado como os vizinhos mais próximos que procuramos. Para reduzir o tempo de loop, o comando Vizinho mais próximo é usado. Escolher umcounterSelec
valor reduzido para 1 retornará o "primeiro" objeto encontrado (é a caixa delimitadora mais exatamente) e pode não ser o correto. Objetos de tamanho de linha diferentes que podem ser obrigados a escolher podem ser 3 ou 5 ou objetos ainda mais próximos para determinar a menor distância. Quanto maior o valor, mais tempo leva. Com centenas de pontos e linhas, começa a ficar muito lento, com 3 ou 5 vizinhos mais próximos, e com milhares, pode incomodar esses valores.fonte
Dependendo dos seus interesses e caso de uso, pode ser útil examinar "algoritmos de correspondência de mapa". Por exemplo, há um projeto do RoadMatcher no wiki do OSM: http://wiki.openstreetmap.org/wiki/Roadmatcher .
fonte