Linie aus Punkten mit PostGIS erstellen?

10

Ich habe eine PostGIS-Tabelle mit Positionsdaten zahlreicher Fahrzeuge und möchte aus diesen Punkten Linien erstellen.

Die Daten können nach Fahrzeug-ID ausgewählt und nach Zeitstempel sortiert werden. Wie werden jedoch Linien aus dem Ergebnis erstellt?

Was ich grundsätzlich brauche, ist ein Liniensegment von Punkt 1 bis Punkt 2, die Linie finalisieren und dann wieder von Punkt 2 bis Punkt 3. Natürlich alles unter Berücksichtigung der Fahrzeug-ID.

Letzteres wird benötigt, weil ich die Fahrtrichtung und Geschwindigkeit des Fahrzeugs von einem Punkt zum nächsten berechnen möchte.

Thomas Becker
quelle
1
Die ST_MakeLine () -Funktion erledigt dies, sobald Sie Ihren GROUP BY-Fahrzeug_ID- und ORDER BY-Zeitstempel ausgearbeitet haben. Siehe: postgis.refractions.net/docs/ST_MakeLine.html
Micha
Okay, ich habe es einfach ausprobiert und die folgende Erklärung abgegeben: 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;Das gibt mir die Spur jedes Fahrzeugs und ist nicht genau das, was ich brauche. Wie kann man ST_MakeLine () anweisen, eine Linie von Punkt 1 bis Punkt 2 zu erstellen, die Linie abzuschließen und eine neue von Punkt 2 bis Punkt 3 zu beginnen ...?
Thomas Becker
Was sind "Punkt 1", "Punkt 2", "Punkt 3"? Woran erkennt man sie?
Micha
Ich dachte, ich erkenne sie an der Reihenfolge des Zeitstempels ... ORDER BY ais_data.bs_ts- ist das möglich? Punkt 1, Punkt 2 usw. sind also im Grunde die Punktinformationen, die in jeder Zeile als Ergebnis der Select-Anweisung angegeben werden.
Thomas Becker
Sie können in einem ersten Schritt eine Zeile pro Fahrzeug und nach dem Generieren eines Scheitelpunkts aus dieser Zeile mithilfe von Tipps aus der Mailingliste postgis postgis.17.x6.nabble.com/…
ThomasG77

Antworten:

12

Dies kann auf verschiedene Arten erfolgen, indem Self-Joins oder korrelierte Unterabfragen verwendet werden. Die Verwendung von Fensterfunktionen ist jedoch wahrscheinlich der einfachste Weg.

Die Funktion lead()gibt einen Wert zurück, der in der angegebenen Partition voraus ist, und unsere Partition ist(PARTITION BY <vehicle_id> ORDER BY <timestamp>)

Diese Abfrage gibt uns die Fahrzeugnummer, die Position dieses Punktes in der Partition (die der Position der damit beginnenden Linie entspricht) und die beiden Geometrien, aus denen die Linie besteht. Natürlich gibt es NULL geom2 für den letzten Punkt zurück, daher müssen wir dies in der äußeren Abfrage überprüfen.

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
quelle