HOW TO

Create parallel features similar to the Copy Parallel tool in ArcGIS Pro with Python

Last Published: October 16, 2020

Summary

Although ArcGIS Pro has the Create Parallel tool, the tool is not available through ArcPy. As an alternative, a Python script can be used to create a similar effect as seen in the image below. A script may be useful and efficient for workflows related to pipelines, roads and highways.

Image showing an output of the script used to create a similar effect tot the Create Parallel tool.

This article provides steps to use a Python script that draws parallel features.

Procedure

Note:
This script does not work on line intersections.
  1. Create a clone of the line feature. Refer to ArcGIS Pro: Copy and paste features using the clipboard or ArcGIS Pro: Copy Features (Data Management) for more information.
  2. Add a Width field to the clone line feature.
    1. Use Add Field in the Fields view of the clone line feature. Refer to ArcGIS Pro: Fields view for more information.
    2. Name the field Width and set any numeric data type (long, short) as the data type.
    3. Populate the Width field with a value to determine the width of the parallel line from the line feature.
  3. Open a Python console or the Python window in ArcGIS Pro.
  4. Import the necessary modules.
import os, arcpy, math
  1. Specify the workspace.
infc=r'<Feature/Shapefile_Path>'
workspace = os.path.dirname(infc)
edit = arcpy.da.Editor(workspace)
  1. Start editing on the feature.
edit.startEditing(False,True)
edit.startOperation()
  1. Define a new function to create the parallel line.
def CopyParallel(plyP,sLength):
    part=plyP.getPart(0)
    lArray=arcpy.Array()
    rArray=arcpy.Array()
    for ptX in part:
        dL=plyP.measureOnLine(ptX)
        ptX0=plyP.positionAlongLine (dL-0.01).firstPoint
        ptX1=plyP.positionAlongLine (dL+0.01).firstPoint
        dX=float(ptX1.X)-float(ptX0.X)
        dY=float(ptX1.Y)-float(ptX0.Y)
        lenV=math.hypot(dX,dY)
        sX=-dY*sLength/lenV
        sY=dX*sLength/lenV
        leftP=arcpy.Point(ptX.X+sX,ptX.Y+sY)
        lArray.add(leftP)
        rightP=arcpy.Point(ptX.X-sX, ptX.Y-sY)
        rArray.add(rightP)
    array = arcpy.Array([lArray, rArray])
    section=arcpy.Polyline(array)
    return section
  1. Start a new cursor to update the clone line feature to become the parallel line.
with arcpy.da.UpdateCursor(infc,("Shape@","Width")) as cursor:
    for shp,w in cursor:
        twoLines=CopyParallel(shp,w)
        cursor.updateRow((twoLines,w))
  1. Delete the cursor and stop editing to release the lock file on the feature.
del cursor
edit.stopOperation()
edit.stopEditing(True)

The following shows the full script:

import os, arcpy, math
infc=r'C:\Users\User\Desktop\Work\Sample\Test_Shapefile.shp'
workspace = os.path.dirname(infc)
edit = arcpy.da.Editor(workspace)

edit.startEditing(False,True)
edit.startOperation()

def CopyParallel(plyP,sLength):
    part=plyP.getPart(0)
    lArray=arcpy.Array()
    rArray=arcpy.Array()
    for ptX in part:
        dL=plyP.measureOnLine(ptX)
        ptX0=plyP.positionAlongLine (dL-0.01).firstPoint
        ptX1=plyP.positionAlongLine (dL+0.01).firstPoint
        dX=float(ptX1.X)-float(ptX0.X)
        dY=float(ptX1.Y)-float(ptX0.Y)
        lenV=math.hypot(dX,dY)
        sX=-dY*sLength/lenV
        sY=dX*sLength/lenV
        leftP=arcpy.Point(ptX.X+sX,ptX.Y+sY)
        lArray.add(leftP)
        rightP=arcpy.Point(ptX.X-sX, ptX.Y-sY)
        rArray.add(rightP)
    array = arcpy.Array([lArray, rArray])
    section=arcpy.Polyline(array)
    return section

with arcpy.da.UpdateCursor(infc,("Shape@","Width")) as cursor:
    for shp,w in cursor:
        twoLines=CopyParallel(shp,w)
        cursor.updateRow((twoLines,w))

del cursor
edit.stopOperation()
edit.stopEditing(True)

Article ID:000024330

Software:
  • ArcGIS Pro 2 x

Get help from ArcGIS experts

Contact technical support

Download the Esri Support App

Go to download options

Related Information

Discover more on this topic