PostGIS: aproximación de un número de casa del rango de direcciones

8

Estoy desarrollando un geocodificador inverso 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 encontrar la mejor manera de aproximar programáticamente el número de casa más cercano al punto lat / lng dado.

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

-[ RECORD 1 ]-
[...]
l_adddirfg | Same Direction
l_hnumf    | 3219
l_hnuml    | 3235
l_stname_c | Breen Road North-west
r_adddirfg | Same Direction
r_hnumf    | 3224
r_hnuml    | 3236
r_stname_c | Breen Road North-west
the_geom   | 0105000020E610000001000000010200000002000000B0F6990E78885CC088DF2B5F3C8C49400875B39A89885CC0A0BCA6AC4B8C4940

Entonces, dada una coordenada lat / lng que se encuentra cerca del segmento de línea "the_geom", una persona podría decir visualmente en qué lado de la calle está el punto (lado izquierdo o derecho) y qué tan lejos está el segmento, por lo tanto aproximando un número de casa. Por ejemplo, si el punto se encuentra en el lado derecho, tres cuartos por la calle, usarí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 esté cerca a:

3232 Breen Road North-west

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

¡Gracias!

René Fournier
fuente

Respuestas:

11

La solución se puede construir completamente en PostGIS.

Dado un punto (ubicación de la casa, lo modelé como un PUNTO) y un segmento de calle (segmento de calle más cercano a este punto, modelado como LINESTRING), usted pregunta:

  • 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 más cercano a la casa y luego determinar si este punto se encuentra a la izquierda o derecha de la casa (el operador &<devuelve verdadero si el primer argumento de geometría se superpone o está a la izquierda de El segundo argumento de geometría). &<en realidad funciona con cuadros delimitadores, pero como estamos trabajando 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 en el segmento de la calle?

Nuevamente, esto se traduce en qué tan lejos (un valor entre 0 y 1) en el segmento de la calle es el punto en la calle más cercano a 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 de cadena lineal y punto utilizado anteriormente

diciu
fuente