Cómo interpolar posiciones GPS en PostGIS

13

Tengo una tabla PostGIS de posiciones GPS por cada cinco segundos:

2011-01-01 00:00:05, POINT(x1,y1)
2011-01-01 00:00:10, POINT(x2,y2)
2011-01-01 00:00:15, POINT(x3,y3)
...

Estoy buscando una consulta que devuelva valores (marca de tiempo y punto) por cada segundo. Está bien suponer que los puntos están conectados por una línea recta.

Estoy buscando específicamente una forma de hacer esto dentro de la base de datos y no escribiendo algún script externo.

bajo oscuro
fuente
Creo que tendrá que escribir una función PL / Python para eso.
Pablo
1
Aquí hay un fragmento de postgis en acción que puede ayudar: bostongis.com/postgis_translate.snippet
Pablo
@Pablo: Sí, lo más probable. Ajustaré mi pregunta.
oscuro

Respuestas:

13

Hola

Si su tabla original se llama gps_p, su campo de marca de tiempo se llama ts y los puntos se llaman th_geom:

SELECT (geom).geom,  ts1 + (((geom).path[1]-1) ||' seconds')::interval FROM 
    (SELECT ts1, ST_DumpPoints(ST_Segmentize(geom, ST_Length(geom)/5)) as geom FROM 
        (SELECT ts1, ST_LineFromMultipoint(ST_Union(geom1, geom2)) as geom FROM
            (SELECT p1.ts as ts1, p2.ts as ts2, p1.the_geom as geom1, p2.the_geom as geom2 
                FROM gps_p p1 INNER JOIN gps_p p2 on p1.ts + '00:00:05'::interval = p2.ts
            ) a
        )b
    ) c
WHERE (geom).path[1] <= 5;

Lo que hace es que construye líneas entre los puntos y usa st_segmentize para dividir la línea en 5 segmentos.

Si no son exactamente 5 segundos entre sus puntos originales, no funcionará. Luego, puede agregar un campo de identificación con una secuencia y usarlo para unirse a la tabla con id1 + 1 = id2 en su lugar.

HTH

/ Nicklas

Nicklas Avén
fuente
6

Aquí hay un borrador de código para pl / python, es solo la idea básica de traducir los puntos por una distancia y acimut dados.
Para ejecutar funciones postgis en pl / python, la única solución que encontré es usar plpy.prepare y plpy.execute (muy aburrido).

total_distance=St_distance(P1,P2)
azimuth=st_azimuth(p1,p2)
partial_distance=total_distance / 5

for i in range(4):
  distance = (i+1)*partial_distance
  x_increment=distance*math.cos(math.degrees(azimuth))
  y_increment=distance*math.sin(math.degrees(azimuth))
  ST_translate(P1, x_increment, y_increment)
Pablo
fuente
0

Si no me equivoco ...
Lo que debe hacer es determinar la línea de conexión y luego dividirla.

Brad Nesom
fuente