Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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.

share|improve this question
    
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
add comment

3 Answers 3

up vote 4 down vote accepted

enter image description here

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;
}
share|improve this answer
add comment

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

share|improve this answer
add comment

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 ;
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.