mpc

Python script in Arc very slow + code improvement

Discussion created by mpc on Mar 23, 2011
Latest reply on Apr 28, 2011 by mpc
The following script takes 3 min to complete in Python on a shapefile that has 211 features. In Arc as a script in a Toolbox it takes 25 min :( Arc sits there when it gets to writing a particular feature and I'm not sure why. Is there extra checking and processing that occurs behind the scenes when you run a script as a tool in Arc?

The script is pretty basic and I know there are some improvements I could do to speed it up; such as utilising a dictionary, so I'm not repeating MakeFeatureLayer for rows that have the same Area_m2 value, and actually working out how to query based on [Shape_Area], and get it to work! However, if it took 3 min in Arc I'd be happy.

Any insights into this would be much appreciated.

import arcpy
import sys

arcpy.env.overwriteOutput = True

# Variables defined by the user

infc = arcpy.GetParameterAsText(0)
FGDBlocation = arcpy.GetParameterAsText(1)
FGDBname = arcpy.GetParameterAsText(2)
outfcname = arcpy.GetParameterAsText(3)
##lyrfile = arcpy.GetParameterAsText(4)

# Set other variables
##lyrfile = "G:\\GIS\\ModelBuilder\\Count_overlaps_tool\\CountOverlaps.lyr"
FGDB = FGDBlocation + "\\" + FGDBname + ".gdb"
output = FGDB + "\\" + outfcname
unionout = FGDB + "\\union"

try:
    # Run repair incase of empty geometries and self intersects
    arcpy.RepairGeometry_management(infc)
##    print "Repaired geometry"
    
    # Create File Geodatabase to hold output featureclass
    arcpy.CreateFileGDB_management(FGDBlocation, FGDBname)
##    print "Created FGDB"
    
    # Create temporary layer in memory for processing
    arcpy.MakeFeatureLayer_management(infc, "in_memory\temp")
##    print "Created temp layer"
    
    # Union featureclass to process overlaps
    arcpy.Union_analysis ("in_memory\temp", unionout)
      
    # Create new field for storing overlap count to be populated
    arcpy.AddField_management(unionout, "Count", "SHORT", "2")
    arcpy.AddField_management(unionout, "Area_m2", "TEXT", "", "", "15")
##    print "Added fields"

    # Populate the new field
    arcpy.CalculateField_management(unionout, "Area_m2", "round(!Shape_Area!, 1)", "PYTHON_9.3")    
        
except:
    print arcpy.GetMessages()
##    print "error"

# Delete unrequired fields    
arcpy.DeleteField_management(unionout, ["Id", "FID_Treatment", "Area", "Hectares"])    
##print "Deleted fields"

# Create temporary layer in memory for processing
arcpy.MakeFeatureLayer_management(unionout, "in_memory\union")

# Create attribute index to speed up querying??
arcpy.AddIndex_management("in_memory\union", "Area_m2", "Area_m2Index")

# Setup cursor for update
rows = arcpy.UpdateCursor("in_memory\union", "", "", "Count; Area_m2")

for row in rows:

    # Get the value from the Shape Area field
    area = row.getValue("Area_m2")
    
    # Clause used to create selection later             
    clause = "\"Area_m2\" = " + "'" + area + "'"
##    print clause

    # Create temporary layer of all features with the same Area_m2 field value
    arcpy.MakeFeatureLayer_management("in_memory\union", "in_memory\temp", clause)

    # Count number of identical features to be used to populate count field
    featcount = arcpy.GetCount_management("in_memory\temp")
##    print featcount

    # Populate the Count field with the number of overlaps
    row.Count = str(featcount)

    # Update the row to write the Count value to the field
    rows.updateRow(row)

else:
    print "End of rows"

try:
    
    # Delete identical features
    arcpy.DeleteIdentical_management(unionout, ["Area_m2"])
##    print "Deleted duplicates"

    # Copy feature class from memory to a physical location
    arcpy.CopyFeatures_management("in_memory\union", output)
##    print "Copied features"

    arcpy.Delete_management(unionout)
    arcpy.Delete_management("in_memory\temp")
    arcpy.Delete_management("in_memory\union")
##    print "Deleted redundant and temporary layers"
    
except:
    print arcpy.GetMessages()

del row
del rows

Outcomes