10

私は Dundas Maps を使用して、ビジネスの実装に固有の地域に国がグループ化された世界地図を描こうとしています。

世界各国の形状データ (ポイントとセグメント) があります。リージョン内の国のすべてのポイントとセグメントを新しいリージョン シェイプに追加することで、国をリージョンに結合できます。

foreach(var region in GetAllRegions()){
    var regionShape = new Shape { Name = region.Name };
    foreach(var country in GetCountriesInRegion(region.Id)){
        var countryShape = GetCountryShape(country.Id);
        regionShape.AddSegments(countryShape.ShapeData.Points, countryShape.ShapeData.Segments);
    }
    map.Shapes.Add(regionShape);
}

問題は、国の境界線がまだ地域内に表示されていることです。地域の境界線のみが表示されるように、それらを削除したいと考えています。

Dundas ポリゴンは、同じポイントで開始および終了する必要があります。これは、すべての国の形状に当てはまります。次に、次のことができるアルゴリズムが必要です。

  • 地域の境界セグメントに参加できるように、地域の境界で国境が交差する場所を特定します。
  • どの国境が地域の境界ではないかを判断して、それらを破棄できるようにします。
  • 結果の地域ポイントを並べ替えて、形状の境界を順番に記述します。

以下は、私がこれまで地図でたどり着いた場所です。国境はまだ削除する必要があることがわかります。たとえば、モンゴルと中国の国境は破棄する必要がありますが、モンゴルとロシアの国境は維持する必要があります。

地域の境界を保持する必要がある理由は、地域の色は情報を伝える上で重要ですが、隣接する地域は同じ色である可能性があるためです。地域は、国を含めたり除外したりするために変更できます。これが、地域の形成が動的でなければならない理由です。

編集: 私が探しているのはポリゴンのUNIONであることを今知っています。David Leanが SQL Server 2008 の空間関数を使用してそれを行う方法を説明していますが、これはオプションかもしれませんが、結果として得られるポリゴン ユニオンが非常に複雑であるため、SQL が 43,680 文字で切り捨てるため、私の努力は停止しました。私は現在、その回避策を見つけるか、コードでユニオンを実行する方法を見つけようとしています。

地域マップ

4

2 に答える 2

5

国をグループ化するとき、重複がないことを願っています-共有頂点を探すかなり単純なアルゴリズムを使用できます-単純なビューは、1つのポリゴン上のポイントを反復処理し、それが他のポリゴン上にあるかどうかを確認することです、および同じ次または前のポイントを共有して、一致があるかどうかを確認します。次に、共有頂点を削除してユニオンを作成します

于 2010-04-19T13:40:48.547 に答える
1

近隣諸国が共通の頂点と辺を共有していると仮定します (そうでない場合、問題はさらに困難になります)。

地域ごとに、その地域の国に対応するポリゴンを調べて、頂点とエッジのリストを作成します。各エッジには、その端点である 2 つの頂点へのポインターが必要であり、各頂点には、それが端点であるエッジへのポインターが必要です。

リストに頂点を追加するときは、それらが一意の頂点であることを確認してください。つまり、座標(x,y)で頂点を追加する場合、リストにそのような頂点が既にある場合は、新しい頂点を追加しないでください。つまり、すべての新しい頂点を、既にリストにあるものと比較してチェックする必要がある可能性があります。領域のバウンディング ボックスを頂点を格納できるnx個のビンに分割することで、これを高速化できます。n新しい頂点が入ってきたら、そのビンを調べて、そのビン内の他の頂点と照合します。

エッジ リストにエッジを追加するときは、同じことを行います。エッジ (v0,v1) を追加する場合は、既存のエッジ (v0,v1) または (v1,v0) があるかどうかを確認します。この場合を除き、既存のエッジをリストから削除し、新しいエッジを追加しないでください。これは、これら 2 つのエッジが互いに「キャンセル」するためです。これらは隣接する国から来ています。また、削除されたエッジに対応する頂点リスト内のエッジ ポインターを削除することを忘れないでください。

完了すると、2 つの国で共有されていないエッジのリストが表示されます。これらは、領域の境界を形成するエッジです。また、2 つのエッジを指している頂点と、エッジを指していない頂点のリストも必要です。前の頂点は領域の境界にあります。

次に、エッジ リストからエッジを選択し、エッジ リストから削除します (そして、その端点である頂点から対応するエッジ ポインターを削除します)。頂点の終点の 1 つに移動すると、別のエッジを指します。このようにして、領域の境界に沿って端から端まで歩きます。これらのエッジをエッジリストから削除するときに、これらのエッジを regionShape に追加します。最終的に、最初のエッジのエンドポイントに戻り、閉ループになります。

エッジリストにエッジが残っている場合は、プロセスを再度開始して別の境界ループを抽出し、すべての境界ループが抽出されてエッジリストが空になるまで続行します。

1 つの最適化について言及しました。これは、頂点が等しいかどうかをより迅速にテストできるように、頂点を空間的にビンに編成することです。もう 1 つの最適化は、リストからエッジを物理的に削除することを避け、単に「削除済み」としてマークすることです。

于 2010-04-23T20:00:45.157 に答える