SqlGeography.STIntersection() returns even when I know there is no intersection

一世执手 提交于 2020-01-02 14:04:15

问题


A little about the application;

The application allows the user to draw and save polygons onto bing maps WPF api.

The piece of code we are interested in is finding weather a point is whithin the polygon or not. The following function simply loops through the LocationCollection of the polygon on the bing map, and creates a SqlGeography object (OpenGisGeographyType.Polygon) which is an instance of a polygon.

We then convert the mouse click into SqlGeography object (OpenGisGeographyType.Point) by latitude and longitude and use the SqlGeography.STIntersection to find if our point lies within the polygon.

As seen in the picture, even when the point is outside the polygon, SqlGeography.STIntersection still returns a point of intersection. (You can tell this in the picture as I set a label to "Within Delivery Area" or "Customer our of Area" depending on what polygonSearch() function returned.

The right example in the picture has the expected results when a location is tested within the polygon.

The left example in the picture contains the unexpected results - Which indicates that a point is within a polygon , when it clearly is not!

NOTES:

  • I Use SqlGeography (myShape) to put the shapes on the map, so I know the shape is being constructed with proper verticies.
  • I use SqlGeography (myPoint) to put the pin on the map, so I know the pin is being tested at the correct verticies.
    • THIS ONLY FAILS ON LARGE POLYGONS

Below I give the peice of code which creates the polygon in memory, as well as converts the mouse click event to lat, longitude. ( I have included the polygon verticies in comments so that this can be looked at without the need of the bing api, just replace the for loop with the comments above it ) Although, you will need to reference Microsoft.SqlServer.Types.dll to create the SqlGeography objects. Its free with SQL Express 2008 , and can be found in 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;



}

Any help at all is much appreciated, I am starting to drive my boss nuts with this problem >.<

Could this have anything to do with the SRID?


回答1:


I fixed this by converting all my polygon lat / long to a Point object on the screen using LocationToViewPortpoint function, as well as the point I'm testing for intersection, and use the X and Y values instead of lat / long in my STIntersects.



来源:https://stackoverflow.com/questions/17458117/sqlgeography-stintersection-returns-even-when-i-know-there-is-no-intersection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!