Bagaimana cara mengidentifikasi dan menyederhanakan cluster titik sehubungan dengan waktu di PostGIS?

11

Saya baru saja mulai bekerja dengan database spasial dan saya ingin menulis query SQL (PostGIS) untuk generalisasi otomatis trek-GPS mentah (dengan frekuensi pelacakan tetap). Hal pertama yang saya wokring adalah kueri yang mengidentifikasi titik macet dalam bentuk kueri seperti "x titik dalam jarak y meter" untuk menggantikan titik awan besar dengan titik yang representatif. Saya sudah sadar untuk mengambil poin dalam jarak tertentu dan menghitung yang terputus. Pada gambar di bawah ini orang dapat melihat trek contoh mentah (titik hitam kecil) dan pusat-pusat titik bentak sebagai lingkaran berwarna (ukuran = jumlah titik bentak).

masukkan deskripsi gambar di sini

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;

Saya akan cukup puas dengan solusi ini, tetapi ada masalah waktu: Pencitraan trek sebagai trek sehari penuh di kota orang dapat kembali ke tempat-tempat yang sudah dikunjungi sebelumnya. Dalam contoh saya, lingkaran biru tua melambangkan rumah orang yang ia kunjungi dua kali tetapi pertanyaan saya tentu saja mengabaikannya.

Dalam hal ini, kueri canggih hanya mengumpulkan poin dengan cap waktu berdekatan (atau id), sehingga akan menghasilkan dua poin representatif di sini. Gagasan pertama saya adalah modifikasi kueri saya ke versi 3d (waktu sebagai dimensi ketiga), tetapi tampaknya tidak berfungsi.

Adakah yang punya saran untuk saya? Saya harap pertanyaan saya jelas.


Terima kasih untuk ide garisnya. Saya menyadari untuk membuat dan menyederhanakan linestring seperti yang dapat Anda lihat pada tangkapan layar di bawah ini (titik adalah poin asli). masukkan deskripsi gambar di sini Apa yang masih saya butuhkan adalah menentukan tempat istirahat (> x poin dalam radius <x meter), idealnya sebagai satu titik dengan waktu kedatangan dan waktu berangkat ... ada ide lain?

Berlin_J
sumber
2
Apakah Anda benar-benar membutuhkan poin untuk tujuan lain? Kalau tidak, sepertinya mungkin hanya membuat garis dari titik, dan kemudian menyederhanakan / menggeneralisasi garis itu akan melayani tujuan Anda.
Anthony -GISCOE-
2
Ini masalah yang menarik. Anda mungkin dapat memperoleh beberapa ide dari pertanyaan yang pada dasarnya sama yang ditanyakan di situs Mathematica di Mathematica.stackexchange.com/questions/2711 . Tidak semua jawaban mengeksploitasi dimensi temporal data (tetapi milik saya tidak :-).
whuber
@ Anthony-GISCOE- itu pendekatan yang menarik. Dalam hal fitur titik diperlukan, yang baru dapat dibuat dari simpul garis yang digeneralisasi, atau sepanjang garis seperti di sini gis.stackexchange.com/questions/27102/… . Saya tahu, itu masih bukan poin asli!
andytilia
@ Anthony: Saya benar-benar membutuhkan "representasi" - titik dari setiap stillstand dan setidaknya mulai - dan akhir ...
Berlin_J
1
dan akan sangat berguna untuk memiliki solusi postgis :)
Berlin_J

Jawaban:

4

Jika Anda benar-benar membutuhkan semua poin untuk visualisasi, maka Anda dapat membuat garis dan st_simplify (yang merupakan implementasi Douglas Peucker) akan melakukan pekerjaan dengan cukup baik.

Dalam beberapa kasus Anda bahkan tidak perlu menyimpan semua poin, sehingga Anda bisa melakukan pemfilteran sebelum menyimpan data poin, misalnya ketika subjek tidak bergerak, jangan menyimpannya. Anda dapat menerapkan DouglasPeucker atau beberapa filter dasar lainnya sebelum menambahkan poin ke DB. Juga beberapa penyedia GPS (seperti Android Location API) dapat melakukan penyaringan awal berdasarkan waktu dan jarak minimum secara otomatis. Dalam beberapa kasus, Anda membuat menyimpan data duplikat: difilter untuk visualisasi cepat dan log lengkap untuk arsip. Penyimpanan polos cukup murah saat ini.

JaakL
sumber
3

Sementara itu, saya menemukan solusi untuk masalah saya:

Pertama, saya menentukan "tipe jarak" untuk setiap titik. Jika titik lebih dekat sebagai x meter ke titik berikutnya, itu ditentukan sebagai "berhenti", atau "bergerak". Kemudian, saya memulai fungsi jendela seperti ini:

     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;

Tabel yang dihasilkan terlihat sebagai berikut:

masukkan deskripsi gambar di sini

Langkah sederhana berikutnya mengelompokkan titik "berhenti", mengidentifikasi titik pusat dari kelompok titik ini, dan mengambil cap waktu minimum dan maksimum sebagai waktu kedatangan dan berangkat.

Berlin_J
sumber