4

I'm using ArcMap 10.1 with Info License. Here is my issue. I have a section of track line with incorrect Z values applied. There are over 15,000 vertexes that I need to update all at once. I know I can do it manually but that would take forever. Basically I just need to add 2 ft. to the existing Z values.

How can I go about doing this?

  • Do you have 3d analyst? – Barbarossa Oct 30 '15 at 18:31
  • I think you should be able to do this using arcpy.da.UpdateCursor() - look into the @SHAPE* token examples. – PolyGeo Oct 30 '15 at 18:36
3

This can be a bit tricky with polylines as the z-values of each vertice are not immediately accessible through the shape field. You will need to access the polyline geometry object (Shape field) with SHAPE@ and drill down further to get to each point in the polyline geometry. Here is a python and arcpy code snippet for how to access the z-values of the vertices of a specific line in a polyline feature class.

id_field = 'TARGET_FID' #field identifies which features need to be shifted
id_value = 12 #value in id_field that identifies specific feature that needs to be shifted
shift_value = 2
with arcpy.da.UpdateCursor("Breaklines", ['SHAPE@', id_field]) as u_cur:
    for row in u_cur:
        if row[1] == id_value:
            geometry = row[0]
            pts = geom.getPart(0) #get polyline geometry
            pt_array = arcpy.Array() #create array to house new points
            for pt in pts:
                pt.Z += shift_value #shift z value
                pt_array.add(pt) #add point to array
            new_polyline_geometry = arcpy.Polyline(pt_array, None, True) #important to enable z-value by having the third parameter set to True
            row[0] = new_polyline_geometry #set row[0] which is SHAPE@ (geometry object)
            u_cur.updateRow(row)

In a nut shell:

  • loop over the vertices of the polyline geometry
  • update each z value of the point geometry
  • add the updated point to an array
  • once all points in the polyline have been adjusted:
    • create a new polyline geometry with the point array, making sure to set it to z-enabled
    • then update the old polyline geometry with the newly created geometry

Currently this will only work on the first part of the geometry, see pts = geom.getPart(0), however it can be easily edited to work on the line if it has multiple parts. By updating the code and integrating another loop and using the .partCount of the Polyline object.

2

Block:

def plineZ(shp):
 arr=arcpy.Array();pM=arcpy.Point()
 part=shp.getPart(0);n=len(part)
 for i in xrange(n):
  p=part.getObject(i)
  pM.X=p.X;pM.Y=p.Y;pM.Z=p.Z+2*0.33
  arr.add(pM)
 return arcpy.Polyline(arr)

Expression:

plineZ( !Shape! )

Run it on Shape field using backup copy of feature class. Works for single part polylines only

2

If you use arcpy.da.UpdateCursor, you can access and edit Z-values with 'SHAPE@Z'. Key though, is to use explode_to_points argument; this allows you to cycle through the vertices without having to deal with geometry and array objects.

Required word of caution: arcpy.da.UpdateCursor of course updates your data. Work on a copy of your original data.

fc = "path to fc"
z_increase = 2

with arcpy.da.UpdateCursor(fc, 'SHAPE@Z', explode_to_points=True) as cursor:
    for row in cursor:
        cursor.updateRow([row[0] + z_increase])

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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