El escenario:
Tengo puntos (direcciones) y cadenas multilíneas (calles), es decir ap
y street
tablas en mi db PostgreSQL 9.5. Tabla ap
contiene 3 filas (puntos de muestra) mientras que street
contiene 85 filas. El escenario de ejemplo se muestra a continuación.
Lo que necesito:
Para cada punto ap
Necesito identificar si está en el "lado izquierdo" o en el "lado derecho" del street
.
El código:
En GIS SE, ya he encontrado algunas preguntas relevantes. Por ejemplo:
- ¿Detectar si un punto está en el lado izquierdo o derecho de una línea en PostGIS? y
- ¿Determinar en qué lado se encuentra un punto de la línea utilizando PostGIS?
El siguiente código es una adaptación del primero enlace .
With cp as
(
Select
a.gid ap_id,
a.geom ap,
ST_SetSRID(ST_LineMerge(b.geom), 3044) line,
ST_SetSRID(ST_ClosestPoint(b.geom, a.geom), 3044) p
from
ap a
Left Join street b on
ST_Dwithin(ST_SetSRID(b.geom, 3044), ST_SetSRID(a.geom, 3044), 25)
Order by a.gid, ST_Distance(b.geom, a.geom)
)
, h as
(
Select
ap_id, ap,
line, p,
ST_MakeLine(p, ap) vec,
ST_MakeLine(p,
ST_LineInterpolatePoint(line,
ST_LineLocatePoint(line, p) * 1.01)) seg
From cp
Order by ap_id
)
Select
ap_id,
degrees(ST_Azimuth(ST_StartPoint(vec), ST_EndPoint(vec)))
- degrees(ST_Azimuth(ST_StartPoint(seg), ST_EndPoint(seg))) diff
from h
order by ap_id
La salida:
El código anterior (para el escenario de ejemplo) funciona y la salida es:
ap_id diff
1 -269.999999988824
2 89.9999999946886
3 269.999999980956
Error:
Sin embargo, el código para otro conjunto de datos de puntos (87 filas), arroja el siguiente error:
ERROR: line_interpolate_point: 2nd arg isn't within [0,1]
Además, el código anterior no parece funcionar para los casos en los que la calle es de este a oeste y tiene un rumbo de 90 grados (Referencia, aquí ). Necesito realizar esta tarea de identificación de puntos para un gran conjunto de datos. Por lo tanto, estoy buscando sugerencias para superar este problema. ¿Hay alguna forma alternativa de identificar si los puntos están en el lado izquierdo o en el lado derecho de la calle?
1 votos
Realmente no tengo tiempo para mirar esto adecuadamente en este momento, pero
ST_ShortestLine
yST_LineCrossingDirection
podría ser prometedor.0 votos
@MickyT: Gracias por la sugerencia. ¿Te importaría explicarte un poco?
0 votos
He añadido una respuesta como explicación, pero ten en cuenta que no he probado esta teoría y puede que no funcione.
0 votos
@MickyT: Probado y con respuesta a su sugerencia.