5

From time to time I have to access geometry field and shuffle through points in it. Process is simple:

  1. Get shape
  2. Get it's part
  3. Iterate through part's points

This is how it looks like in a script

import arcpy
fc = r'd:\scratch\line.shp'
with arcpy.da.SearchCursor(fc,"Shape@") as cursor:
   for row in cursor:
      shp=row[0]
      part=shp.getPart(0)
      for p in part:
         print p.X

However, when I try to do similar thing using field calculator:

def plineM(shp):
 part=shp.getPart(0)
 for p in part:
  return p.X

plineM( !Shape! )

I got 999999 error.

To make it work I am forced to a) define the length of an array and b) use getObject() method to access the point:

def plineM(shp):
 part=shp.getPart(0)
 n=len(part)
 for i in xrange(n):
  p=part.getObject(i)
  return p.X

Question: why simple array iterator works in script and does not work in field calculator?

2 Answers 2

7

With cursors and the "SHAPE@" token, a geometry object is returned. The getPart() method returns an Array containing all the points for that particular part.

Interestingly, field calculator also returns a geometry object, but the getPart() method does not appear to return an array, although it is something similar. Maybe an unpacked array?

Luckily, arcpy can be accessed inside field calculator, so it's a simple call to arcpy.Array():

def plineM(shp):
  for part in arcpy.Array(shp.getPart(0)):
    for p in part:
      return None if p is None else p.X          

plineM(!Shape!)
3
  • It seems getPart() in FC does return array, because getObject() is very 'array' method. Script on the other hand converts array to something like list. +1 anyway, I never though I can use arcpy without import arcpy in calculator
    – FelixIP
    Aug 18, 2015 at 22:32
  • 1
    I am accepting it because you confirmed my observation, that calculator and script do return different objects. I hit the wall yesterday trying to figure this
    – FelixIP
    Aug 19, 2015 at 0:10
  • 1
    This will fail on a polygon interior ring ("AttributeError: 'NoneType' object has no attribute 'X'"). This seems to work: for p in part: if p: return p.X Feb 10, 2016 at 21:51
0

It looks like it works in a script because you are explicitly getting the Shape@ field.

If you run into a feature with a null shape, your first field calculator will try to unpack it and run into an error.

1
  • What do I access in field calculator with !Shape! ?
    – FelixIP
    Aug 18, 2015 at 21:48

Your Answer

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

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