2

关于应用程序的一些信息;

该应用程序允许用户在 bing 地图 WPF api 上绘制和保存多边形。

我们感兴趣的代码是查找某个点是否在多边形内的天气。下面的函数简单地循环遍历LocationCollectionbing 地图上的多边形,并创建SqlGeography object (OpenGisGeographyType.Polygon)一个多边形实例。

然后我们将鼠标点击转换SqlGeography object (OpenGisGeographyType.Point)为纬度和经度,并使用 SqlGeography.STIntersection 来查找我们的点是否位于多边形内。

如图所示,即使该点在多边形之外,SqlGeography.STIntersection 仍然返回一个交点。(您可以在图片中看出这一点,因为我将标签设置为“在交付区域内”或“我们的区域内的客户”,具体取决于 polyalSearch() 函数返回的内容。

当在多边形内测试位置时,图片中的右侧示例具有预期结果。

图片中左边的例子包含了意想不到的结果——这表明一个点在一个多边形内,而它显然不是!

在此处输入图像描述

笔记:

  • 我使用 SqlGeography (myShape) 将形状放在地图上,所以我知道形状是用适当的顶点构造的。
  • 我使用 SqlGeography (myPoint) 将图钉放在地图上,所以我知道图钉正在正确的顶点进行测试。
    • 这只在大多边形上失败

下面我给出了在内存中创建多边形以及将鼠标单击事件转换为纬度、经度的代码片段。(我已经在注释中包含了多边形顶点,这样就可以在不需要 bing api 的情况下查看它,只需将 for 循环替换为上面的注释)虽然,您需要引用Microsoft.SqlServer.Types.dll 来创建 SqlGeography 对象。它在 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 有关吗?

4

1 回答 1

0

我通过使用函数将我所有的多边形纬度/经度转换Point为屏幕上的对象来解决这个LocationToViewPortpoint问题,以及我正在测试交叉点的点,并使用 X 和 Y 值而不是我的STIntersects.

于 2013-07-06T05:38:53.390 回答