Be The First To Get Support Updates
Want to know about the latest technical content and software updates?
How To: Create parallel features similar to the Copy Parallel tool in ArcGIS Pro with Python
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.

This article provides steps to use a Python script that draws parallel features.
Procedure
Note: This script does not work on line intersections.
- 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.
- Add a Width field to the clone line feature.
- Use Add Field in the Fields view of the clone line feature. Refer to ArcGIS Pro: Fields view for more information.
- Name the field Width and set any numeric data type (long, short) as the data type.
- Populate the Width field with a value to determine the width of the parallel line from the line feature.
- Open a Python console or the Python window in ArcGIS Pro.
- Import the necessary modules.
import os, arcpy, math
- Specify the workspace.
infc=r'<Feature/Shapefile_Path>' workspace = os.path.dirname(infc) edit = arcpy.da.Editor(workspace)
- Start editing on the feature.
edit.startEditing(False,True) edit.startOperation()
- 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
- 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))
- 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)
Related Information
Last Published: 10/15/2020
Article ID: 000024330
Software: ArcGIS Pro 2.6.2, 2.6.1, 2.6, 2.5.2, 2.5.1, 2.5, 2.4.3, 2.4.2, 2.4.1, 2.4, 2.3.3, 2.3.2, 2.3.1, 2.3, 2.2.4, 2.2.3, 2.2.2, 2.2.1, 2.2