Sunday 2 July 2017

arcpy - How to update the Z value using an UpdateCursor?


I have created the following script to mimic the ArcGIS 3D Analyst tool, FeatureTo3DByAttribute, which creates a 3D copy of a 2D feature class and sets the Z to a specified attribute.


import arcpy, os
from arcpy import env

# Parameters
in_features = arcpy.GetParameterAsText(0) #Feature Layer
out_features = arcpy.GetParameterAsText(1) #Feature Class

height_field = arcpy.GetParameterAsText(2) #Field

# disable overwrite protection
arcpy.env.overwriteOutput = True

# enable environment outputZFlag
arcpy.env.outputZFlag = "Enabled"

# copy input to output
arcpy.CopyFeatures_management(in_features, out_features)


# Use cursor to update geometry with z value based on height_field
with arcpy.da.UpdateCursor(out_features, ("SHAPE@Z", height_field)) as cursor:
for row in cursor:
row[0] = row[1]
cursor.updateRow(row)

Unfortunately, the z value is 0 for all of the output features. I can't find any documentation as to why this is. An alternative would be read every point and change the z value. Does anyone know why it is failing to update the z?


EDIT: Additional discussion


https://geonet.esri.com/thread/93322



https://geonet.esri.com/thread/82123



Answer



I encountered the same problem and I solved it by simply setting the "has_z" property to TRUE while creating the polygon geometry: arcpy.Polygon(my_array, my_spat_ref, TRUE). In the code below I update the z value of the vertices of my polygon fc taking the z values of a point fc.


import arcpy
arcpy.env.workspace = "my_path"
point_fc="my_points_fc.shp"
polygon_fc = "my_pol_fc.shp"
my_field = "SHAPE@"
my_field_pnt = "SHAPE@XYZ"



with arcpy.da.UpdateCursor(polygon_fc, my_field) as myUpdtCur:
for row in myUpdtCur:
geom = row[0]
arr_pol = arcpy.Array()
for part in geom:
arr_part = arcpy.Array()
pnt_count = 0
for pnt in part:
with arcpy.da.SearchCursor(point_fc, my_field_pnt) as mySrcCur:

for srcPnt in mySrcCur:
if int(pnt.X) == int(srcPnt[0][0]) and int(pnt.Y) == int(srcPnt[0][1]):

updZpnt=srcPnt[0][2]
del mySrcCur
pnt_count += 1
print pnt_count
myXYZPoint = arcpy.Point(pnt.X, pnt.Y, updZpnt)
arr_part.add(myXYZPoint)
arr_pol.add(arr_part)

## here is where I create my polygon and set the "has_z" property to true, otherwise it dosn't write the z value
polygon = arcpy.Polygon(arr_pol,None, True)
row[0] = polygon
myUpdtCur.updateRow(row)
del myUpdtCur

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...