Come ottenere il punto più vicino su un linestring ad un determinato punto?


28

Uso PostGIS da molto tempo ormai ma non ho mai dovuto usare la LINESTRINGgeometria ...! :)

Ecco cosa mi piacerebbe fare: ho una tabella di linee di linea (che rappresentano le strade di una determinata città, SRID 3395) e vorrei trovare le linee di linea più vicine a un determinato punto (posizione GPS, SRID 4326).

La soluzione che ho trovato è selezionare tutte le stringhe di linea all'interno del mio punto utilizzando il expand()metodo e determinare la distanza tra ciascuna stringa di linea e il mio punto utilizzando il ST_Distance()metodo.

Ecco l'SQL:

SELECT myLineId, myLineName, ST_Distance(ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395),myLineGeom) AS myLineDistance
FROM myLines
WHERE myLineGeom && expand(ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395), 100)
ORDER BY myLineDistance;

I risultati che ottengo sembrano OK, ma ho l'impressione che qualcosa non vada nella mia implementazione.

1) Pensi che sia expand()possibile ottenere tutti i linestrings interessati?

2) Pensi che ST_Distance()sia il metodo giusto da usare? Immagino che lo stia facendo in modo sbagliato poiché la distanza che vorrei ottenere è la distanza minima tra il punto e la mia linea e non la distanza tra il punto e uno dei punti della stringa lineare.

Illustrazione:

testo alternativo

Risposte:


11

ad 1) Guardando la documentazione per le tue funzioni usate, direi: "Sì, verranno trovati tutti i linestring interessati".

espandi (geometria, float)

Questa funzione restituisce un rettangolo di selezione espanso in tutte le direzioni dal rettangolo di selezione della geometria di input, di un importo specificato nel secondo argomento. Molto utile per le query distance (), per aggiungere un filtro indice alla query.

A && B

L'operatore "&&" è l'operatore "sovrapposizioni". Se il riquadro di selezione di A si sovrappone al riquadro di selezione di B, l'operatore restituisce true.

annuncio 2) Dovresti essere in grado di ottenere ciò che desideri tramite:

line_interpolate_point(linestring, line_locate_point(LineString, Point))

line_interpolate_point (linestring, posizione)

Interpola un punto lungo una linea. Il primo argomento deve essere un LINESTRING. Il secondo argomento è un float8 tra 0 e 1 che rappresenta la frazione della lunghezza totale di 2d che deve essere localizzata.

line_locate_point (LineString, Point)

Restituisce un galleggiante compreso tra 0 e 1 che rappresenta la posizione del punto più vicino su LineString al punto dato, come una frazione della lunghezza totale della linea 2d. È possibile utilizzare la posizione restituita per estrarre un punto (line_interpolate_point)

Fonte: http://main.merlin.com.ua/doc/postgis/docs/ch06.html


Per il punto 2), mi stavo solo chiedendo se ST_Distance tra una geometria POINT e una geometria LINESTRING dia la minima distanza possibile tra le tesi (ovvero la lunghezza della linea perpendicolare tra POINT e LINGESTRING); voglio la distanza da ogni geometria LINESTRING :)
Vivi,

E suppongo che non sia la distanza che sto cercando poiché "la funzione line_locate_point ti dà un valore compreso tra 0 e 1 che rappresenta la posizione del punto più vicino su LineString al punto dato": /
Vivi

Temo che mi hai perso nel tuo ultimo commento. Ora non sono più sicuro di ciò che vuoi;)
underdark

1
Scusa :) Mi piacerebbe questo: dando una geometria LINESTRING (che rappresenta un percorso) e una geometria POINT, voglio avere la geometria POINT più vicina che si trova sul percorso (che potrebbe non essere un punto della definizione della geometria LINESTRING). È chiaro? Forse dovrei aggiornare il mio post con un disegno: D
Vivi,

Non riesco ad aggiornare il mio post, quindi ecco un link a un disegno di ciò che vorrei ottenere: i.imgur.com/UwPxo.jpg
Vivi,

7

ciao

Innanzitutto la domanda su cosa restituisce ST_Distance. ST_Distance restituisce la distanza più breve tra la linea e il punto (o quali tipi di geometria vengono immessi) Ciò significa che ST_Distance tra il punto (1 3) e la stringa lineare (0 0,0 10) restituirà 1. La distanza non verrà misurata tra punto e (0 0) o il punto e (0 10) ma dal punto (1 3) a (0 3).

Quindi, da quello che capisco, ST_Distance ti dà la risposta che desideri.

Se vuoi trovare il punto (0 3) nell'esempio sopra puoi usare ST_Closestpoint se hai PostGIS 1.5 Per il mio esempio lo usi in questo modo: ST_Closestpoint ('LINESTRING (0 0,0 10)' :: geometria, ' POINT (1 3) ':: geometria) quindi dovresti ottenere in cambio il punto (0 3), il punto sulla linea più vicino al tuo punto.

HTH Nicklas


5

L'ho trovato :) (Beh, immagino: P)

Usando ST_Line_Locate_Point()e ST_Line_Interpolate_point()sono riuscito a ottenere un punto che NON fa parte della definizione LINESTRING ma È sulla suddetta linea :) Tutto quello che devo fare è ottenere la distanza dal mio punto a questo punto e il gioco è fatto.

SELECT AsText(ST_Line_Interpolate_Point(myLineGeom,ST_Line_Locate_Point(myLineGeom,ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395))))
FROM myLines
WHERE myGeom && expand(ST_Transform(GeomFromText('POINT(LON LAT)',4326),3395), 100)

Il ST_Line_Locate_Point()metodo trova la posizione del punto più vicino sulla linea a un determinato punto, il ST_Line_Interpolate_Pointmetodo trasforma questa posizione in un punto.


1
St_distance tra il punto e la linea ti darà la stessa risposta. Perché pensi di doverlo fare in questo modo?
Nicklas Avén,

1
Penso che ST_Distance possa essere utilizzato con qualsiasi tipo di geometria. postgis.refractions.net/docs/ST_Distance.html :ST_Distance(geometry g1, geometry g2)
Magno C

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.