This project is read-only.

Query polygon featureset by point

Dec 2, 2010 at 2:36 PM

I would like to query a polygon feaureset - based on shapefile - by a given point geometry.

My test code:

FeatureSet pFeatureSet = new FeatureSet();
pFeatureSet.Projection = KnownCoordinateSystems.Geographic.World.WGS1984;
pFeatureSet.Open(@"C:\Maps\poly.shp");

DotSpatial.Topology.Point pPoint = new DotSpatial.Topology.Point(19.1,47.1);
FeatureSet pPointFeatureSet = new FeatureSet(DotSpatial.Topology.FeatureType.Point);
pPointFeatureSet.Projection = KnownCoordinateSystems.Geographic.World.WGS1984;
pPointFeatureSet.AddFeature(pPoint);

Extent pAffectedExtent = null;
var result = pFeatureSet.Select(pPointFeatureSet.Extent, out pAffectedExtent);

foreach (IFeature feature in result)
{
    MessageBox.Show(feature.DataRow.Field<string>("NAME"));
}

It results 2 features: one is correct, one is incorrect. One is correct, because the given point in that polygon, other one is incorrect, because this polygon does not intersects my point. It is 'close' to the point - these 2 polygons are neighbours - but not within. Also, if I check pAffectedExtent, it is not the point itself, but some area around my point. My question is: how to query a polygon layer by a point? I do not need any tolerance, only one polygon, that contains my point.

Thanks in advance!

Dec 2, 2010 at 7:17 PM

there is an overload on the select method with a strict extent specified that gets used for selecting polygons.

Dec 2, 2010 at 11:03 PM

Thanks fof your answer.

I think there is a misunderstanding between us. IFeatureSet.Select does not have this overload method, only FeatureIndentifier tool has it. I need IFeatureSet.Select not this tool (I don't need layers etc.), and also note, that this strict extent you mentioned is nothing special, it is just a point 'buffered' by a smaller radius, than the normal extent:

Rectangle rtol = new Rectangle(e.X - 8, e.Y - 8, 16, 16); //normal
Rectangle rstr = new Rectangle(e.X -1, e.Y - 1, 2, 2); //strict
(MapFunctionIdentify.cs, line 65)

I need only a method, which selects a polygon from a featureset by a point. I workarounded my previous solution (highlited by bold):

Extent pAffectedExtent = null;
var result = pFeatureSet.Select(pPointFeatureSet.Extent, out pAffectedExtent);

foreach (IFeature feature in result)
{
  DotSpatial.Topology.Polygon pPolygon = (DotSpatial.Topology.Polygon)feature.BasicGeometry;
  if (pPolygon.Intersects(pPoint))
  {
    MessageBox.Show(feature.DataRow.Field<string>("NAME"));
  }
}

...but I still don't understand why should I do this if I only would like to select a polygon by a point. ;)

Dec 2, 2010 at 11:18 PM

Sorry about that, I was away from any of the source code at a conference answering from my droid and was getting featureset selection mixed up with layer selection.  I think I have found the answer.  Looking at the code posted below, it looks like when the shapes are in index mode, it tests the shape itself against the extent in question.  But when you are working with features, it seems to use the envelope of the feature instead of testing intersection with the feature itself.  I will post a fix for this later tonight and post it.

Ted

List<IFeature> result = new List<IFeature>();
			if (IndexMode)
			{
				ShapeRange aoi = new ShapeRange(region);
				Extent affected = new Extent();
				List<ShapeRange> shapes = ShapeIndices;
				if (shapes != null)
				{
					ProgressMeter = new ProgressMeter(ProgressHandler, "Selecting shapes", shapes.Count);
					for (int shp = 0; shp < shapes.Count; shp++)
					{
						ProgressMeter.Next();
						if (!shapes[shp].Intersects(aoi))
						{
							continue;
						}

						IFeature f = GetFeature(shp);
						affected.ExpandToInclude(shapes[shp].Extent);
						result.Add(f);
					}
					ProgressMeter.Reset();
				}

				affectedRegion = affected;
				return result;
			}

			affectedRegion = new Extent();

			bool useProgress = (Features.Count > 10000);
			ProgressMeter = new ProgressMeter(ProgressHandler, "Selecting Features", Features.Count);
			foreach (IFeature feature in Features)
			{
				if (useProgress) ProgressMeter.Next();
				if (!region.Intersects(feature.Envelope))
				{
					continue;
				}
				result.Add(feature);
				affectedRegion.ExpandToInclude(feature.Envelope.ToExtent());

			}
			if(useProgress)ProgressMeter.Reset();

			return result;

Dec 2, 2010 at 11:25 PM

I understand Ted, thanks a lot!

Dec 15, 2010 at 4:30 PM

Hi!

I still can not find the fix. Did you make it?

Thanks in advance!

Dec 15, 2010 at 5:18 PM

No I have been swamped with other stuff from work and soon will be on break.  I will try to remember to get to this tonight, but if that is not soon enough consider posting the fix yourself.  I want this to be a community effort where we have user-developers that can post the fix.  Kyle and others are already doing a great job of this, so don't be afraid to participate.

Ted

 

Dec 16, 2010 at 2:25 AM

This issue has been fixed as of change set f17ef8e3ce31 on 12/15/2010