Créer une ligne à partir de points à l'aide de PostGIS?

10

J'ai une table PostGIS avec les données de position de nombreux véhicules et je souhaite créer des lignes à partir de ces points.

Les données peuvent être sélectionnées par identifiant de véhicule et commandées par horodatage, mais comment créer des lignes à partir du résultat?

Ce dont j'ai essentiellement besoin, c'est d'un segment de ligne du point 1 au point 2, finaliser la ligne, puis à nouveau du point 2 au point 3. Bien sûr, tout cela en tenant compte de l'ID du véhicule.

Ce dernier est nécessaire parce que je veux calculer la direction et la vitesse de croisière du véhicule d'un point à l'autre.

Thomas Becker
la source
1
La fonction ST_MakeLine () le fera, une fois que vous aurez établi l'horodatage GROUP BY Vehicle_id et ORDER BY. Voir: postgis.refractions.net/docs/ST_MakeLine.html
Micha
D'accord, je l'ai simplement essayé et j'ai émis la déclaration suivante: SELECT ais_data.mmsi, ST_MakeLine(ais_data.geom) AS newgeom INTO ais_lines FROM (SELECT * FROM ais_data ORDER BY ais_data.mmsi, ais_data.bs_ts ASC) AS ais_data GROUP BY ais_data.mmsi;cela me donnera la trace de chaque véhicule, et ce n'est pas exactement ce dont j'ai besoin. Comment dire à ST_MakeLine () de créer une ligne du point 1 au point 2, de finaliser la ligne et d'en démarrer une nouvelle du point 2 au point 3 ...?
Thomas Becker
Que sont "point 1", "point 2", "point 3"? Comment les reconnaissez-vous?
Micha
J'ai pensé à les reconnaître via la commande de l'horodatage ... ORDER BY ais_data.bs_ts- est-ce possible? Ainsi, le point 1, le point 2 et ainsi de suite sont essentiellement les informations de point données dans chaque ligne comme résultat de l'instruction Select.
Thomas Becker
Vous pouvez dans un premier temps générer une ligne par véhicule et ensuite générer un sommet à partir de cette ligne en utilisant les conseils de la liste de diffusion postgis postgis.17.x6.nabble.com/…
ThomasG77

Réponses:

12

Cela peut être fait de plusieurs manières, en utilisant des auto-jointures ou des sous-requêtes corrélées, mais l'utilisation des fonctions de fenêtre est probablement le moyen le plus simple.

La fonction lead()renvoie une valeur qui est en avance dans la partition donnée et notre partition est(PARTITION BY <vehicle_id> ORDER BY <timestamp>)

Cette requête nous donne le numéro du véhicule, la position de ce point dans la partition (qui est égale à la position de la ligne commençant par lui) et les deux géométries qui feront la ligne. Bien sûr, il renvoie NULL geom2 pour le dernier point, nous devons donc vérifier cela dans la requête externe.

SELECT mmsi, num, ST_MAKELINE(geom,geom2) FROM (
  SELECT mmsi, row_number() OVER w AS num, geom, lead(geom) OVER w AS geom2
  FROM ais_data WINDOW w AS (PARTITION BY mmsi ORDER BY bs_ts) ) as q
WHERE geom2 IS NOT NULL;
Jakub Kania
la source