How to identify feature vertices that are part of a donut hole in ArcGIS 10?

432
3
Jump to solution
06-12-2012 02:42 AM
MartinScheiber
Occasional Contributor
Hello everybody,

I´m exporting the coordinates of polygon vertices to a CSV-File using the "Feature Vertices to Points" and then the "Export feature attributes to ASCII"-tools.

Some of these polygons have holes (donuts). Can I do the analysis in a way, that in the resulting CSV-File it´s possible to identify if a point has been part of the outer boder or the inner border (donut) of the polygon?

Thanks, Martin
0 Kudos
1 Solution

Accepted Solutions
MarcinGasior
Occasional Contributor III
You can try this Python script which reads vertices coordinates, recognises inner ring and writes '1' for inner ring coordinates:
def main():     try:         import arcpy, sys, traceback         polygon = r"C:\tmp\Test.gdb\PolygonWithInnerRings"         txtFile = open(r"C:\tmp\PolygonToTXT.txt","w")         headerLine = (", ").join(["VertObjID", "X", "Y", "InRing"])         txtFile.write(headerLine + "\n")          rows = arcpy.SearchCursor(polygon)         for row in rows:             feature = row.SHAPE #get the geometry into variable             featureID = row.OBJECTID #adjust this if not in geodatabase              partNum = 0             #feature can have multiple parts - first goes iteration through parts             for featurePart in feature:                 part = feature.getPart(partNum) #the output is Array of points                  isInnerRing = "0"                 linesLst = []                  #iterate through points                  for pnt in part:                     if pnt:                         vertexLine = (", ").join([str(featureID), str(pnt.X), str(pnt.Y), isInnerRing])                         linesLst.append(vertexLine)                     else:                         isInnerRing = "1"                         linesLst.append("InRing")                                          #remove duplicated point and write to file                 linesLst.pop(linesLst.index("InRing")-1)                 for line in linesLst:                     if line != "InRing":                         txtFile.write(line + "\n")                  partNum += 1          del rows, row         txtFile.close()      except:         print arcpy.GetMessages()         # Get the traceback object         tb = sys.exc_info()[2]         tbinfo = traceback.format_tb(tb)[0]          # Concatenate information together concerning the error into a         #   message string         pymsg = tbinfo + "\n" + str(sys.exc_type)+ ": " + str(sys.exc_value)          # Return python error messages for use with a script tool         arcpy.AddError(pymsg)          # Print Python error messages for use in Python/PythonWin         print pymsg  if __name__ == '__main__':     main()

View solution in original post

0 Kudos
3 Replies
MarcinGasior
Occasional Contributor III
You can try this Python script which reads vertices coordinates, recognises inner ring and writes '1' for inner ring coordinates:
def main():     try:         import arcpy, sys, traceback         polygon = r"C:\tmp\Test.gdb\PolygonWithInnerRings"         txtFile = open(r"C:\tmp\PolygonToTXT.txt","w")         headerLine = (", ").join(["VertObjID", "X", "Y", "InRing"])         txtFile.write(headerLine + "\n")          rows = arcpy.SearchCursor(polygon)         for row in rows:             feature = row.SHAPE #get the geometry into variable             featureID = row.OBJECTID #adjust this if not in geodatabase              partNum = 0             #feature can have multiple parts - first goes iteration through parts             for featurePart in feature:                 part = feature.getPart(partNum) #the output is Array of points                  isInnerRing = "0"                 linesLst = []                  #iterate through points                  for pnt in part:                     if pnt:                         vertexLine = (", ").join([str(featureID), str(pnt.X), str(pnt.Y), isInnerRing])                         linesLst.append(vertexLine)                     else:                         isInnerRing = "1"                         linesLst.append("InRing")                                          #remove duplicated point and write to file                 linesLst.pop(linesLst.index("InRing")-1)                 for line in linesLst:                     if line != "InRing":                         txtFile.write(line + "\n")                  partNum += 1          del rows, row         txtFile.close()      except:         print arcpy.GetMessages()         # Get the traceback object         tb = sys.exc_info()[2]         tbinfo = traceback.format_tb(tb)[0]          # Concatenate information together concerning the error into a         #   message string         pymsg = tbinfo + "\n" + str(sys.exc_type)+ ": " + str(sys.exc_value)          # Return python error messages for use with a script tool         arcpy.AddError(pymsg)          # Print Python error messages for use in Python/PythonWin         print pymsg  if __name__ == '__main__':     main()
0 Kudos
MartinScheiber
Occasional Contributor
Great. Thanks a lot for that !!

Is this only working for one donut or for several ones as well? What do I have to do, to get written a 2 or 3 for the second or third donut.

Regards,
Martin
0 Kudos
LazarKovacevic
New Contributor
pppppppppppppppppppppppppppppppppp
0 Kudos