En primer lugar, echa un vistazo a las siguientes funciones de PostGIS:
ST_NumGeometries y ST_GeometryN.
Entonces, seleccionar tus objetos individuales y calcular el azimut podría ser así (lo comprobé con algunos datos de muestra en mi PC)
WITH multiobject AS
(SELECT
lnumber,
your_multilinestring_column AS geom,
generate_series(1,100) AS n
FROM your_multilinestring_table),
objects AS
(SELECT
lnumber,
n,
ST_GeometryN(geom, n) AS geometries
FROM multiobject
WHERE n <= ST_NumGeometries(geom))
SELECT DISTINCT ON
(ST_Distance(your_point_column, geometries))
ST_Azimuth(ST_Startpoint(geometries), ST_Endpoint(geometries))
FROM objects, your_point_table
GROUP BY geometries, your_point_column
ORDER BY ST_Distance(your_point_column, geometries)
LIMIT 1;
Explicaremos esto un poco.
En la primera parte se selecciona tu MULTILINESTRING y se construye algo así como una secuencia con generate_series
(como máximo una colección de geometrías con 100 objetos; n=100). Puedes cambiar n cuando tengas más de 100 objetos en tu columna de multilíneas.
Con ST_GeometryN(geom, n)
seleccionas los objetos individuales y estableces el límite usando n <= ST_NumGeometries(geom)
. Así que tu resultado de la consulta es tan grande como los objetos en tu tabla de multilíneas.
En la última parte (quizás un poco complicada) seleccionas la distancia entre tus datos de puntos y los objetos (geometries
) en tu columna de multilíneas. Con SELECT DISTINCT ON
puedes eliminar filas duplicadas de tu conjunto de resultados. Al ordenar con ST_Distance(your_point_column, geometries)
y limitar el conjunto de resultados a 1, tienes la línea más cercana "extraída" en la parte superior.
El resultado de esta consulta es el azimut de una línea que es la más cercana a todos los puntos de una tabla. Tal vez debas establecer algunas cláusulas WHERE con tus ID en tus tablas de geometría (como gids o algo similar).
EDICIÓN
Mantente simple con ST_Dump. Creo que esto es mucho más fácil.
WITH objects AS
(SELECT
(ST_Dump(your_multilinestring_column)).geom AS geometries
FROM your_multilinestring_table)
SELECT DISTINCT ON
(ST_Distance(your_point_column, geometries))
ST_Azimuth(ST_Startpoint(geometries), ST_Endpoint(geometries))
FROM objects, your_point_table
GROUP BY geometries, your_point_column
ORDER BY ST_Distance(your_point_column, geometries)
LIMIT 1;
De las refracciones de PostGIS:
ST_Dump — Retorna un conjunto de filas geometry_dump (geom,path), que componen una geometría
La ventaja de la primera consulta quizás sea que puedes seleccionar un objeto distinto con n
. No sé cómo seleccionar objetos individuales con ST_Dump
usando el path
.
0 votos
Comprendiendo tu pregunta correctamente, ¿quieres calcular el azimut de un linestring que forma parte de un multilinestring? ¿Como el azimut de un palito que está más cerca de ti cuando juegas mikado =)
0 votos
Exactamente. Disculpa por el malentendido.
1 votos
¿Ya probaste mi consulta? Tengo curiosidad al respecto.
0 votos
Gracias, Stefan. La consulta (la versión más corta editada) falla después de un largo tiempo de ejecución, porque se queda sin memoria. (ERROR: no se pudo escribir el bloque 2456902 del archivo temporal: No queda espacio en el dispositivo HINT: ¿Quizás sin espacio en disco?). Supongo que funcionaría si el conjunto de datos fuera más pequeño. Disculpas por la demora en la respuesta, tuve un receso de la oficina.
0 votos
¿También consultaste tus datos con la primera consulta? Tal vez la función ST_Dump use demasiada memoria, especialmente al trabajar con grandes cantidades de datos.
0 votos
Quizás revisa tus archivos de registro de postgres con 'ls -la /var/log/postgresql/' (linux). Para Windows, solo mira en el archivo 'postgresql.conf' y verifica dónde se encuentran tus archivos de registro ('#log_directory'). Puede que estés produciendo muchos archivos de registro (demasiado grandes). Revisa el uso de tu disco, especialmente 'tmpfs', también con 'df -h'. Además, ¿estás utilizando GIDs (índices espaciales)??
0 votos
La primera consulta también se queda sin espacio. Se ejecuta durante una hora y sale con el mismo mensaje de error. Mi conjunto de datos es realmente grande, pero tengo más espacio libre en la unidad que el tamaño de la base de datos. Y sí, estoy usando índices espaciales...
0 votos
¿Has tenido éxito hasta ahora? ¿Lo has intentado con un conjunto de datos más pequeño? No soy ambicioso por la reputación, ¿pero podrías aceptar mi respuesta como la correcta, si funciona?
0 votos
He renunciado a esto en mi flujo de trabajo, por lo que no hice más intentos, pero tu respuesta parece ser la correcta. Gracias una vez más.