4 votos

Distancia entre puntos secuenciales postgre

Mi tabla es la siguiente

1;"2015-10-02";"POINT(lat,lon) as geometry"
2;"2015-10-03";"POINT(lat,lon) as geometry"
3;"2015-10-04";"POINT(lat,lon) as geometry"

¿Cómo puedo hallar la distancia entre dos puntos secuenciales?

Así que tendría id=1 e id=2 distancia entre ellos = 99m (las distancias se encontrarían entre [1,2],[2,3],[3,4] y así sucesivamente

Más tarde me gustaría agregarlos (si la distancia < 100m agrega)

No he llegado muy lejos con él

Esto me da la distancia pero no sé cómo obtener la geometría de la siguiente fila

SELECT st_distance_sphere(t.latlon,next.latlon) from test as t where id=1

Luego traté de leer la distancia como una columna adicional, pero no pude averiguar una consulta correcta

UPDATE test SET dist=ST_Distance(test.latlon, next.geom) 
FROM (SELECT latlon FROM test WHERE id = test.id + 1) into b;

El resultado deseado sería

1;"2015-10-02";"POINT(lat,lon) as geometry";distance between 1 and 2
2;"2015-10-03";"POINT(lat,lon) as geometry";distance between 2 and 3
3;"2015-10-04";"POINT(lat,lon) as geometry";distance between 3 and 4

6voto

MBCook Puntos 8316

Una forma más general de resolver esto (que no depende de tener un identificador secuencial sin puntos perdidos) es utilizar la función de PostgreSQL lag función de ventana (véase docs ).

En este caso, es tan sencillo como:

SELECT
  id,
  dt, 
  ST_Distance(geom, lag(geom, 1) OVER (ORDER by dt ASC))
FROM testpoints;

donde dt es la columna que contiene sus valores de fecha-hora. ¿Cómo, entonces, agregar los puntos? Una forma es utilizar sum como función de ventana para ver cuántas roturas se han encontrado hasta el momento (aquí estoy usando 0,64 como umbral).

SELECT
  id,
  dt,
  dist,
  SUM(CASE WHEN dist > 0.64 THEN 1 ELSE 0 END) OVER (ORDER BY dt ASC) AS clustr
FROM
    (SELECT 
       id, 
       dt, 
       ST_Distance(geom, lag(geom, 1) OVER (ORDER BY dt ASC)) AS dist
     FROM testpoints) sq;

Para mis puntos de prueba, el resultado es ahora el siguiente:

 id |              dt               |       dist        | clustr 
----+-------------------------------+-------------------+--------
  1 | 2015-11-11 08:15:37.996556-05 |                   |      0
  2 | 2015-11-11 08:15:39.237025-05 | 0.411143570472674 |      0
  3 | 2015-11-11 08:15:39.760647-05 |  0.18676903202556 |      0
  4 | 2015-11-11 08:15:40.123549-05 |  0.53587461849279 |      0
  5 | 2015-11-11 08:15:40.429877-05 | 0.699859353108215 |      1
  6 | 2015-11-11 08:15:40.729668-05 | 0.363468389297844 |      1
  7 | 2015-11-11 08:15:41.028922-05 | 0.649386937777059 |      2
  8 | 2015-11-11 08:15:41.32032-05  | 0.675600276096486 |      3

Ahora, si quiero agregarlos, puedo seleccionarlos con SELECT ST_Collect(geom) FROM query_above GROUP BY clustr o tal vez ST_MakeLine(geom ORDER BY dt ASC) GROUP BY clustr .

2voto

evojacking Puntos 21

Esto le dará una tabla con dos ids y la distancia entre esos dos.

SELECT b.id, a.id, a.wkb_geometry <-> b.wkb_geometry
FROM test a
JOIN test b ON (a.id = b.id + 1);

<-> le da la distancia bbox, podría utilizar <#> 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