About polygon contains points

Topics: General Topics
Feb 18, 2009 at 7:04 PM
 I want to know if a point  is within a polygon.
So I code it like this :

#################code#################code#################code###############
             SharpMap.Geometries.BoundingBox bbox = new SharpMap.Geometries.Point(lon, lat).GetBoundingBox();
             List<Geometry> list = layCountries.DataSource.GetGeometriesInView(bbox);

            Point point = new Point(lon, lat);
            for (int k = 0; k < list.Count; k++)
            {
                if (list[k].Contains(point))
                {
                    return "find it";
                }
            }
#################code#################code#################code###############
But I can not find this point in the geometry list.
When I tried to trace the source code of sharpmap,I found that any contains function are all go to the contains function of point.But point can not contain any geometry,so always return false.

So who can tell me what's the way to know if a point  is within a polygon?

Coordinator
Feb 19, 2009 at 8:33 AM
Edited Feb 19, 2009 at 8:34 AM
Hi athel, you would probably want to use NTS (NetTopologySuite) for this type of thing. You can find a converter between NTS and SharpMap geometry types in the sharpmap extensions project along with the NTS, GeoAPI and ProjNet dlls. hth jd
Feb 19, 2009 at 8:31 PM
Edited Feb 19, 2009 at 8:32 PM
now I'm thinking the method called "ExecuteIntersectionQuery",
how could I get the boundingbox parameter for this function?
I do it like this: 
SharpMap.Geometries.BoundingBox bbox = new SharpMap.Geometries.Point(lon, lat).GetBoundingBox();
 the point is from client.
but no result.

I trace the source code , but I don't know what's the view means for the GetObjectIDsInView function.
it said get objects in view,but what's the view?where is it?why use the input parameter(bbox) as a paramter?

Thanks
athel
Feb 20, 2009 at 2:53 AM
Reference the NTS library in your code and pass it a coordinate and it will test the objects that lies under it to see if it's geometry is within those coordinates.  Here's my code to do it that you will need to modify to fit your purposes:

        /// <summary>
        /// Returns the HASC code for a given lat/lon
        /// </summary>
        /// <param name="x">lon</param>
        /// <param name="y">lat</param>
        /// <returns></returns>
        private string GetUnderlyingHASC(double x, double y)
        {
            if (x != 0 || y != 0)
            {
                ptX = x;
                ptY = y;
            }
            string sHASC = "";
            SharpMap.Data.Providers.ShapeFile oShape = new SharpMap.Data.Providers.ShapeFile(layerColl[_iMap].folderpath + layerColl[_iMap].base_filename);
            oShape.Open();
            uint i = 0;
            uint iFeature = (uint)oShape.GetFeatureCount();

            SharpMap.Geometries.Point oPoint = new SharpMap.Geometries.Point(ptX, ptY);
            GisSharpBlog.NetTopologySuite.Geometries.Geometry oPt = SharpMap.Converters.NTS.GeometryConverter.ToNTSGeometry(oPoint, new GisSharpBlog.NetTopologySuite.Geometries.GeometryFactory());

            // find a record
            for (i = 0; i < iFeature; i++)
            {
                GisSharpBlog.NetTopologySuite.Geometries.Geometry oPoly = SharpMap.Converters.NTS.GeometryConverter.ToNTSGeometry(oShape.GetFeature(i).Geometry, new GisSharpBlog.NetTopologySuite.Geometries.GeometryFactory());
                if (oPt.Within(oPoly))
                {
                    sHASC = oShape.GetFeature(i)["HASC"].ToString();
                    break;
                }
            }
            return sHASC;
        }


Hope this helps get you started,

Dirk
Coordinator
Feb 20, 2009 at 7:39 AM
Hi athel, the 'view' in question is an abstract concept of a viewport. Think of it as a large cardboard sheet with a rectangular hole cut out placed over a paper map. As you move the cardboard sheet around you can only see the map through the hole. This is like the viewport, it limits the result set to only features within a rectangular area - the bbox represents the coordinates of the hole.
WRT ExecuteIntersectionQuery for the shapefile provider: note it only tests the bounding boxes of features with the bounding box of the test geometry -  even if you use the overload that takes geometry. To do a true intersection test with the shapefile provider you need to either use the shapefileprovider.FilterMethod property to do a full NTS based test or do a further test on each geometry returned
hth jd
Feb 20, 2009 at 2:50 PM
Thanks for all of you.

Now I can judge the point if it is within a polygon.I use  dirkkaiser's method.
But I must loop all the attribute,so I afraid that will bring some trouble about efficiency.
Because we must load all the attributes into memory.

I use the NTS to intersect the point and  geometry(TrueGeomsIntersect function),so I can get the geometry.
Now I want to konw how could I get the attributes from on geometry?
for example,I add a attribute named "TestName". The final goal is when I click the map,show it.
Coordinator
Feb 20, 2009 at 3:25 PM
If you use the ExecuteIntersectionQuery method first you will not have to test every geometry - the rough bounding box test will quickly limit the number of candidate records.
so the process would be :
Get a BoundingBox with the coordinates set appropriately to the bounding box of your test geometry e.g testGeometry.GetBoundingBox();
create a new FeatureDataSet
Call ExecuteIntersectionQuery on the shapefile passing in the bounding box and FeatureDataSet
Get the first FeatureDataTable out of the FeatureDataSet
this table now contains all the attributes and geometries for all the features within the bounding box;
If you want to get only the features which definately intersect  you can loop backwards through the FeatureDataTable applying the NTS test and removing rows which do not pass.
After that you will have all the matching attributes and geometry data in the FeatureDataTable.
You can use this with a GeometryFeatureProvider to supply both a vector layer and label layer on your map.. hth jd
Feb 23, 2009 at 4:00 PM
Thanks for all of you so much.I got it.