PostGISで時間に関してポイントクラスターを識別および簡素化する方法


11

空間データベースの使用を開始したばかりで、生のGPSトラックを自動で一般化するためのSQL(PostGIS)クエリを作成したい(追跡頻度を固定)。私が最初に注目しているのは、「yメートルの距離内にあるxポイント」のようなクエリの形式で停止ポイントを特定し、代表的なポイントで巨大なポイントクラウドを置き換えるクエリです。特定の距離内でポイントをスナップし、スナップしたものをカウントすることは既に実現しました。下の図では、未加工のサンプルトラック(小さな黒い点)と、スナップされた点の中心が色付きの円(サイズ=スナップされた点の数)として表示されています。

ここに画像の説明を入力してください

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;

私はこのソリューションに非常に満足していますが、時間の問題があります:トラックを1日コースとして都市でイメージすることで、その人は以前に訪れた場所に戻ることができます。私の例では、濃い青色の円は、彼が2回訪れた人の家を表しますが、もちろん私のクエリはそれを無視します。

この場合、洗練されたクエリは、連続するタイムスタンプ(またはID)を持つポイントのみを収集する必要があるため、ここでは2つの代表的なポイントが生成されます。最初のアイデアは、クエリを3Dバージョンに変更することでした(3番目の次元としての時間)が、うまくいかないようです。

誰か私にアドバイスはありますか?私の質問が明確であることを願っています。


ラインアイデアをありがとう。下のスクリーンショットでわかるように、ラインストリングを作成して単純化することに気付きました(ドットは元のポイントです)。 ここに画像の説明を入力してください 私がまだ必要なのは、理想的には到着時間と出発時間を持つ1つのポイントとして、休憩場所(半径<xメートル内のxポイント)を決定することです...他のアイデアはありますか?


2
実際に他の目的のためにポイントが必要ですか?それ以外の場合は、ポイントから線を作成するだけで、それらの線を単純化/一般化することが目的にかなうように思えます。
アンソニー-GISCOE-

2
それは魅力的な問題です。Mathematicaサイトのmathematica.stackexchange.com/questions/2711で尋ねられたのと本質的に同じ質問からいくつかのアイデアを収集できるかもしれません。すべての回答がデータの時間的側面を活用しているわけではありません(ただし、私の場合はそうです:-)。
whuber

@ Anthony-GISCOE-これは興味深いアプローチです。ポイントフィーチャが必要な場合は、一般化されたラインの頂点から、またはここのようなラインに沿って新しいフィーチャを作成できますgis.stackexchange.com/questions/27102/…。私は知っています、それらはまだ元のポイントではありません!
-andytilia

アンソニー@:私は絶対に...「表現」任意のstillstandのポイント超と少なくともスタート-と終了時刻を必要とする
Berlin_J

1

回答:


4

視覚化のために本当にすべてのポイントが必要な場合は、線を作成してst_simplify(ダグラスピアッカーの実装)が非常にうまく機能します。

場合によっては、すべてのポイントを保存する必要さえないので、ポイントデータを保存する前にフィルタリングを行うことができます。たとえば、被写体が動かないときは保存しません。DBにポイントを追加する前に、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;

結果のテーブルは次のようになります。

ここに画像の説明を入力してください

次の簡単な手順では、「停止」ポイントをグループ化し、これらのポイントグループの重心を特定し、最小および最大のタイムスタンプを到着時間と出発時間として取得します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.