4 votos

Encontrar puntos cercanos en el espacio y el tiempo

Tengo una tabla que tiene un ID, una geometría de punto y una hora. Básicamente son las coordenadas del GPS y algunos otros datos. Quiero ser capaz de seleccionar todas las filas que interactúan (se acercan en el espacio y el tiempo) a mi ID de destino.

Por ejemplo, obtengo mi pista objetivo, los puntos de Juan, con una simple consulta y luego puedo crear una línea a partir de esos puntos, almacenarla en el buffer y obtener todas las demás filas que caen dentro de esa pista almacenada en el buffer.

En la imagen de abajo tengo todos los puntos de Juan para un mes y todos los puntos de otras identificaciones para el mismo mes que caen dentro de 10 km de su pista. Esto funciona bien si me limito a un día o dos.

El problema que estoy experimentando es que a medida que aumenta el límite de tiempo me salen cada vez más partidos malos; los puntos de la pista de Juan que suceden el día 15 están rodeados de pistas que suceden el día 1 o el 30.

John's GPS track and all GPS tracks that might interact

Entonces, ¿cómo debería hacer esto? ¿Crear un CTE de los puntos de John y luego algún tipo de ventana móvil sobre eso para obtener sólo los puntos que están dentro de 1 km y 1 hora del punto X de John?

No estoy seguro de qué herramientas utilizar...

SQL que utilizo para obtener imagen (aunque coloreo los puntos de John de forma diferente):

WITH target_track AS 
    (SELECT DISTINCT ON (name) 
  name, 
  ST_MakeLine(gps_point) AS track, 
  ST_Buffer(ST_MakeLine(POSITION), 0.1) AS buff_track 
     FROM gps_history
    WHERE 
    name = 'john'
    AND
     event_time BETWEEN '2019-01-01' and '2019-01-30'
    GROUP BY name)

SELECT gps_history.* FROM
gps_history, target_track
WHERE
ST_Within(gps_point, target_track.buff_track)
AND
event_time BETWEEN '2019-01-01' and '2019-01-30'

Utilizo group by y distinct para obtener una única fila para el CTE target_track y luego lo utilizo para encontrar todos los puntos que están en esa región temporal/espacial.

1 votos

Mhhh, hasta ahora diría que deberías ser capaz de resolver tu problema con alguna condición where en la columna datetime cuando creas tu buffer y cuando recuperas tus puntos... no debería ser más difícil creo (o he entendido algo mal)

0 votos

He añadido el SQL que he utilizado para obtener la imagen. El problema es que los datos devueltos están trayendo todos los mensajes que caen dentro de la pista del buffer y todo el período del mes. Así que cuando Juan está en el extremo izquierdo, al final de la pista, estoy obteniendo datos de los GPS que estaban allí cuando él estaba en el extremo derecho. Estaban cerca en el espacio pero muy lejos en el tiempo..

0 votos

Ok, yo sugeriría crear varios caminos, digamos uno por día y sólo considerar los puntos alrededor de cada geom en la fecha hora dada. Su enfoque es bueno, pero también debe dividir su trayectoria en el tiempo. Entonces necesitas cambiar tu primera consulta con un Grupo Por tal vez...

2voto

Mark Jeronimus Puntos 196

Si trabaja con series temporales, Postgis tiene ahora una forma nativa de manejarlas: trayectoria (se basa en LINESTRINGM, puedes ver por ejemplo en el enlace o en la primera función que debes utilizar: ST_IsValidTrajectory ).

No tiene mucha función (en mi opinión), pero a mi entender puede responder a tu problema. Una vez que tengas tus líneas transformadas en trayectorias, puedes utilizar por ejemplo ST_ClosestPointOfApproach para obtener el punto más cercano entre 2 trayectorias (tanto en el tiempo como en el espacio), y ver si respeta su requisito.

Probablemente deberías usar ST_CPAWithin antes para filtrar la mayoría de tus trayectorias que no quieres, pero desafortunadamente si puedes pasar una distancia como parámetro, no puedes pasar una diferencia de tiempo máxima que quieres, por eso necesitas usar ST_ClosestPointOfApproach después.

0 votos

Esto parece proimsing, he editado el SQL para hacer trayectorias de todos los puntos gps en el buffer: ST_MakeLine(ST_MakePoint(longitud, latitud, extract(epoch from event_time)) ORDER BY event_time) AS track_traj pero ST_CLosestPointof Approach falla: AVISO: La línea no tiene dimensión M ERROR: Ambas geometrías de entrada deben tener una dimensión de medida

0 votos

Whoops, la función correcta es ST_MakePoint(Lon, Lat, 0, epoch) en lugar de (Lon, Lat, Epoch)

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