Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I'm new to Python (v 2.6.5) and am trying to write an ArcMap (10) script that reads the vertex coordinates of a polygon shapefile which includes a small hole (doughnut polygon). I've been working from the ESRI Help page on reading geometries. The script I've developed outputs coordinate information until it hits coordinate 1025 of 1088 at which point it fails with the error "Array: GetObject not point". I suspect this is the 'null point object' returned as the separator between my outer and inner rings (described in the Help), but I'm stumped on how to account for this in a way that my script doesn't fail (I thought the "if pnt:" line would handle that...). Here's my script - thanks for any guidance!

import arcpy
infc = arcpy.GetParameterAsText(0)
desc = arcpy.Describe(infc)
shapefieldname = desc.ShapeFieldName
rows = arcpy.SearchCursor(infc)
for row in rows:
    feat = row.getValue(shapefieldname)
    arcpy.AddMessage("Feature %i:" % row.getValue(desc.OIDFieldName))
    partnum = 0
    for part in feat:
        pointnum = 0
        arcpy.AddMessage("Part %i:" % partnum)
        for pnt in feat.getPart(partnum):
            if pnt:
                arcpy.AddMessage("Point number " + str(pointnum) + ": " + str(pnt.X)+ ", " + str(pnt.Y))
                pointnum += 1
            else:
                arcpy.AddMessage("Interior Ring:")
        partnum += 1
share|improve this question
    
Scott, I'm running into the exact same problem. I was wondering how you incorported Dan's code to solve the ESRI script to make it work? –  user1238592 Mar 21 '12 at 15:41

4 Answers 4

up vote 3 down vote accepted

If you want to use a function to be called, then you can look at this example.

def pntXY(pnt):
  '''Gets X,Y coordinates given a point object, returns a list'''
  XY= [pnt.X, pnt.Y]
  return XY

def shapeToPoints(a_shape,theType,arcpy):
  '''
  pnts = shapeToPoints(a_shape, shape type, geoprocessor)
  Purpose:  Converts a shape to points, the shape and its type
  are passed by the calling script
  Requires:  def pntXY(pnt)
  '''
  outList=[]
  part_num = 0
  part_count = a_shape.partCount
  if theType == "Multipoint":    #Multipoints
    while part_num < part_count:
      pnt = a_shape.getPart(part_num)
      XY = pntXY(pnt)
      if XY not in outList:
        outList.append(XY)
      part_num += 1
  else:                          #Poly* features
    while part_num < part_count: #cycle through the parts
      a_part = a_shape.getPart(part_num)
      pnt = a_part.next()
      while pnt:                 #cycle through the points
        XY = pntXY(pnt)
        if XY not in outList:
          outList.append(XY)
        pnt = a_part.next()      
        if not pnt:              #null point check (rings/donuts)
          pnt = a_part.next()
          if pnt:
            XY = pntXY(pnt)
            if XY not in outList:
              outList.append(XY)
      part_num += 1
  return outList
share|improve this answer
    
Thanks Dan, I was able to incorporate this into my script and it looks to have solved the problem. Many thanks! I'm still wondering why the original ESRI example won't work - but I'm happy to have a solution. –  Scott Jan 21 '12 at 19:55

The ESRI example do indeed not work at all. This method works fine:

for row in rows:
    feat = row.getValue(shapefieldname)
    print "Feature %i:   numpoints=%i" % (row.getValue(desc.OIDFieldName), feat.pointCount)
    print 'Number of parts: ', feat.partCount
    partnum = 0;
    while partnum < feat.partCount:
        print "Part %i:" % partnum
        part = feat.getPart(partnum)
        pnt = part.next()
        while pnt:
            print pnt.X, pnt.Y
            pnt = part.next()
            if pnt is None:
                pnt = part.next()
                if pnt:
                    print "Interior ring:"
        partnum += 1
share|improve this answer
    
i have the same problem and this solution solve it "thanks" –  AbdelMounaim TAOUSSI Jan 19 at 17:48

I ran into this a couple months ago when I had to remove interior rings from polygons. I can't confirm that this was the solution (the code is on my work computer), but I think you need to swap the if logic when checking for the null point object:

for pnt in feat.getPart(partnum):
   if pnt is None:
      arcpy.AddMessage("Interior Ring:")
   else:
      arcpy.AddMessage("Point number " + str(pointnum) + ": " + str(pnt.X)+ ", " + str(pnt.Y))
      pointnum += 1

If this doesn't work, let me know and I can check when I get into the office on Monday.

share|improve this answer
    
Thanks for the help Dmahr, but with this variation the script still throws the same error. –  Scott Jan 21 '12 at 17:40

Couldn't you just catch any errors and write them out to a text file using the logging module (which is pretty easy to use) and then just check to make sure that is the only error that is thrown so you will know it is the one you expect.

import loggging, sys, string, arcpy, os, traceback
logging.basicConfig(level=logging.DEBUG, filename=r"C:\log.txt", format='%(asctime)s %(levelname)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
try:
    whatever your trying
except:
    logging.Debug(traceback.format_exc())#This should get the error for you
share|improve this answer
    
For some reason, I couldn't get logging to work on my Python. But I did use error trapping in earlier attempts at troubleshooting to expose the error and it was just returning the same info about 'GetObject not point'. –  Scott Jan 21 '12 at 19:54

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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