Recién comencé a trabajar con bases de datos espaciales y quiero escribir una consulta SQL (PostGIS) para la generalización automática de pistas GPS sin procesar (con frecuencia de seguimiento fija). Lo primero en lo que estoy trabajando es una consulta que identifica puntos de parada en forma de consulta como "puntos x dentro de una distancia de y metros" para reemplazar las nubes de puntos masivas por puntos representativos. Ya me di cuenta de tomar puntos dentro de una cierta distancia y contarlos. En la siguiente imagen, se puede ver una pista de ejemplo sin formato (pequeños puntos negros) y los centros de los puntos ajustados como círculos de colores (tamaño = número de puntos ajustados).
CREATE table simplified AS
SELECT count(raw.geom)::integer AS count, st_centroid(st_collect(raw.geom)) AS center
FROM raw
GROUP BY st_snaptogrid(raw.geom, 500, 0.5)
ORDER BY count(raw.geom) DESC;
Estaría bastante satisfecho con esta solución, pero existe el problema del tiempo: imaginando la pista como una pista de día completo en una ciudad, la persona puede regresar a lugares ya visitados anteriormente. En mi ejemplo, el círculo azul oscuro representa el hogar de la persona que visitó dos veces, pero mi consulta, por supuesto, lo ignora.
En este caso, la consulta sofisticada solo debe recopilar puntos con marcas de tiempo contiguas (o id), para que produzca dos puntos representativos aquí. Mi primera idea fue una modificación de mi consulta a una versión 3D (tiempo como tercera dimensión), pero no parece funcionar.
¿Alguien tiene algún consejo para mí? Espero que mi pregunta sea clara.
Gracias por la idea de línea. Me di cuenta de hacer y simplificar una cadena lineal como se puede ver en la captura de pantalla a continuación (los puntos son puntos originales). Lo que aún necesito es determinar los lugares de descanso (> x puntos en <x metros de radio), idealmente como un punto con una hora de llegada y una hora de salida ... ¿alguna otra idea?
Respuestas:
Si realmente necesita todos los puntos para la visualización, puede crear una línea y st_simplify (que es la implementación de Douglas Peucker) haría el trabajo bastante bien.
En algunos casos, ni siquiera necesita almacenar todos los puntos, por lo que puede filtrar antes de guardar los datos de los puntos, por ejemplo, cuando el sujeto no se mueve, no lo almacene. Puede aplicar DouglasPeucker o algún otro filtro básico antes de agregar puntos a la base de datos. Además, algunos proveedores de GPS (como la API de ubicación de Android) pueden realizar automáticamente el filtrado inicial en función del tiempo y la distancia mínima. En algunos casos, debe mantener datos duplicados: prefiltrados para visualizaciones rápidas y registro completo para el archivo. El almacenamiento simple es bastante barato hoy en día.
fuente
Mientras tanto, encontré una solución para mi problema:
Primero, determiné un "tipo de distancia" para cada punto. Si el punto está más cerca como x metros del siguiente punto, se determina como "detener", de lo contrario, como "mover". Entonces, comencé una función de ventana como esta:
La tabla resultante tiene el siguiente aspecto:
El siguiente paso simple agrupa los puntos de "detención", identifica el centroide de estos grupos de puntos y toma las marcas de tiempo mínimas y máximas como hora de llegada y salida.
fuente