Як визначити та спростити кластерні точки щодо часу в PostGIS?


11

Я тільки почав працювати з просторовими базами даних і хочу написати запит SQL (PostGIS) для автоматичного узагальнення необроблених GPS-треків (з фіксованою частотою відстеження). Перше, про що я веду, - це запит, який визначає точки зупинки у формі запиту, як "x балів на відстані y метрів", щоб замінити масивні хмари точок репрезентативними точками. Я вже зрозумів, що потрібно набрати певні відстані на певній відстані та порахувати оснащені. На малюнку нижче можна побачити грубу прикладну доріжку (маленькі чорні точки) та центри відрізаних точок у вигляді кольорових кіл (розмір = кількість відрізаних точок).

введіть тут опис зображення

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;

Я був би настільки задоволений цим рішенням, але є проблема часу: уявляючи доріжку як довічну доріжку в місті, людина може повернутися до вже відвіданих місць. У моєму прикладі темно-синій круг представляє будинок людини, якого він відвідував двічі, але мій запит, звичайно, це ігнорує.

У цьому випадку складний запит повинен збирати лише очки із суміжними часовими позначками (або ідентифікаторами), щоб він створював дві репрезентативні точки. Моя перша ідея була модифікацією мого запиту до 3d-версії (час як третій вимір), але, схоже, це не працює.

Хтось має поради для мене? Я сподіваюся, що моє питання зрозуміле.


Дякую за лінію-ідею. Я зрозумів, що зробити і спростити рядок рядків, як ви можете бачити на скріншоті нижче (точки - це оригінальні точки). введіть тут опис зображення Що мені ще потрібно - це визначити місця відпочинку (> х балів у радіусі <х метрів), в ідеалі як одна точка з часом прильоту та часом відходу ... будь-які інші ідеї?


2
Вам справді потрібні очки для інших цілей? В іншому випадку це здається, що, можливо, просто створення ліній з точок, а потім спрощення / узагальнення цих ліній буде служити вашому призначенню.
Антоній -ГІСКО-

2
Це захоплююча проблема. Можливо, ви зможете отримати деякі ідеї з того самого питання, яке задавали на сайті Mathematica за адресою mateica.stackexchange.com/questions/2711 . Не всі відповіді використовують часовий вимір даних (але мій :-).
whuber

@ Anthony-GISCOE - це цікавий підхід. Якщо потрібні особливості точок, нові версії можна створити з вершин узагальнених ліній або уздовж таких рядків, як тут gis.stackexchange.com/questions/27102/… . Я знаю, це все ще не оригінальні моменти!
andytilia

@ Ентоні: Мені абсолютно потрібні "репрезентації" -точки будь-якого досі та, принаймні, початкового та кінцевого часу ...
Berlin_J

1
і було б дуже корисно мати postgis-рішення :)
Berlin_J

Відповіді:


4

Якщо вам справді потрібні всі точки для візуалізації, тоді ви можете створити рядок і st_simplify (що є реалізацією Дугласа Пекера) зробив би цю роботу досить непогано.

У деяких випадках вам навіть не потрібно зберігати всі точки, тому ви можете виконати фільтрацію перед збереженням даних точки, наприклад, коли об'єкт не переміщується, не зберігайте їх. Ви можете застосувати DouglasPeucker або якийсь інший базовий фільтр перед додаванням балів до БД. Також деякі GPS-провайдери (наприклад, Android Location API) можуть здійснювати початкову фільтрацію на основі часу та мінімальної відстані автоматично. У деяких випадках ви зберігаєте дублікати даних: попередньо відфільтровані для швидкої візуалізації та повний журнал для архіву. Звичайне зберігання в наш час досить дешеве.


3

Тим часом я знайшов рішення для своєї проблеми:

По-перше, я визначив "тип відстані" для кожної точки. Якщо точка ближче на відстань x метрів до наступної точки, вона визначається як "стоп", інакше як "переміщення". Потім я запустив функцію вікна таким чином:

     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;

Отримана таблиця виглядає так:

введіть тут опис зображення

Простий наступний крок групує точки "зупинки", ідентифікує центроїд цих точкових груп та приймає мінімальні та максимальні часові позначки як час прибуття та відходу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.