Jak interpolować pozycje GPS w PostGIS

13

Co pięć sekund mam tabelę pozycji GPS PostGIS:

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

Szukam zapytania, które zwróci wartości (znacznik czasu i punkt) na każdą sekundę. Można założyć, że punkty są połączone linią prostą.

W szczególności szukam sposobu na zrobienie tego w bazie danych, a nie przez napisanie zewnętrznego skryptu.

podmrok
źródło
Myślę, że musisz do tego napisać funkcję PL / Python.
Pablo
1
Oto fragment postgis w akcji, który może pomóc: bostongis.com/postgis_translate.snippet
Pablo
@Pablo: Tak, najprawdopodobniej. Dostosuję moje pytanie.
podmroku

Odpowiedzi:

13

halo

Jeśli twoja oryginalna tabela nazywa się gps_p, twoje pole znacznika czasu nazywa się ts, a punkty nazywa się 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;

Robi to, że buduje linie między punktami i używa st_segmentize, aby podzielić linię na 5 segmentów.

Jeśli nie będzie dokładnie 5 sekund między oryginalnymi punktami, to nie zadziała. Następnie możesz po prostu dodać pole identyfikatora z sekwencją i użyć go do samodzielnego dołączenia do tabeli za pomocą id1 + 1 = id2.

HTH

/ Nicklas

Nicklas Avén
źródło
6

Oto szkic kodu dla PL / Pythona, to tylko podstawowa idea tłumaczenia punktów o zadaną odległość i azymut.
Aby uruchomić funkcje postgis w pl / python, jedynym rozwiązaniem, które znalazłem, jest użycie plpy.prepare i plpy.execute (bardzo nudne).

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
źródło
0

Jeśli się nie mylę ...
Musisz ustalić linię łączącą, a następnie wykonać na niej podział.

Brad Nesom
źródło