I can't read shape points in py script, getPart() doesn't work

1400
8
05-24-2011 03:47 AM
EliaszHaas
New Contributor
Hi!

I've got layer of polygons and I'm trying to read with py script all shapes.
But for almost all shapes I can't read their geometries (getPart() returns nothing - I've checked partCount returns 0, but pointCount nonzero values)
Of course all objects are displayed well in ArcEditor

I use code similar to:

import arcpy

# Identify the geometry field
#
desc = arcpy.Describe("myLayer")
shapefieldname = desc.ShapeFieldName

# Create search cursor
#
rows = arcpy.SearchCursor(infc)

# Enter for loop for each feature/row
#
for row in rows:
    # Create the geometry object 'feat'
    #
    feat = row.getValue(shapefieldname)
    pnt = feat.getPart()

    # Print x,y coordinates of current point
    #
    print pnt.X, pnt.Y

What is going on?
Any idea?

Piotr
0 Kudos
8 Replies
DanPatterson_Retired
MVP Emeritus
The following function requires a shape from your search cursor, the type of shape (ie multipoint, polygon or polyline and the arcpy object.  You can glean the necessary lines for your code.

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
0 Kudos
EliaszHaas
New Contributor
Thanks
... but your code doesn't work the same way as mine. Me and you call getPart() function and it returs nothing (partCount returns 0 and pointCounts returns nonzero value). As I said my polygons are properly displayed in ArcScene, ArcEditor.

Piotr
0 Kudos
ChrisSnyder
Regular Contributor III
You need to provide an index to tell the .getpart() method what part you want to get. Get part is the way to deal with possible multipart shapes. If you are SURE your features are singlepart, then .getpart(0) will do the trick. Otherwise you need to loop through the parts as Dan's code is doing.
0 Kudos
EliaszHaas
New Contributor
Hi

getPart() and getPart(0) return the same result: nothing - and that's my problem.

Piotr
0 Kudos
ChrisSnyder
Regular Contributor III
How about using .centroid? Here is a v93 example.

fc = r"D:\csny490\temp\road_pnts.shp"
pntDict = {}
dsc = gp.describe(fc)
shapeFieldName = dsc.shapefieldname
oidFieldName = dsc.oidfieldname
searchRows = gp.searchcursor(fc)
searchRow = searchRows.next()
while searchRow:
    shapeFieldValue = searchRow.getvalue(shapeFieldName)
    oidFieldValue = searchRow.getvalue(oidFieldName)
    centroidValue = shapeFieldValue.centroid
    xValue = centroidValue.x
    yValue = centroidValue.y
    if (xValue,yValue) in pntDict:
        pntDict[(xValue,yValue)].append(oidFieldValue]
    else:
        pntDict[(xValue,yValue)] = [oidFieldValue]
    searchRow = searchRows.next()
0 Kudos
ChrisSnyder
Regular Contributor III
How about using .centroid? Here is a v93 example.

fc = r"D:\csny490\temp\road_pnts.shp"
pntDict = {}
dsc = gp.describe(fc)
shapeFieldName = dsc.shapefieldname
oidFieldName = dsc.oidfieldname
searchRows = gp.searchcursor(fc)
searchRow = searchRows.next()
while searchRow:
    shapeFieldValue = searchRow.getvalue(shapeFieldName)
    oidFieldValue = searchRow.getvalue(oidFieldName)
    centroidValue = shapeFieldValue.centroid
    xValue = centroidValue.x
    yValue = centroidValue.y
    if (xValue,yValue) in pntDict:
        pntDict[(xValue,yValue)].append(oidFieldValue]
    else:
        pntDict[(xValue,yValue)] = [oidFieldValue]
    searchRow = searchRows.next()
0 Kudos
DanPatterson_Retired
MVP Emeritus
run the "repair geometry" tool on the file to check and correct any geometry errors
0 Kudos
EliaszHaas
New Contributor
Thanks Dan!

I "repaired geometry" and it helped.
I did it for the first layer and I hope It'll work for other layers too.
That's my first task in ArcGis so I had no idea what to do 😉
Thanks

Piotr
0 Kudos