Solved! Go to Solution.
I am having the same issue. I have a point that I have converted to an extremely small envelope, but I get get 3 results back from my query and should only be getting one. This seems like a bug.
Anyone from ESRI reading these?
It's only a bug if the three returned shapes do not overlap the requested envelope. Do they? Can you provide a FGDB data sample and the corners of the envelope with which you're querying?
ALL application code must handle the possibility that a point-in-poly query could return zero, one, or many features. With a simple envelope search, the probability of multiple return rows approaches unity.
Since there's no way to alter the design without including a full geometry processing library in the FGDBAPI DLL (and that doesn't seem likely), the best possible solution is going to be a simple helper function to test point-in-polygon (and even that will need to return a ternary response -- {"IN", "OUT", "ON"}).
- V
THanks, I will provide a data and code sample in the morning when I am back at my PC.
Attached is a small file geodatabase with one featureclass. When I query with the point shown on the attached map(expanded slightly to make an envelope), I get three results. The correct one, David James, but also Tandy and Hamilton, which is obviously wrong. There should be only one row returned, but I am getting three.
Thanks
Code:
static void Main(string[] args)
{
Geodatabase geodatabase = null;
Table table = null;
try
{
geodatabase = Geodatabase.Open(@"C:\Temp\test.gdb");
Esri.FileGDB.Point pt = new Esri.FileGDB.Point();
double x = 1204123.4375;
double y = 273148.87152777775;
pt.x = x;
pt.y = y;
Envelope envelope = new Envelope();
envelope.xMin = x - .00001;
envelope.yMin = y - .00001;
envelope.xMax = x + .00001;
envelope.yMax = y + .00001;
table = geodatabase.OpenTable("MetroCouncil");
RowCollection spQueryRows = table.Search("*", "", envelope, RowInstance.Recycle);
foreach (Row spQueryRow in spQueryRows)
{
Console.WriteLine(spQueryRow.GetString("COUN_NAME").ToString());
}
Console.ReadLine();
}
catch (Exception ex)
{
}
finally
{
table.Close();
geodatabase.Close();
}
}
Well, I couldn't read the FGDB, but the JPEG indicates an envelope-on-envelope search is being conducted (which is what I expected).

The results are not incorrect, they're just imprecise. The spatial search just nominates candidates which are close enough to have a relationship (beyond envelope_overlap). You need to do the point-in-polygon test on your own (which is what I wrote in March).
- V
Thanks Vince, it all made perfect sense as soon as I saw your attached image.
I went ahead and put together the helper function earlier and am attaching this process for anyone else who finds this, its working well now:
RowCollection spQueryRows = table.Search("*", "", envelope, RowInstance.Recycle);
MultiPartShapeBuffer rowGeomPoly = new MultiPartShapeBuffer();
foreach (Row spQueryRow in spQueryRows)
{
//Get the row polygon
rowGeomPoly = spQueryRow.GetGeometry();
//Convert ESRI Geometry to PointF array
System.Drawing.PointF[] polyPts = new PointF[rowGeomPoly.Points.Length];
System.Drawing.PointF point;
for(int j = 0;j<=rowGeomPoly.Points.Length -1;j++)
{
point = new PointF { X = (float)rowGeomPoly.Points.x, Y = (float)rowGeomPoly.Points.y };
polyPts = point;
}
//Intersect
bool isIntersected = PointIsInPolygon(polyPts, new System.Drawing.PointF { X = (float)pt.x, Y = (float)pt.y });
if (isIntersected)
{
Console.WriteLine(spQueryRow.GetString("COUN_NAME").ToString());
break;
}
} private static bool PointIsInPolygon(PointF[] polygon, PointF target_point)
{
// Make a GraphicsPath containing the polygon.
GraphicsPath path = new GraphicsPath();
path.AddPolygon(polygon);
// See if the point is inside the path.
return path.IsVisible(target_point);
}