2

I'm trying to snap a line's vertices to several points in height. The XY have already been snaped, but the snap tool doesn't seem to get the Z value. There is one vertex for each point. Is there a way to update the vertices of the line with the Z value of the points?

Z of points and polyline.

I've had a similar problem before, but that time it was between points which shared the same ID. I'm not sure the vertices are able to store an ID the same way. I have acces to Arcgis Pro 2.2 and ArcMap 10.6.

Update: I tried to edit BERAs code to edit an existing fc instead of creating a new one.

with arcpy.da.UpdateCursor(existingFC, ['SHAPE@']) as cursor:
for row in cursor:
    linelist = []
    for part in row[0]: 
        partlist = []
        for pnt in part:
            if (pnt.X, pnt.Y) in pointzdict:
                print("in list")
                row[0] = arcpy.Point(pnt.X,pnt.Y,pointzdict[(pnt.X,pnt.Y)])
            else:
                row[0] = pnt
    #row[0] = arcpy.Polyline(arcpy.Array(linelist), arcpy.Describe(polylinefc2).spatialReference, True)
    cursor.updateRow(row)

It gives me this error:

Traceback (most recent call last):
  File "<string>", line 13, in <module>
SystemError: <built-in method updateRow of da.UpdateCursor object at 0x00000195B48ECDF0> returned NULL without setting an error
1
  • @BERA Correct. One line vertice for each point that shares the same XY, but not Z.
    – birks
    Jan 28, 2019 at 8:33

1 Answer 1

2

You can use arcpy. Create a dictionary with Point XY as key and Z as value using the da.SearchCursor. Then use da.UpdateCursor to update Z values of line vertices found in the dictionary:

import arcpy

arcpy.env.workspace = r'C:\Default.gdb' #Change
polylinefc = 'polylineZ' #Change to input line name, have to be in workspace
pointfc = 'pointZ' #Change to input Point name, have to be in workspace

pointzdict = {k:v for k,v in arcpy.da.SearchCursor(pointfc,['SHAPE@XY','SHAPE@Z'])} #Create dictionary of points with XY as key and Z as values

with arcpy.da.UpdateCursor(polylinefc,'SHAPE@') as cursor: #Update Z of polyline vertices where a match is found in point dictionary
    for row in cursor:
        linelist = []
        for part in row[0]:
            partlist=[]
            for pnt in part:
                if (pnt.X,pnt.Y) in pointzdict:
                    partlist.append(arcpy.Point(pnt.X,pnt.Y,pointzdict[(pnt.X,pnt.Y)]))
                else:
                    partlist.append(pnt)
            linelist.append(partlist)
        row[0] = arcpy.Polyline(arcpy.Array(linelist), arcpy.Describe(polylinefc).spatialReference, True)
        cursor.updateRow(row)

enter image description here

2
  • 1
    Thank you very much! Is it possible to do this without creating a new featureclass? I tried to edit the code to do it, but it gives me this weird error: "SystemError: <built-in method updateRow of da.UpdateCursor object at 0x00000195B48ECDF0> returned NULL without setting an error". I'll update the question.
    – birks
    Jan 28, 2019 at 10:55
  • Yes I have changed the code to update the existing line fc
    – BERA
    Jan 28, 2019 at 11:01

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.