8 votos

PostGIS: Aproximación de un número de casa a partir de un rango de direcciones

Estoy desarrollando un inversor de geocodificación para Canadá. Hasta ahora, dado un lat/lng, puedo encontrar la calle más cercana (segmento de línea), que incluye la dirección del segmento de línea y los rangos de direcciones para ambos lados de la calle. Ahora estoy tratando de averiguar la mejor manera de aproximar de forma programática el número de casa más cercano al punto lat/lng dado.

Aquí tienes un ejemplo de una fila que contiene los datos de la calle:

-[ REGISTRO 1 ]-
[...]
l_adddirfg | Misma Dirección
l_hnumf    | 3219
l_hnuml    | 3235
l_stname_c | Breen Road North-west
r_adddirfg | Misma Dirección
r_hnumf    | 3224
r_hnuml    | 3236
r_stname_c | Breen Road North-west
the_geom   | 0105000020E610000001000000010200000002000000B0F6990E78885CC088DF2B5F3C8C49400875B39A89885CC0A0BCA6AC4B8C4940

Entonces, dado un coordenada lat/lng que se encuentre cerca del segmento de línea "the_geom", una persona podría visualmente determinar en qué lado de la calle se encuentra el punto (lado izquierdo o derecho) y a qué distancia a lo largo del segmento se encuentra, estimando así un número de casa. Por ejemplo, si el punto se encuentra en el lado derecho, a tres cuartos de la calle, utilizaría los campos r_hnumf (lado derecho, primer número) y r_hnuml (lado derecho, último número)... La dirección de la calle probablemente sea cercana a:

3232 Breen Road North-west

Lo que estoy buscando es una mejor práctica para calcular/aproximar esto en PostGIS (en lo que soy nuevo), o en la capa de la aplicación una vez que se obtiene la fila.

¡Gracias!

11voto

axk Puntos 2147

La solución se puede construir completamente en PostGIS.

Dado un punto (ubicación de la casa, lo he modelado como un POINT) y un segmento de calle (segmento de calle más cercano a este punto, modelado como LINESTRING) preguntas:

  • ¿Cómo saber si el punto está a la izquierda de un segmento de calle?

Una posible solución es determinar el punto en el segmento de calle que esté más cerca de la casa y luego determinar si este punto está a la izquierda o a la derecha de la casa (el operador &< devuelve true si el primer argumento de geometría se superpone o está a la izquierda del segundo argumento de geometría). &< en realidad trabaja con cajas delimitadoras, pero como trabajamos con puntos esto no debería importar.

osm=# select 'POINT(4 1)'::geometry &< st_closestpoint('LINESTRING(1 1,2 3,6 6)'::geometry, 'POINT(4 1)'::geometry) as houseIsOnLeft;
 houseisonleft 
---------------
 f
(1 row)
  • ¿Qué tan lejos está la casa a lo largo del segmento de calle?

Nuevamente esto se traduce en qué tan lejos (un valor entre 0 y 1) a lo largo del segmento de calle está el punto en la calle que está más cerca de la casa. Hay una función incorporada para eso, llamada st_line_locate_point:

osm=# select st_line_locate_point('LINESTRING(1 1,2 3,6 6)'::geometry, 'POINT(2 1)'::geometry);
 st_line_locate_point 
----------------------
   0.0618033988749895
(1 row)

osm=# select st_line_locate_point('LINESTRING(1 1,2 3,6 6)'::geometry, 'POINT(5 6)'::geometry);
 st_line_locate_point 
----------------------
    0.889442719099992
(1 row)

Diagrama del linestring y punto utilizado arriba

1voto

dlanod Puntos 8661

Echa un vistazo a http://www.postgis.org/documentation/manual-svn/ST_Line_Locate_Point.html

El ejemplo en la página es básicamente lo que creo que estás intentando hacer también.

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