Jak zidentyfikować i uprościć klastry punktowe w odniesieniu do czasu w PostGIS?

11

Właśnie zacząłem pracować z przestrzennymi bazami danych i chcę napisać zapytanie SQL (PostGIS) do automatycznego generowania surowych śladów GPS (ze stałą częstotliwością śledzenia). Pierwszą rzeczą, o której mówię, jest zapytanie, które identyfikuje punkty zatrzymania w formie zapytania, takiego jak „x punktów w odległości y metrów”, aby zastąpić masywne chmury punktów reprezentatywnymi punktami. Już zdałem sobie sprawę, że przyciągam punkty w pewnej odległości i liczę te. Na poniższym zdjęciu widać surowy przykładowy ślad (małe czarne punkty) i środki punktów przyciągania w postaci kolorowych kół (rozmiar = liczba punktów przyciągania).

wprowadź opis zdjęcia tutaj

CREATE table simplified AS 
 SELECT count(raw.geom)::integer AS count, st_centroid(st_collect(raw.geom)) AS center
   FROM raw
  GROUP BY st_snaptogrid(raw.geom, 500, 0.5)
  ORDER BY count(raw.geom) DESC;

Byłbym bardzo zadowolony z tego rozwiązania, ale istnieje problem czasowy: wyobrażając sobie tor jako całodniowy tor w mieście, osoba może wrócić do miejsc, które już odwiedził. W moim przykładzie ciemnoniebieskie kółko reprezentuje dom osoby, którą odwiedził dwukrotnie, ale moje zapytanie oczywiście to ignoruje.

W takim przypadku wyrafinowane zapytanie powinno gromadzić tylko punkty z ciągłymi znacznikami czasu (lub identyfikatorami), aby wygenerować tutaj dwa reprezentatywne punkty. Moim pierwszym pomysłem była modyfikacja mojego zapytania do wersji 3d (czas jako trzeci wymiar), ale wydaje się, że nie działa.

Czy ktoś ma dla mnie jakąś radę? Mam nadzieję, że moje pytanie jest jasne.


Dziękuję za pomysł na linię. Uświadomiłem sobie, że mogę stworzyć i uprościć znakowanie linii, jak widać na zrzucie ekranu poniżej (kropki są oryginalnymi punktami). wprowadź opis zdjęcia tutaj Nadal potrzebuję określić miejsca odpoczynku (> x punktów w promieniu <x metrów), idealnie jako jeden punkt z czasem przybycia i czasem wyjazdu ... jakieś inne pomysły?

Berlin_J
źródło
2
Czy faktycznie potrzebujesz punktów do innych celów? W przeciwnym razie wydaje się, że może po prostu tworzenie linii z punktów, a następnie uproszczenie / uogólnienie tych linii spełni twoje zadanie.
Anthony -GISCOE-
2
To fascynujący problem. Być może uda ci się zebrać pomysły z tego samego pytania, które zostało zadane na stronie Mathematica pod adresem mathematica.stackexchange.com/questions/2711 . Nie wszystkie odpowiedzi wykorzystują wymiar czasowy danych (ale moje :-).
whuber
@ Anthony-GISCOE- to ciekawe podejście. Potrzebne są w funkcje punktowe Case, nowe mogą być tworzone z wierzchołków ogólnych liniach lub wzdłuż linii podoba tutaj gis.stackexchange.com/questions/27102/... . Wiem, że to wciąż nie są oryginalne punkty!
andytilia
@ Anthony: Absolutnie potrzebuję punktów „reprezentacji” każdego stojącego miejsca, a przynajmniej czasu rozpoczęcia i zakończenia ...
Berlin_J,
1
i przydałoby się mieć rozwiązanie postgis :)
Berlin_J,

Odpowiedzi:

4

Jeśli naprawdę potrzebujesz wszystkich punktów do wizualizacji, możesz utworzyć linię i st_simplify (czyli implementacja Douglasa Peuckera) wykonałaby to zadanie całkiem nieźle.

W niektórych przypadkach nie musisz nawet przechowywać wszystkich punktów, więc możesz wykonać filtrowanie przed zapisaniem danych punktów, np. Gdy obiekt się nie porusza, nie przechowuj go. Możesz zastosować DouglasPeucker lub jakiś inny podstawowy filtr przed dodaniem punktów do DB. Również niektórzy dostawcy GPS (np. Android Location API) mogą automatycznie przeprowadzić wstępne filtrowanie na podstawie czasu i minimalnej odległości. W niektórych przypadkach możesz zachować duplikaty danych: wstępnie filtrowane w celu szybkiej wizualizacji i pełny dziennik do archiwizacji. Zwykłe przechowywanie jest obecnie dość tanie.

JaakL
źródło
3

Tymczasem znalazłem rozwiązanie mojego problemu:

Najpierw określiłem „typ odległości” dla każdego punktu. Jeśli punkt znajduje się bliżej x metrów od następnego punktu, określa się go jako „stop”, w przeciwnym razie jako „ruch”. Następnie uruchomiłem taką funkcję okna:

     SELECT t1.id, t1.dist_type, t1."time", t1.the_geom, t1.group_flag, sum(t1.group_flag) OVER (ORDER BY t1.id) AS group_nr
FROM ( SELECT distances.id, distances.the_geom, distances."time", distances.dist_type, 
                CASE
                    WHEN lag(distances.dist_type) OVER (ORDER BY distances.id) = distances.dist_type THEN NULL::integer
                    ELSE 1
                END AS group_flag
           FROM distances) t1;

Wynikowa tabela wygląda następująco:

wprowadź opis zdjęcia tutaj

Prosty następny krok grupuje punkty „zatrzymania”, identyfikuje środek ciężkości tych grup punktów i przyjmuje minimalne i maksymalne znaczniki czasu jako czas przyjazdu i wyjazdu.

Berlin_J
źródło