アプリケーションについて少し。
このアプリケーションを使用すると、ユーザーは多角形を描いて bing maps WPF API に保存できます。
私たちが興味を持っているコードは、ポイントがポリゴン内にあるかどうかの天気を見つけることです。LocationCollection
次の関数は、bing マップ上のポリゴンの を単純にループし、ポリゴンSqlGeography object (OpenGisGeographyType.Polygon)
のインスタンスである を作成します。
次に、マウス クリックをSqlGeography object (OpenGisGeographyType.Point)
緯度と経度に変換し、SqlGeography.STIntersection を使用して、ポイントがポリゴン内にあるかどうかを確認します。
図に示すように、ポイントがポリゴンの外側にある場合でも、SqlGeography.STIntersection は交点を返します。(polygonSearch() 関数が返す内容に応じて、ラベルを「配送エリア内」または「エリア内のお客様」に設定しているため、図でこれを確認できます。
写真の右側の例は、ポリゴン内で場所をテストしたときに期待される結果を示しています。
写真の左の例には、予期しない結果が含まれています。これは、ポイントがポリゴン内にあることを示していますが、明らかにそうではありません!
ノート:
- SqlGeography (myShape) を使用して図形をマップに配置するので、図形が適切な頂点で構築されていることがわかります。
- SqlGeography (myPoint) を使用してピンをマップに配置するので、ピンが正しい頂点でテストされていることがわかります。
- これは大きなポリゴンでのみ失敗します
以下に、メモリ内にポリゴンを作成し、マウス クリック イベントを緯度経度に変換するコードを示します。( bing api を必要とせずにこれを見ることができるように、ポリゴンの頂点をコメントに含めました。 for ループをその上のコメントに置き換えるだけです ) ただし、Microsoft.SqlServer.Types.dl
SqlGeography オブジェクトを作成するには l を参照する必要があります。SQL Express 2008 では無料で、次の場所にあります。C:\Program Files (x86)\Microsoft SQL Server\100\SDK\Assemblies
public bool polygonSearch2(LocationCollection points, double lat, double lon)
{
SqlGeography myShape = new SqlGeography();
SqlGeographyBuilder shapeBuilder = new SqlGeographyBuilder();
// here are the verticies for the location collection if you want to hard code and try
//shapeBuilder.BeginFigure(47.4275329011347, -86.8136038458706);
//shapeBuilder.AddLine(36.5102408627967, -86.9680936860962);
//shapeBuilder.AddLine(37.4928909385966, -80.2884061860962);
//shapeBuilder.AddLine(38.7375329179818, -75.7180936860962);
//shapeBuilder.AddLine(48.0932596736361, -83.7161405610962);
//shapeBuilder.AddLine(47.4275329011347, -86.8136038458706);
//shapeBuilder.EndFigure();
//shapeBuilder.EndGeography();
// Here I just loop through my points collection backwards to create the polygon in the SqlGeography object
for (int i = points.Count - 1; i >= 0; i--)
{
if (i == 0)
{
shapeBuilder.AddLine(points[i].Latitude, points[i].Longitude);
shapeBuilder.EndFigure();
shapeBuilder.EndGeography();
continue;
}
if (i == points.Count - 1)
{
shapeBuilder.SetSrid(4326);
shapeBuilder.BeginGeography(OpenGisGeographyType.Polygon);
shapeBuilder.BeginFigure(points[i].Latitude, points[i].Longitude);
continue;
}
else
{
shapeBuilder.AddLine(points[i].Latitude, points[i].Longitude);
}
}
myShape = shapeBuilder.ConstructedGeography;
// Here I am creating a SqlGeography object as a point (user mouse click)
SqlGeography myPoint = new SqlGeography();
SqlGeographyBuilder pointBuilder = new SqlGeographyBuilder();
pointBuilder.SetSrid(4326);
pointBuilder.BeginGeography(OpenGisGeographyType.Point);
// Should pass, which it does
// Lat: lat = 43.682110574649791 , Lon: -79.79005605528323
// Should fail, but it intersects??
// Lat: 43.682108149690094 , Lon: -79.790037277494889
pointBuilder.BeginFigure(lat, lon);
pointBuilder.EndFigure();
pointBuilder.EndGeography();
myPoint = pointBuilder.ConstructedGeography;
SqlGeography result = myShape.STIntersection(myPoint);
if (result.Lat.IsNull)
return false;
else
return true;
}
どんな助けでも大歓迎です。私はこの問題で上司を怒らせ始めています >.<
これは SRID と関係がありますか?