Línea más corta entre geometrías en PostGIS: ST_ShortestLine

La función de medición ST_ShortestLine en PostGIS devuelve la línea bidimensional más corta entre dos geometrías. Como el manual de referencia generalmente usa ejemplos sencillos, es conveniente probar como sería la sintaxis del comando cuando se realiza un query con una tabla de una base de datos y empleando situaciones algo más complejas para así detectar como es el comportamiento.

Por tanto, me dispuse a probar el comando en una situación como esta:

shortest1

donde la tablas ‘random_points’ y ‘polygon8’, con componente espacial, coexisten en mi database PostGIS.

En principio, la lógica sugiere que si existen 25 puntos (features) en una tabla y 8 features en la otra (polygon8) el número total de ‘shortest lines’ debería ser 25 x 8 = 200.

Un query sencillo en la consola de postgresql:

SELECT ST_AsText((ST_ShortestLine(polygon8.geom, random_points.geom))) 
FROM polygon8, random_points;

produce la salida siguiente que corrobora lo de las 200 líneas más cortas:

shortest2

Sin embargo, lo que me interesa son las 8 líneas más cortas desde un punto determinado a cada feature del polígono. Un query como el siguiente puede contestar, en parte, la pregunta (porque es difícil explorar, por ejemplo, en una salida con 20.000 líneas):

SELECT pol8.fid, ST_AsText(ST_ShortestLine(pol8.geom, rp.geom)) AS geom, 
	ST_LENGTH((ST_ShortestLine(pol8.geom, rp.geom))) AS length
	FROM polygon8 AS pol8, random_points AS rp
ORDER BY pol8.fid, length ASC;

donde éste es el resultado:

shortest3

La primera línea de cada serie ordenada por fid (‘poligono8’) es la respuesta. Llama la atención que existen distancias iguales a cero. Esto significa que indirectamente se está determinando aquellos puntos que coinciden con los rasgos del polígono (“puntos en polígonos”; que en el caso del feature con fid=1 existen 3).

Con el query siguiente creé la tabla de todas las líneas más cortas:

CREATE TABLE lines AS(
SELECT pol8.fid, ST_ShortestLine(pol8.geom, rp.geom) AS geom, 
	ST_LENGTH((ST_ShortestLine(pol8.geom, rp.geom))) AS length
	FROM polygon8 AS pol8, random_points AS rp
ORDER BY pol8.fid, length ASC
);

y esta es la visualización del resultado:

shortest4

Con el query a continuación:

SELECT pol8.fid, min(ST_LENGTH(ST_ShortestLine(pol8.geom, rp.geom)))
FROM polygon8 AS pol8, random_points AS rp
GROUP BY pol8.fid
ORDER BY pol8.fid;

se obtiene el resultado siguiente:

  fid |       min        
------+------------------
   0  | 7973.82638451241
   1  |                0
   2  |                0
   3  |   714.0772000191
   4  | 821.511702702019
   5  |                0
   6  | 2499.72683210753
   7  |                0
(8 rows)

donde se observa rápidamente que para los rasgos 1, 2 y 5 existen puntos que se encuentran dentro de la geometría que ellos delimitan (distancia mínima igual a cero).

Cuatro consultas similares a la siguiente (para las opciones diferentes a cero):

SELECT lines.geom FROM lines
WHERE length >= 7973 AND length <= 7974;

permiten obtener la geometría de las líneas en formato WKB:

                                        geom                                            
--------------------------------------------------------------------------------------------
 0102000020647F000002000000BDFC6928C51F174193CAE6546205514177AF2F258E961741B93B75C6BB075141
(1 row)

y el plugin QuickWKT permite visualizarlas en la Map View de QGIS; tal como se presenta en la imagen siguiente:

shortest5

Aquí se corrobora que corresponden efectivamente a las distancias mínimas esperadas.

Esta entrada fue publicada en Postgres+postgis, QGIS, SIG, Software Libre. Guarda el enlace permanente.

Una respuesta a Línea más corta entre geometrías en PostGIS: ST_ShortestLine

  1. Pingback: Anillos exteriores de un polígono en PostGIS: ST_ExteriorRing | El Blog de José Guerrero

Responder

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s