2013-07-03 21 views
2

有关应用程序;SqlGeography.STIntersection()返回即使我知道没有交集

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

我们感兴趣的代码是发现天气点是多边形或不是。下面的函数简单地遍历冰箭地图上的多边形的LocationCollection,并创建一个SqlGeography object (OpenGisGeographyType.Polygon),它是一个多边形的一个实例。

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

如图所示,即使点位于多边形之外,SqlGeography.STIntersection仍然返回一个交点。 (你可以在图片中看到这一点,因为我根据polygonSearch()函数返回的内容将标签设置为“在发货区域内”或“客户我们的区域”

图片中的正确示例具有预期结果一个位置多边形内测试

在画面左侧的示例中包含了意想不到的结果 - 这表明,一个点是多边形内,当它显然不是

enter image description here

注意!:

  • 我使用SqlGeography(myShape)在地图上放置形状,因此我知道 正在使用适当的顶点构建形状。
  • 我使用SqlGeography(myPoint)将引脚放在地图上,所以我知道 引脚正在正确的顶点测试。
    • 这只失败对大型POLYGONS

下面我给出的代码在内存中创建多边形peice的,以及转换鼠标点击事件,纬度,经度。 (我已经在注释中包含了多边形顶点,因此可以在不需要API 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有什么关系?

+0

它是否总是返回true或仅当它接近但仍然在外? –

+0

@ ta.speot。仅在关闭时但仍在外 – clamchoda

+0

'这只在缩放后失败。你是否在缩放地图后再添加一个标记,返回错误的结果?当图像放大时,并不是多边形内部的针标记首先在多边形之外呈现,对吗? – Tim

回答

0

我解决了这个问题,我使用LocationToViewPortpoint函数将我的多边形lat/long转换为屏幕上的Point对象,以及我正在测试交点的点,并使用X和Y值代替lat/long在我的STIntersects

相关问题