HOW TO

Extend line features in a polygon feature using ArcPy in ArcGIS Pro

Last Published: November 7, 2023

Summary

In ArcGIS Pro, when there are line features in a polygon, it is possible to extend the line features to the polygon boundary for various spatial analysis and visualization purposes such as to construct a floodplain mapping project for a river basin. The image below shows an example of line features not connected to the polygon boundary.

Line features are not connected to the polygon boundary

This article provides the workflow to extend line features in a polygon feature using ArcPy in ArcGIS Pro.

Procedure

Note: 
This workflow requires the full script to run in the ArcGIS Pro Python window and an additional line feature class as the output layer.
  1. In ArcGIS Pro, open the map containing the line and polygon feature classes.
  2. Open the Python window. Refer to ArcGIS Pro: Python window for more information.
  3. Run the following script:
    1. Define the file paths for the input and output shapefiles. Replace '<filePath1>', '<filePath2>' and '<filePath3>' with the paths of the line, polygon and the output line feature classes.
def main():
    print ("Start process...")
    import arcpy
    fc_line = r'<filePath1>'
    fc_pol = r'<filePath2>'
    fc_out = r'<filePath3>'
  1. Retrieve the geometry of the polygon and get its perimeter.
    print ("Get polygon and boundary")
    polygon = arcpy.da.SearchCursor(fc_pol, ('SHAPE@')).next()[0]
    boundary = polygon.boundary()
  1. Loop through the polyline features while extending them using boundary geometry and append the processed features, with progress logged for every 10 iterations.
    print ("start loop...")
    lst_feats = []
    cnt = 0
    with arcpy.da.SearchCursor(fc_line, ('SHAPE@')) as curs:
        for row in curs:
            cnt += 1
            if cnt % 10 == 0:
                print (" - processing line", cnt)
            polyline = row[0]
            pnt1 = polyline.firstPoint
            pnt2 = polyline.lastPoint

            pntg1_snap = boundary.snapToLine(pnt1)
            pntg2_snap = boundary.snapToLine(pnt2)
            polyline_out = ExtendPolyline(polyline, pntg1_snap.firstPoint, pntg2_snap.firstPoint)

            lst_feats.append(polyline_out)
  1. Save the processed data.
    print ("store results...")
    arcpy.CopyFeatures_management(lst_feats, fc_out)
  1. Snap the first and last line to the nearest part of the given polyline.
def ExtendPolyline(polyline, pnt1, pnt2):
    sr = polyline.spatialReference
    lst_pnts = []
    for part in polyline:
        for pnt in part:
            lst_pnts.append(pnt)

    lst_pnts.insert(0, pnt1)
    lst_pnts.append(pnt2)
    return arcpy.Polyline(arcpy.Array(lst_pnts), sr)
  1. Check if the script is being run directly.
if __name__ == '__main__':
    main()

The code block below demonstrates the example of the full working script.

def main():
    print ("Start process...")
    import arcpy
    fc_line = r'C:\Users\Documents\ArcGIS\Projects\MyProject22\MyProject22.gdb\Line1'
    fc_pol = r'C:\Users\Documents\ArcGIS\Projects\MyProject22\MyProject22.gdb\TestPolygons'
    fc_out = r'C:\Users\Documents\ArcGIS\Projects\MyProject22\MyProject22.gdb\snapped_lines'

    print ("Get polygon and boundary")
    polygon = arcpy.da.SearchCursor(fc_pol, ('SHAPE@')).next()[0]
    boundary = polygon.boundary()

    print ("start loop...")
    lst_feats = []
    cnt = 0
    with arcpy.da.SearchCursor(fc_line, ('SHAPE@')) as curs:
        for row in curs:
            cnt += 1
            if cnt % 10 == 0:
                print (" - processing line"), cnt
            polyline = row[0]
            pnt1 = polyline.firstPoint
            pnt2 = polyline.lastPoint

            pntg1_snap = boundary.snapToLine(pnt1)
            pntg2_snap = boundary.snapToLine(pnt2)
            polyline_out = ExtendPolyline(polyline, pntg1_snap.firstPoint, pntg2_snap.firstPoint)

            lst_feats.append(polyline_out)

    print ("store results...")
    arcpy.CopyFeatures_management(lst_feats, fc_out)

def ExtendPolyline(polyline, pnt1, pnt2):
    sr = polyline.spatialReference
    lst_pnts = []
    for part in polyline:
        for pnt in part:
            lst_pnts.append(pnt)

    lst_pnts.insert(0, pnt1)
    lst_pnts.append(pnt2)
    return arcpy.Polyline(arcpy.Array(lst_pnts), sr)

if __name__ == '__main__':
    main()

The image below shows the line features are extended to the polygon boundary.

The line features are extended to the polygon boundary

Article ID: 000031420

Software:
  • ArcGIS Pro 3 1
  • ArcGIS Pro 3 0
  • ArcGIS Pro 3 2

Receive notifications and find solutions for new or common issues

Get summarized answers and video solutions from our new AI chatbot.

Download the Esri Support App

Related Information

Discover more on this topic

Get help from ArcGIS experts

Contact technical support

Download the Esri Support App

Go to download options