[GIS] Create list of [X, Y] coordinates within field calculator

arcgis-10.1arcgis-desktoparcpyfield-calculator

Lately i've been working on a script that must calculate a value in ArcGIS field calculator based on all vertex coordinates of a polyline. But i am struggling to create a list of a polylines coordinates whitin the field calculator. The list is not meant to fill the field values, but it make other calculations possible.

This is how the list must be like:

coordinates = [[534359.1787999999, 6944339.3809], [534298.1876999997, 6944310.3992], [534282.0721000005, 6944304.4425]]

I have found some material about it on ArcGIS Resource Center, it works when i run their script through the command line and append to a list, but it doesn't work at all in field calculator. I've tried to write a code for the field calculator but it didn't work either, it look like this:

def listCoordinates(shape):
    coordinatesList = []
    n = 0 
    for pnt in shape.getPart(n):
        xn = pnt.X
        yn = pnt.Y
        coordinatesList.append([xn , yn])
        n += 1
    return coordinatesList

and the expression (this function will be inside another function that return a unique value):

listCoordinates(!shape!) 

Is this possible? Am i missing something? Any tips will be welcome! 🙂


It turns out that arcpy.getPart() do not return an array in field calculator. So you can use arcpy.Array() to get to the array. I was able to get what i wanted with:

def getCoords(shp):
    coords = []
    n = 0
    for part in arcpy.Array(shp.getPart(n)):
        for p in part:
            coords.append([p.X , p.Y])
        n += 1
    return coords

Best Answer

I am going to provide an alternative using the python interactive console in ArcMap.

I find it is easier to deal with python code like this using the interactive console. I am sure if you are very stuck with using the Field Calculator, this can be adapted to it.

rows = arcpy.da.UpdateCursor(yourLayer, ["SHAPE@", "fieldToStoreInfo"]) 
for row in rows:
     coords = []
     for i in range(row[0].partCount):
         parts = row[0].getPart(i)
         for part in parts:
             coords.append((part.X, part.Y))
     row[1] = str(coords)
     rows.updateRow(row)

SHAPE@ returns a geometry object which lets you check its part count (vertices). Then you can iterate through all the parts to get each one's X and Y values. Append it to your list and when you return you convert the list to a string. The value that gets stored is like:

[(2924327.0050581694, 10204574.257406339), (2924318.8784340024, 10204555.405738011), (2924317.0618365854, 10204533.60164775), (2924322.5132692605, 10204520.88152884), (2924331.5985529274, 10204511.796245173), (2924366.122762084, 10204511.796245173)]

Also, make sure your field has enough space for a long list of coordinate points. I set mine at a crazy high number just because my test file was a set of utility lines.

Related Question