Friday, September 16, 2011

ArcGIS Desktop API: Finding a point intersect along a polyline

So here a simple way to find a point's intersect along a polyline. The code includes the ability to include buffer distance. So if the point doesn't actually intersect, but is within X meters it will also return intersection for the point. Very handy little piece of code. Enjoy.
 public static double GetPointCollectionIntersectIndex(  
   IPointCollection points, IPoint point, double? bufferDistanceInMeters)  
 {  
   object Missing = Type.Missing;  
   PointClass queryPoint = new PointClass();  
   Polyline testPolyline = new Polyline();  
   // first see if point is in collection  
   for (int i = 0; i < points.PointCount; i++)  
   {  
     // get the point in the collection  
     points.QueryPoint(i, queryPoint as IPoint);  
     // we've found our point along the polyline  
     if (queryPoint.Compare(point) == 0) return i;  
   }  
   // time to do some intersect checks  
   for (int i = 1; i < points.PointCount; i++)  
   {  
     // remove old points if reusing  
     if (testPolyline.PointCount > 0) testPolyline.RemovePoints(0, 2);  
     // create first point  
     points.QueryPoint(i - 1, queryPoint as IPoint);  
     testPolyline.AddPoint(queryPoint as IPoint, ref Missing, ref Missing);  
     // create second point  
     points.QueryPoint(i, queryPoint as IPoint);  
     testPolyline.AddPoint(queryPoint as IPoint, ref Missing, ref Missing);  
     // get the relation operator for the target geometry and topological operator for buffering  
     ITopologicalOperator bufferOperator = testPolyline as ITopologicalOperator;  
     // get the row cursor  
     IRelationalOperator relationOperator =   
       (bufferDistanceInMeters == null ?  
         (IGeometry)testPolyline :  
         bufferOperator.Buffer((double)bufferDistanceInMeters)) as IRelationalOperator;  
     // a disjoint indicates a non-intersection, so if it's false, we have our intersect point  
     if (relationOperator.Disjoint(point) == false) return ((double)i) - 0.5;  
   }  
   // return -1  
   return result;  
 }  

No comments: