PostGIS'te zamana ilişkin nokta kümelerini nasıl belirleyebilir ve basitleştirebiliriz?


11

Ben sadece uzamsal veritabanları ile çalışmaya başladı ve ben ham GPS-parça (genel izleme frekansı ile) otomatik genelleme için bir SQL (PostGIS) sorgusu yazmak istiyorum. Üzerinde uyandığım ilk şey, durma noktalarını, büyük nokta bulutlarını temsili noktalarla değiştirmek için "y metre mesafedeki x noktaları" gibi sorgu biçiminde tanımlayan bir sorgudur. Zaten belirli bir mesafedeki noktaları yakalamayı ve yakalananları saymayı zaten fark ettim. Aşağıdaki resimde bir ham örnek izi (küçük siyah noktalar) ve kopan noktaların merkezleri renkli daireler olarak görülebilir (boyut = kopan nokta sayısı).

resim açıklamasını buraya girin

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;

Bu çözümden oldukça memnun olurdum, ama zaman sorunu var: Parkuru, kişinin daha önce ziyaret ettiği yerlere geri dönebileceği bir şehirde tam günlük bir parkur olarak görmek. Örneğimde, koyu mavi daire, iki kez ziyaret ettiği kişinin evini temsil ediyor, ancak sorgulamam elbette bunu görmezden geliyor.

Bu durumda, karmaşık sorgu yalnızca bitişik zaman damgalarına (veya kimliklere) sahip noktaları toplamalıdır, böylece burada iki temsili nokta üretecektir. İlk fikrim, sorgumun 3 boyutlu bir versiyona (üçüncü boyut olarak zaman) bir modifikasyonuydu, ancak işe yaramadı.

Benim için bir tavsiye var mı? Umarım sorum açıktır.


Çizgi fikir için teşekkür ederim. Aşağıdaki ekran görüntüsünde görebileceğiniz gibi bir linestring yapmayı ve basitleştirmeyi fark ettim (noktalar orijinal noktalardır). resim açıklamasını buraya girin İhtiyacım olan şey dinlenme yerlerini (<x metre yarıçapında> x puan), ideal olarak bir varış zamanı ve bir ayrılma zamanı olan bir nokta olarak belirlemektir.


2
Aslında başka amaçlar için puanlara mı ihtiyacınız var? Aksi takdirde, belki sadece noktalardan çizgiler oluşturmak gibi görünür ve daha sonra bu çizgileri basitleştirmek / genelleştirmek amacınıza hizmet eder.
Anthony -GISCOE-

2
Bu büyüleyici bir problem. Üzerinde istendi esasen aynı soruya gelen bazı fikirler toplamaktadır mümkün olabilir Mathematica bünyesinde mathematica.stackexchange.com/questions/2711 . Bütün cevaplar verinin zamansal boyutunu kullanmaz (ama benimki :-).
whuber

@ Anthony-GISCOE- bu ilginç bir yaklaşım. Nokta özelliklerine ihtiyaç duyulması halinde, genelleştirilmiş hatların köşelerinden veya buradaki çizgiler boyunca yenileri oluşturulabilir . Gis.stackexchange.com/questions/27102/… . Biliyorum, bunlar hala orijinal noktalar değil!
andytilia

@ Anthony: Kesinlikle herhangi bir
sabit standın

1
ve bir postgis-çözümüne sahip olmak gerçekten yararlı olacaktır :)
Berlin_J

Yanıtlar:


4

Görselleştirme için gerçekten tüm noktalara ihtiyacınız varsa, bir çizgi oluşturabilir ve st_simplify (Douglas Peucker uygulamasıdır) işi oldukça güzel yapar.

Bazı durumlarda tüm noktaları saklamanız bile gerekmez, bu nedenle nokta verilerini kaydetmeden önce filtreleme yapabilirsiniz, örneğin konu hareket etmediğinde saklamayın. DB'ye puan eklemeden önce DouglasPeucker veya başka bir temel filtre uygulayabilirsiniz. Ayrıca bazı GPS sağlayıcıları (Android Konum API'sı gibi) otomatik olarak zamana ve minimum mesafeye göre ilk filtreleme yapabilir. Bazı durumlarda yinelenen verileri tutarsınız: hızlı görselleştirmeler için önceden filtrelenmiş ve arşiv için tam günlük. Düz depolama günümüzde oldukça ucuzdur.


3

Bu arada, sorunum için bir çözüm buldum:

İlk olarak, her nokta için bir "mesafe tipi" belirledim. Nokta bir sonraki noktaya x metre kadar yakınsa, "dur", aksi halde "hareket" olarak belirlenir. Sonra şöyle bir pencere işlevi başlattım:

     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;

Ortaya çıkan tablo aşağıdaki gibi görünür:

resim açıklamasını buraya girin

Bir sonraki basit adım "durma" noktalarını gruplandırır, bu nokta gruplarının merkezini belirler ve varış ve ayrılma zamanı olarak minimum ve maksimum zaman damgalarını alır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.