关于应用程序的一些知识;
该应用程序允许用户在多边形地图WPF api上绘制和保存多边形。
我们感兴趣的一段代码是查找天气是否在多边形中。以下函数简单地在bing地图上循环通过多边形的LocationCollection
,并创建作为多边形实例的SqlGeography object (OpenGisGeographyType.Polygon)
。
然后,我们通过纬度和经度将鼠标单击转换为SqlGeography object (OpenGisGeographyType.Point)
,并使用SqlGeography.STIntersection查找我们的点是否位于多边形内。
如图所示,即使该点在多边形之外,SqlGeography.STIntersection仍返回交点。 (您可以在图片中告诉您这一点,因为我根据返回的polygonSearch()函数将标签设置为“交货范围内”或“客户属于我们的区域”)。
当在多边形内测试位置时,图片中的右侧示例具有预期的结果。
图片中的左侧示例包含意外结果-指示点在多边形内,而显然不是!
笔记:
我使用SqlGeography(myShape)将形状放在地图上,所以我知道
正在使用适当的顶点构造形状。
我使用SqlGeography(myPoint)将图钉放在地图上,所以我知道
引脚正在正确的位置进行测试。
仅在大型多边形上失败
下面,我将介绍在内存中创建多边形以及将鼠标单击事件转换为经度和纬度的代码。 (我在注释中包含了多边形顶点,因此无需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有什么关系吗?
最佳答案
我通过使用Point
函数将所有多边形的lat / long转换为屏幕上的LocationToViewPortpoint
对象以及正在测试交点的点来解决此问题,并使用X和Y值代替lat / long在我的STIntersects
中。
关于c# - 即使我知道没有交集,SqlGeography.STIntersection()也会返回,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17458117/