Comment interpoler les positions GPS dans PostGIS

13

J'ai un tableau PostGIS des positions GPS toutes les cinq secondes:

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)
...

Je recherche une requête qui retournera des valeurs (horodatage et point) pour chaque seconde. Il est normal de supposer que les points sont reliés par une ligne droite.

Je cherche spécifiquement un moyen de le faire à l'intérieur de la base de données et non en écrivant un script externe.

obscur
la source
Je pense que vous aurez besoin d'écrire une fonction PL / Python pour cela.
Pablo
1
Voici un extrait de postgis en action qui pourrait vous aider: bostongis.com/postgis_translate.snippet
Pablo
@Pablo: Oui, très probablement. Je vais ajuster ma question.
underdark

Réponses:

13

Bonjour

Si votre table d'origine s'appelle gps_p, votre champ d'horodatage s'appelle ts et les points s'appellent 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;

Ce qu'il fait, c'est qu'il construit des lignes entre les points et utilise st_segmentize pour diviser la ligne en 5 segments.

Si ce n'est pas exactement 5 secondes entre vos points d'origine, cela ne fonctionnera pas. Ensuite, vous pouvez simplement ajouter un champ id avec une séquence et l'utiliser à la place pour rejoindre la table avec id1 + 1 = id2.

HTH

/ Nicklas

Nicklas Avén
la source
6

voici un projet de code pour pl / python, c'est juste l'idée de base de traduire les points par une distance et un azimut donnés.
Pour exécuter les fonctions postgis en pl / python, la seule solution que j'ai trouvée est d'utiliser plpy.prepare et plpy.execute (très ennuyeux).

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
la source
0

Si je ne me trompe pas ...
Ce que vous devez faire est de déterminer la ligne de connexion, puis de la diviser.

Brad Nesom
la source