30 votos

¿Cómo obtener el punto más cercano de una cadena de líneas a un punto dado?

Llevo mucho tiempo utilizando PostGIS pero nunca he tenido que utilizar el LINESTRING ¡geometría ...! :)

Lo que me gustaría hacer es lo siguiente: tengo una tabla de líneas (que representan las calles de una ciudad determinada, SRID 3395) y me gustaría encontrar las líneas más cercanas a un punto determinado (posición GPS, SRID 4326).

La solución que he encontrado es seleccionar todas las cadenas de líneas dentro de mi punto utilizando el expand() y determinar la distancia entre cada línea y mi punto utilizando el método ST_Distance() método.

Aquí está el 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;

Los resultados que obtengo se ven bien pero tengo la sensación de que algo está mal en mi implementación.

1) ¿Creen ustedes que el expand() ¿puede obtener todas las líneas en cuestión?

2) ¿Creen ustedes que el ST_Distance() ¿es el método correcto a utilizar? Supongo que lo estoy haciendo mal ya que la distancia que me gustaría obtener es la menor distancia entre el punto y mi línea y no la distancia entre el punto y uno de los puntos de la cadena de líneas.

Ilustración:

alt text

12voto

tobes Puntos 19

ad 1) Mirando la documentación de sus funciones usadas, yo diría: "Sí, se encontrarán todas las cadenas de líneas afectadas".

expand(geometry, float)

Esta función devuelve un cuadro delimitador expandido en todas las direcciones a partir del cuadro delimitador de la geometría de entrada, en una cantidad especificada en el segundo argumento. Muy útil para las consultas de distance(), para añadir un filtro de índice a la consulta.

A Y B

El operador "&&" es el operador de "solapamiento". Si el cuadro delimitador de A se solapa con el cuadro delimitador de B, el operador devuelve verdadero.

ad 2) Deberías ser capaz de conseguir lo que quieres a través de:

st_line_interpolate_point(linestring, st_line_locate_point(LineString, Point))

st_line_interpolate_point(linestring, location)

Interpola un punto a lo largo de una línea. El primer argumento debe ser un LINESTRING. El segundo argumento es un float8 entre 0 y 1 que representa la fracción de la longitud total de 2d que el punto tiene que ser localizado.

st_line_locate_point(LineString, Point)

Devuelve un flotador entre 0 y 1 que representa la ubicación del punto más cercano en LineString al Punto dado, como una fracción de la longitud total de la línea 2d. Puede utilizar la ubicación devuelta para extraer un Punto (line_interpolate_point)

7voto

Lars Mæhlum Puntos 4569

Hola

Primero la pregunta sobre lo que devuelve ST_Distance. ST_Distance devuelve la distancia más corta entre la línea y el punto (o los tipos de geometría introducidos). Esto significa que ST_Distance entre el punto (1 3) y la línea (0 0,0 10) devolverá 1. La distancia no se medirá entre el punto y (0 0) o el punto y (0 10) sino desde el punto (1 3) hasta (0 3).

Por lo que entiendo ST_Distance te da la respuesta que quieres.

Si quieres encontrar el punto (0 3) en el ejemplo anterior puedes usar ST_Closestpoint si tienes PostGIS 1.5 Para mi ejemplo lo usas así ST_Closestpoint('LINESTRING(0 0,0 10)'::geometría, 'POINT(1 3)'::geometría) entonces usted debe obtener el punto (0 3) en el retorno, el punto en la línea que está más cerca de su punto.

HTH Nicklas

5voto

Simon Gillbee Puntos 366

Lo he encontrado :) (Bueno, supongo que sí :P)

Utilizando el ST_Line_Locate_Point() y ST_Line_Interpolate_point() He conseguido un punto que NO forma parte de la definición de LINESTRING pero que sí está en dicha línea :) Lo único que tengo que hacer es obtener la distancia de mi punto a este punto y ya está.

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)

El ST_Line_Locate_Point() encuentra la ubicación del punto más cercano de la línea al punto dado, el ST_Line_Interpolate_Point convierte esta ubicación en un punto.

2voto

BWW Puntos 302

Este hilo de archivo de Postgis puede responderle http://postgis.refractions.net/pipermail/postgis-users/2007-June/016045.html

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X