ThinkGeo.com    |     Documentation    |     Premium Support

GetFeaturesNearestTo not finding nearest polygon

 Hi


I'm trying to use GetFeaturesNearestTo to find the nearest property (polygon) to a point. 


It is returning a polygon that appears to be further away than a closer one.


I'm wondering if I'm using the function correctly and how it is calculating the nearest polygon.


Here is my code:



Collection<Feature> selectedFeatures =
    shapeLayer.QueryTools.GetFeaturesNearestTo(defectShape, GeographyUnit.Meter, 1, ReturningColumnsType.AllColumns);

Attached is a screenshot of the map, the point, what is returned and what should be returned.



Cheers


Steve


 


 



Steve, 
  
 Probably you need to provide your sample data that we can test in our local machine so that I can figure out the problem, I have tested our HowDowI sample->Features->DetermineTheLengthOfALineFeature, it seems it’s working fine. 
  
 Thanks, 
 James

Do you have an ftp site I can upload the data to - it’s 25mb zipped. 
  
 Cheers 
  
 Steve

Steve, 
  
 Yes, we have. About how to upload it you can send email to support@thinkgeo.com to get detail information. Let me know if the data is ready to get. 
  
 Thanks, 
 James

OK, data is uploaded. 
  
 Create a point at the following location (defectShape) and use the GetNearestFeatureTo code above to query the property layer I sent. 
  
 You should see it returning a property withan  address of 2 Station Street rather than 160 Anzac Avenue which is closer. 
  
 Cheers 
  
 Steve

Oops, forgot the location: 
  
 X - 497997.373551679 
 Y - 6984410.50241488 
  
 Cheers 
  
 Steve

Steve, 
  
 I got your data and recreate your problem, the input point is far from the result. But couldn’t figure out the problem so far. I will keep researching on it, any progress I will let you know. 
  
 Thanks, 
 James

James 
  
 Glad to hear that you have replicated the problem. It is half the battle! 
  
 I wonder if it is anything to do with the polygon it returns being so large. I know it shouldn’t but if you look a the screenshot I posted the polygon being returned is huge and could have skewed the result? 
  
 Cheers 
  
 Steve

Steve, just let you know we still working on it. Hope we can fix it in version 5.5 release this month. 

 



Thanks for the update. Please let me know if you’d like me to test anything. 
  
 Cheers 
  
 Steve

Steve,


I found the problem is, internally we use layer.FeatureSource.GetFeaturesInsideBoudingBox(defectShape.GetBoundingBox()), it returns that shape which is further than  two other shapes. We are working on it and try to fix the bug.


The workaround is that you can try to use following function instead:


        private static Feature GetFeatureNearestTo(ShapeFileFeatureLayer layer, BaseShape defectShape)

        {

            layer.Open();

            Collection<feature></feature> feautres = layer.QueryTools.GetFeaturesNearestTo(defectShape, GeographyUnit.Meter, 2, ReturningColumnsType.NoColumns);

            layer.Close();

            double distance1 = defectShape.GetDistanceTo(feautres[0], GeographyUnit.Meter, DistanceUnit.Meter);

            double distance2 = defectShape.GetDistanceTo(feautres[1], GeographyUnit.Meter, DistanceUnit.Meter);

            Feature feature = feautres[0];

            if (distance1 > distance2)

            {

                feature = feautres[1];

            }

            return feature;

        }


Thanks,


James



Steve, 
  
   I have tracked down the issue related to finding the closest shape.  The explanation is a little long and included in the paragraphs below.  First I want to give you the answer which is to call the GetFeaturesNearestTo and instead of passing “1” for the third parameter pass in “20” or higher.  This will return you back a collection of features and you would then choose the first one in the collection.  This should be the one you expected to get. 
  
   Finding the closest feature quickly is not as straight forward as you might think.  The first thing we need to do is to get a number of reasonable candidates.  We would not want to actually check the distance from the point to every shape in the shape file.  To do this initial filter we use the bounding boxes to determine if a shape is close.  We take the selection point and we buffer it to create an area.  We next check to see what bounding boxes of nearby shapes intersect that rectangle.  We check the number of features returned against the third parameter in the GetFeaturesNearestTo which you had set as “1”.  If we don’t find less than that number of features features then we scale up the search bounding box and try again.  We do this as many times as it takes to satisfy the number of records to return parameter.  Once we get the number of features we do an in depth distance calculation to see which feature is really the closest based on the geometry and not the bounding box.  We sort the return in distance order.  
  
   In the case you illustrated the issue was that since you chose to return only one feature we picked the wrong one because that feature, while far away, had its bounding box overlap our search area.  If you had chosen a high number of the records to return we would have gotten the right feature in the mix and would then had returned it first.  It is interesting because in this example the closest record’s bounding box does not contain the search point.  We use the bounding boxes as first because our R-Tree index uses rectangles and it allows us to find overlapping features lightning fast.  The number for the max number of features to return needs to be higher if the density of shapes in an area is high.  Taking a quick look at your data from the screenshot it looks like 20 would be a good number.  Remember the higher the number the more time it will take however the more accurate the results will be.  The only way to make the result 100% accurate is to test against every shape in the file and that has a high amount of overhead. 
  
 David