# How to create 3D parallel lines with Z coordinates as same as Original 3D polyline using Arcpy?

I want to calculate cut/fill cost for road alignments. For this reason i need to create a buffer-like polygon from given road centre-line but this polygon has to have Z-values that are taken from corresponding Z coordinates of polyline (check my recent question for more details). Also my project is to optimize road coordinates to decrease cut/fill cost with genetic algorithm, so manual buffer creation will not be feasible. After some search for finding solution to the problem i have found this question. The answers from @FelixIP and @jbalk to the question, inspired me the following methodology:

1.Create two 3D parallel polylines with same Z-values

2.Convert the parallel polylines to polygon

The mentioned script is:

``````import arcpy, math
infc=r'..\SCRARCH\clone.shp'

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)
rightP=arcpy.Point(ptX.X-sX, ptX.Y-sY)
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))
``````

However the script in the answer doesn't yield in 3D polyline and i couldn't figure out how to manipulate the script to get my goal. What changes must be made in the mentioned script to create two 3D parallel polylines? I have a 3D Analyst license and am using ArcMap/ArcScene/etc with advanced license, however any answer in any platform other than Arcpy, like QGIS could be helpful too.

UPDATE:

Just to clarify my question, i made a 3D model of a simple example in Autodesk AutoCAD and took a screenshot. In the screenshot image the blue line is road centreline. The white surface is the output of buffer tool from blue line which doesn't help me, also its borders could be generated from mentioned code above. The red polygon, is my desired polygon which i need to calculate cut/fill and yellow lines are subject of this question that i need to create the red polygon. • Forget about my script, it works for very basic near straight lines, small bufer distance and few vertices. As I understand you have road centre line and elevation model and you'd like 3d polygon that follows terrain but has flat cross section? Mar 23, 2020 at 19:32
• @FelixIP thank you sir for responding. I have just uploaded an image to my question to clarify it, then i have explained it. Please read last 4 lines. Thank you again. Mar 24, 2020 at 0:05
• Not clear at all. Cut and fill comares 2 surfaces. What are they? Is your road on a ground? Mar 24, 2020 at 2:30

When you create the left and right `Point()` objects using the offset coordinates, also include the original `ptX.Z`

``````leftP=arcpy.Point(ptX.X+sX, ptX.Y+sY, ptX.Z)
Then when you create the `Polyline()`, include a `spatial_reference` and set `has_z` to `True`, otherwise they'll end up 2d. Note that those are positional-only arguments despite the docs suggesting that you can provide keyword args (in 10.3, at least).
``````section=arcpy.Polyline(array, srs, True)