Select to view content in your preferred language

Point in Polygon and Calculate Field crashes on conditional Statement

442
1
04-20-2011 02:47 PM
MikeMacRae
Frequent Contributor
I created a script to calculate some fields in a number polygon feature classes. It also counts the points within each polygon and places the count into a field (ASSOC_PTS) for each polygon record.

In only one of the polygon feature classes, there is an extra field (SUBREG) that is not in any of the others. I borrowed a conditional statement (the first 'try' statement) to check for the extra field and to calculate or ignore it as needed. I borrowed the statement from another script I made for some point feature classes that have the same senario with the extra field. It works in the point script, but doesn't in the polygon script.

The error message is:

'geoprocessing list object' object is not iterable

I changed the geoprocessing object from

gp = arcgisscripting.create()

to

gp = arcgisscripting.create(9.3)

This seems to allow the condition statement to pass successfully, but then the script crashes on the loop portion at the bottom which iterates through the rows of the polygon feature class and counts all the points from a point feature class (the second 'try' statement) and then places the count into a field called ASSOC_PTS.

Error is:

Object: Error in executing tool

Before I added the conditional statement, the point in polygon script works perfectly.

I have feeling part of the code is recognized in 9.3 and the rest is recognized in an older version, but I'm not sure. Does anyone have suggestions why it crashes?

Thanks,
Mike

# Import native arcgisscripting module
import arcgisscripting, sys
# Create the geoprocessor object
gp = arcgisscripting.create()

# Load required toolboxes...
gp.AddToolbox("C:/Program Files/ArcGIS/ArcToolbox/Toolboxes/Data Management Tools.tbx")
gp.AddToolbox("C:/Program Files/ArcGIS/ArcToolbox/Toolboxes/Analysis Tools.tbx")

# Table and field name inputs
POINT = sys.argv[1]
POLYGON = sys.argv[2]
SITE = sys.argv[3]
DATESURVEY = sys.argv[4]

gp.AddMessage("Enter Site Name into SITE field...")
# Process: Calculate Field - SITE...
gp.CalculateField_management(POLYGON, "SITE", SITE, "VB", "")

gp.AddMessage("Updating DATE_SURVEY field with survey date...")
# Process: Calculate Field - DATE_SURVEY...
gp.CalculateField_management(POLYGON, "DATE_SURVEY", DATESURVEY, "VB", "")

gp.AddMessage("Updating SOURCE field with ~Company~...")
# Process: Calculate Field - SOURCE...
gp.CalculateField_management(POLYGON, "SOURCE", "\"Company\"", "VB", "")


#Loop through fields to determine if SUBREG field exists. If it does, then calculate with the string "Boreal Mixedwood".
#If it doesn't exist, then finish the script

gp.AddMessage("Checking for SUBREG field")

try:

    thefieldlist = gp.ListFields(POLYGON)
   
    for field in thefieldlist:
            if "SUBREG" in field.name:
                gp.CalculateField_management(POLYGON, "SUBREG", "\"Boreal Mixedwood\"", "VB", "")
                gp.AddMessage("SUBREG has been found and calculated")
       
            else:
                pass


except Exception, errMsg:

#  If we have messages of severity error (2), we assume a GP tool raised it,
#  so we'll output that.  Otherwise, we assume we raised the error and the
#  information is in errMsg.

    if gp.GetMessages(2):   
        gp.AddError(gp.GetMessages(2))
    else:
        gp.AddError(str(errMsg))

del thefieldlist



# Converts unselectable feature class into a selectable feature layer
gp.MakeFeatureLayer(POINT,"point")
gp.MakeFeatureLayer(POLYGON,"polygon")

rows = gp.SearchCursor("polygon")
row = rows.Next()

gp.AddMessage("Calculating Points in Polgons...")


try:

    while row:
       
        #gp.AddMessage(row.OBJECTID)

        # Select each record inside of the polygon feature class    
        SelPoly = gp.SelectLayerByAttribute("polygon", "NEW_SELECTION", "\"OBJECTID\" =" + str(row.OBJECTID))
        #gp.AddMessage(row.OBJECTID)
            
        # Select all the point that are inside of the polygon record
        SelPts = gp.SelectLayerByLocation("point", "WITHIN", SelPoly, 0, "NEW_SELECTION")
        
        # Count the points that are in each polygon
        GetCount = gp.GetCount_management(SelPts)
        
        # Calculate the ASSOC_PTS field with the counted points
        gp.CalculateField_management("polygon", "ASSOC_PTS", GetCount, "VB", "")

        # Move to the next row   
        row = rows.Next()


except Exception, errMsg:

#  If we have messages of severity error (2), we assume a GP tool raised it,
#  so we'll output that.  Otherwise, we assume we raised the error and the
#  information is in errMsg.

    if gp.GetMessages(2):   
        gp.AddError(gp.GetMessages(2))
    else:
        gp.AddError(str(errMsg))
       
del row
del rows
Tags (2)
0 Kudos
1 Reply
NiklasNorrthon
Frequent Contributor
Two points:

By adding try - except statements without fixing the error in question, you hide vital information (like the traceback) that is very useful for debugging purposes.  Don't be afraid of unhandled exceptions and tracebacks, learn to read them and fix the problem behind them instead of hiding them. If you remove both your try - except statements in your code you will get the line number of the origin of the exception. When you have done that, and still can't pinpoint the reason of the crash, you can post the edited code, together with the full traceback and it will be much easier to help you fix the problem.

In my opinion there are basically two reasons for try - except: To handle expected errors and exceptions that can be fixed in the code, and to log error messages. In the latter case the exception should be reraised with an empty raise statement.

My second point is regarding your loop:
A much cleaner and less error prone pattern for looping over search cursors in 9.3 instead of what Esri teaches in there samples is:
rows = gp.SearchCursor('some_feature_class')
row_count = 0
for row in iter(rows.Next, None):
    # inside loop processing goes here
    print row.Name # or whatever
    row_count += 1
# after loop processing goes here
print row_count
0 Kudos