即使我知道没有交集,SqlGeography.STIntersection()也会返回

关于应用程序;

该应用程序允许用户将多边形绘制并保存到bing贴图WPF api上。

我们感兴趣的代码是找到天气,一个点是否在多边形中。 以下函数只是在bing映射上循环遍历多边形的LocationCollection ,并创建一个SqlGeography object (OpenGisGeographyType.Polygon) ,它是多边形的一个实例。

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

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

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

图片中的左侧示例包含意外结果 – 这表示一个点在多边形内,当它显然不是!

在此处输入图像描述

笔记:

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

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

我通过使用LocationToViewPortpoint函数将我的所有多边形lat / long转换为屏幕上的Point对象,以及我正在测试交叉点的点来修复此问题,并在我的STIntersects使用X和Y值而不是lat / long。