1

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)
        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))

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.

enter image description here

3
  • 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?
    – FelixIP
    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.
    – Sina_Alef
    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?
    – FelixIP
    Mar 24, 2020 at 2:30

1 Answer 1

3

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)
lArray.add(leftP)
rightP=arcpy.Point(ptX.X-sX, ptX.Y-sY, ptX.Z)
rArray.add(rightP)

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)

And of course the feature class needs to be Z-enabled to start with since you're using an update cursor

1
  • Thank you! It works properly
    – Sina_Alef
    Mar 24, 2020 at 8:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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