セグメントを一致させるためのアルゴリズム


23

セグメントを一致させる最適なアルゴリズムは何ですか?

2つのマップソースの対応するセグメントを一致させようとしています。1つは精度が低くなりますが、セグメント名があり、もう1つはセグメント名がない場合です。より正確なマップにセグメント名を半自動的に適用したい。

「一致」が十分に定義されておらず、多くの要因(方向、相対的な長さ、距離)が異なるシナリオで異なる重みを持っているため、要求されたアルゴリズムは非常に曖昧な説明を持っています。ただし、この問題を処理するための一般的なアプローチに関する基本的な知識を探しています。

オープンソース環境(PostGISなど)の実用的な実装は大歓迎です。

サンプルセグメント:以下の説明を参照してください。


データのスナップショットを投稿して、セグメント密度の概要とそれらの違いを教えてください。
ジュリアン

1
flickrにいくつかのイラストを投稿しました。リンクを参照してください。
アダムMatan

1
「conflation」を検索してみてください。
カーククイケンダル

回答:


14

ハウスドルフ距離を用いることができる:マッチング・セグメントは、この距離に応じて「閉じる」セグメントとすることができます。セグメントの計算は非常に簡単です。

無料のJava実装がJTSで利用可能です-JTS Distance Packageをご覧ください。また、JCS Conflation Suite(現在は放棄されている、https://github.com/oschrenk/jcsなどのソースのコピー)もご覧ください


2
ハウスドルフ距離もGEOSからPostGISにあるため、JTS
NicklasAvén

10

それがあなたのセグメントの詳細に依存するので、私は何が「最高」になるかわかりません。

一般的に良いアプローチは、セグメントを重要な幾何学的情報ハッシュすることです。これには、少なくとも、中心の位置(x、y)、方向(0〜180度)、および長さが含まれます。適切な重みを適用し、方向を細かく設定すると(180が0に戻るため)、すべてのセグメントのコレクションにほぼすべての統計的クラスタリングアルゴリズムを適用できます。(K-meansは適切なオプションですが、ほとんどの階層的方法はうまく機能するはずです。このようなクラスター分析は高速で適用しやすい傾向があります。)は簡単だ。

方向の問題に対処する1つの方法は、ラベル付きセグメントのコピーを作成することです。90未満の場合、最初のコピーの方向に180度を加算し、それ以外の場合は方向から180度を減算します。これにより、データセットが(明らかに)大きくなりますが、それ以外はアルゴリズムを変更しません。

座標、長さ、方向の違いは、対応するセグメントの類似性に関してまったく異なることを意味するため、重みが必要です。多くのアプリケーションでは、セグメント間の違いは、エンドポイントの場所の違いから生じます。大まかな概算として、セグメントの長さの典型的な変動は、エンドポイント間の典型的な変動とほぼ同じであると予想できます。したがって、x、y、およびlengthに関連付けられた重みはほぼ同じである必要があります。オリエンテーションを距離と同等にすることはできず、さらに悪いことに、短いセグメントは長いセグメントよりも誤った方向になりやすいため、トリッキーな部分はオリエンテーションに重みを付けます。いくつかの角度のずれをセグメント間の典型的なギャップのサイズと同等にし、手順がうまくいくように見えるまで調整する試行錯誤の方法を考えてください。ガイダンスについては、みましょうLは典型的なセグメント長です。小さな角度t度による方向の変化は、約L / 2 * t / 60の距離を掃引します (60は1ラジアンの度数に近似します)。これは L / 120倍のtです。これは、x、y、および長さの単位重量と、向きのL / 120の重量から開始することをお勧めします。

要約すると、この提案は次のとおりです。

  1. ラベル付きセグメントのコピーを作成します(方向の微調整に関する段落で説明されています)。

  2. 各セグメントを4倍(x、y、長さ、L / 120 *方向)に変換します。ここで、Lは一般的なセグメントの長さです。

  3. 四重極のクラスター分析を実行します。適切な統計パッケージを使用してください(Rは無料です)。

  4. クラスター分析の出力をルックアップテーブルとして使用して、ラベル付きセグメントを近くのラベルなしセグメントに関連付けます。


4

5年ほど前に、同様の要件を持つプロジェクトに取り組みました。道路の中心線からの座標を(比較的高い座標精度で)組み合わせて、Highway Performance Monitoring System(HPMS)の交通ネットワークリンクを結合しました。

当時、FHWAはこのようなことを行うためのツールを提供していませんでした。変更された可能性がありますので、確認してください。高速道路のデータを使用していない場合でも、ツールは関連する可能性があります。

ArcGISで作成しましたが、ISegmentGraphと同様のトレース機能を提供する限り、アルゴリズムはオープンソースで動作するはずです

// features is a collection of features with higher geometry
// Links are a collection features with attributes but low res geometry
For each Link in lowResFeatureclass
    point startPoint = SnapToClosestPoint(Link.StartPoint, hiResfeatures);
    if(startPoint == null)
       continue;
    point endPoint = SnapToClosest(Link.EndPoint, hiResfeatures);
    if(endPoint == null)
       continue;
    polyline trace = Trace(hiResfeatures,startPoint,endPoint);
    if(polyline != null)
    {
        // write out a link with high precision polyline
        Write(Link,polyline);
    }
Next Link

4

ここにアイデアがあります

比較するためにラインストリングの1つを引き裂いて比較し、頂点ポイントが他の比較するラインストリングからある距離内にあるかどうかをテストする場合、多くの方法でテストを制御できます。

それらの例はPostGISで動作します(だれが推測できるでしょう:-))

まず、table_1の線ストリングのすべての頂点ポイントが0.5メートル(マップ単位)またはtable_2の線ストリングに近い場合に一致すると言います。

SELECT a.id, b.id FROM
(SELECT ST_NPoints(the_geom) as num_of_points,
(ST_Dumppoints(the_geom)).geom as p, id FROM table_1) a 
INNER JOIN 
table_2 b 
ON ST_DWithin(a.p, b.the_geom, 0.5) GROUP BY a.id, b.id
HAVING COUNT(*)=num_of_points;

次に、table_1の線ストリングの頂点ポイントの60%以上がtable_2の線ストリングの距離内にある場合に一致すると言うことができます。

SELECT a.id, b.id FROM
(SELECT ST_NPoints(the_geom) as num_of_points, 
(ST_Dumppoints(the_geom)).geom as p, id FROM table_1) a 
INNER JOIN 
table_2 b 
ON ST_DWithin(a.p, b.the_geom, 0.5) GROUP BY a.id, b.id
HAVING COUNT(b.id)/num_of_points::float > 0.6

または、1つのポイントが範囲内にないことを受け入れることができます。

SELECT a.id, b.id FROM
(SELECT ST_NPoints(the_geom) as num_of_points, 
(ST_Dumppoints(the_geom)).geom as p, id FROM table_1) a 
INNER JOIN 
table_2 b 
ON ST_DWithin(a.p, b.the_geom, 0.5) GROUP BY a.id, b.id
HAVING COUNT(b.id)-num_of_points <= 1;

また、逆の役割でtable_1とtable_2を使用してクエリを実行する必要があります。

私はそれがどれくらい速くなるかわかりません。ST_Dumppointsは現在、PostGISのsql関数であり、必要以上に遅くなるC関数ではありません。しかし、とにかく非常に高速になると思います。

空間インデックスは、ST_Dwithinが効果的に機能するのに役立ちます。

HTHニクラス


1
+1これは、最後に使用したアプローチに非常に似ています(すぐに回答を投稿します)。
アダムマタン

4

境界線ジェネレーターで、ずさんなラインセグメントマッチング(およびオーバーラップ)を処理するコードを記述しました。http://blog.shoutis.org/2008/10/inside-boundary-generator-computational.htmlで、その背後にある(かなり基本的な)数学を書きました。コードはオープンソースであり、そのブログ投稿からリンクされています。

コードは非常に単純なアプローチに従います。

  • 2つのラインセグメントが指定された角度と距離の許容範囲内でオーバーラップするかどうか、およびオーバーラップの量を示すセグメントセグメントテスト。
  • データセット内のすべてのラインセグメントをデータセット内の他のすべてのラインセグメントに対してテストする必要をなくす、クイックアンドダーティな空間インデックス。

このアプローチの主な利点は、有効な角度、距離、およびオーバーラップの長さに対して、きちんと正確なノブを取得できることです。欠点は、2つの線分セグメントの類似性を一般的に測定する方法ではないため、たとえば統計的なクラスタリングを行って一致する可能性を判断することははるかに困難です。正確なノブにこだわっています。

注:十分なSQLチョップにより、セグメント間テストをWHERE句に詰め込むことができると推測しています... :)

乾杯!


+1これは素晴らしいアプローチです。クアッドツリーを構築すると、計算上優れたものになります。ただし、細部に注意が必要です:セグメントの近接または類似性(交差の代わりに)を決定する場合、データ構造がセグメントの一意の表現を提供しないという事実を考慮する必要があります:方向vxで始まるセグメント、長さのT等しく良好にセグメント発信元であるX + TのV方向に-v長のT
whuber

1

ここで、比較的簡単に使用できるマップマッチングの大まかなプロトタイプを実装しました。オープンソースのルーティングエンジンに基づいており、Javaで書かれています。ここで使用されたアルゴリズムについて説明します

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