# Get part of polyline based on 2 points in Arc Engine

Currently I have a layer with polylines; in another layer, I allowed the user to create 2 points on the polyline.

I want to know if there is a function for the polyline feature that I can use to get the clipped portion of the polyline based on the 2 user-added points. Thanks.

• Do you want to cut the "line" that the user created with the two points from the polyline layer? Or do you just want to create a polyline that stretches from the first to the second point? In other words, what are you trying to do? – Michael Todd Jun 16 '11 at 19:58
• Sorry, i should of elaborate on it more, yes i want to create a new polyline that stretches from the first and second point using points/vertex from the polyline layer. – Kev84 Jun 16 '11 at 20:13

## 3 Answers

The testmethod only works with arcmap, but the other methods should work with arcengine.

``````private void TestGetsubCurve()
{
IPoint pnt1 = null;
IPoint pnt2 = null;
IPolyline polyLine = null;
var gc = ArcMap.Document.FocusMap as IGraphicsContainer;
gc.Reset();
IElement elem;
while((elem = gc.Next())!= null)
{
if (elem.Geometry is IPoint && pnt1 == null)
pnt1 = elem.Geometry as IPoint;
else if (elem.Geometry is IPoint && pnt2 == null)
pnt2 = elem.Geometry as IPoint;
else if (elem.Geometry is IPolyline)
polyLine = elem.Geometry as IPolyline;
}
if (pnt1 == null || pnt2 == null || polyLine == null)
{
Debug.Print("missing some geometry");
return;
}
var subCurve = GetSubCurve(polyLine, pnt1, pnt2);
elem = new LineElementClass();
((ILineElement)elem).Symbol = ((IDocumentDefaultSymbols)ArcMap.Document).LineSymbol;
elem.Geometry = subCurve;
gc.AddElement(elem, 0);
((IActiveView)ArcMap.Document.FocusMap).Refresh();
}

private IPolyline GetSubCurve(IPolyline inpolyLine, IPoint pnt1, IPoint pnt2)
{
double d1 = GetDistAlong(inpolyLine,pnt1);
double d2 = GetDistAlong(inpolyLine, pnt2);

var c = inpolyLine as ICurve;
ICurve outCurve;
c.GetSubcurve(d1, d2, false, out outCurve);
if (c == null || c.IsEmpty)
throw new Exception("unable to get subcurve");
var outPolyline = outCurve as IPolyline;
if (outPolyline == null)
{
// this didn't happen in testing, but one never knows ...
outPolyline = new PolylineClass() as IPolyline;
var sc = outPolyline as ISegmentCollection;
sc.AddSegment((ISegment)outCurve);
((IGeometry)sc).SpatialReference = outCurve.SpatialReference;
}
return outPolyline;
}

private double GetDistAlong(IPolyline polyLine, IPoint pnt)
{
var outPnt = new PointClass() as IPoint;
double distAlong = double.NaN;
double distFrom = double.NaN;
bool bRight = false;
polyLine.QueryPointAndDistance(esriSegmentExtension.esriNoExtension, pnt, false, outPnt,
ref distAlong, ref distFrom, ref bRight);
return distAlong;
}
``````

You should be able to use the clip function and automate it with python as seen in the very bottom of the page... http://webhelp.esri.com/arcgiSDEsktop/9.3/index.cfm?TopicName=clip_%28analysis%29

i have figured it out, the major problem is the the layer is a flow layer, and if we choose 2 points, the flow in between 2 points may consist of many polylines.

What I did was this:

From the start point get the polyline, go through each point and add it to my new line collection, if we hit the end of line, search all other lines that has the start point equalivent to the endpoint of current point an keep going. I did this recursively, so in the end it just added all the points of each polyline and i have myself a new polyline spanning from one node to another. Thanks

``````   private IPolyline GetNewPath(IPoint fromPoint, IPoint toPoint, IPolyline path)
{
IPolyline partialPath = new PolylineClass();
IPoint currentPoint;
bool startAddingPoints = false;

for (int x = 0; x < ((IPointCollection)path).PointCount; x++)
{
currentPoint = ((IPointCollection)path).get_Point(x);

if (currentPoint.X == fromPoint.X && currentPoint.Y == fromPoint.Y)
startAddingPoints = true;

if (startAddingPoints)
((IPointCollection)partialPath).AddPoint(currentPoint);

if (currentPoint.X == toPoint.X && currentPoint.Y == toPoint.Y)
break;
else if (((IPointCollection)path).PointCount == x + 1)
{
IIdentify identify1 = {featureLayer} as IIdentify;
IArray array = identify1.Identify(currentPoint);
IGeometry newPath;
IPoint newPathStartPoint;

for (int y = 0; y < array.Count; y++)
{
newPath = ((IFeature)(((IRowIdentifyObject)array.get_Element(y)).Row)).Shape;
newPathStartPoint = ((IPolyline)newPath).FromPoint;

if (newPathStartPoint.X == currentPoint.X && newPathStartPoint.Y == currentPoint.Y)
{
((IPointCollection)partialPath).AddPointCollection(GetMajorChannel(currentPoint, toPoint, newPath as IPolyline) as IPointCollection);
break;
}
}
}
}

return partialPath ;
}
``````