jread

Looking for ways to optimize painfully slow code:

Discussion created by jread on Jun 7, 2013
Latest reply on Jun 8, 2013 by jread
We are trying to accomplish the following:

1.  Water Mains have a Pressure Zone assigned to them depending on what zone they are located in.

2.  The junction/point features (valves, fittings, etc.) have attributes called PRESSUREZONE1 and PRESSUREZONE2.

3.  The Pressure Zone values of the mains connected to the junction determine what its PRESSUREZONE1/2 values are.  If all the mains connected have the same Pressure Zone value, then PRESSUREZONE1 is that value and PRESSUREZONE2 is Null.  If the mains have two or more values, PRESSUREZONE1 is one value, and PRESSUREZONE2 is one of the other values (there are no specific criteria for what to do if there are 3 ore more different Pressure Zones, and there is not a field to hold the extra values anyway.

I have started a script to assign the PRESSUREZONE1/2 values to the junctions programmatically, and am just testing it with two featureclasses so far:  ZoneValves and Mains.  The script does work, but it is very slow and takes about 1-second per feature to process.  This is a big problem as some of the junction featureclasses have tens of thousands of records.

Here is what I have done so far:

# Import arcpy module
import arcpy, string

# Local variables:
Main = "Database Connections\\gissde.sde\\CITY.Water\\CITY.Main"
ZoneValve = "Database Connections\\gissde.sde\\CITY.Water\\CITY.ZoneValve"

arcpy.MakeFeatureLayer_management(Main, "Main_Lyr")
arcpy.MakeFeatureLayer_management(ZoneValve, "ZoneValve_Lyr")

rows = arcpy.UpdateCursor("ZoneValve_Lyr")
for row in rows:
    arcpy.SelectLayerByAttribute_management("ZoneValve_Lyr", "NEW_SELECTION", "AW_ID = " + str(row.AW_ID))
    arcpy.SelectLayerByLocation_management("Main_Lyr", "INTERSECT", "ZoneValve_Lyr", "", "NEW_SELECTION")

    mainPZList = []

    mainRows = arcpy.SearchCursor("Main_Lyr")
    for mainRow in mainRows:
        mainPZList.append(mainRow.PRESSUREZONE)

    mainPZList = list(set(mainPZList)) # Remove duplicate values from list

    if len(mainPZList) >= 1:
        row.PRESSUREZONE1 = mainPZList[0]
        rows.updateRow(row)

    if len(mainPZList) > 1:
        row.PRESSUREZONE2 = mainPZList[1]
        rows.updateRow(row)


Basically I am making feature layers out of the featureclasses, creating an Update Cursor to iterate through the junction/point features, then for each feature doing a spatial selection to select the mains that intersect the junction, adding the pressure zones for those mains to a list, using "set" to compress the list to remove duplicate values, then populating the PRESSUREZONE1/2 values of the junction feature based on whether or not one or more Pressure Zone values are found in the list of connected mains.

I see some obvious problems, such as creating a Search Cursor for each junction (tens of thousands of search cursors are created when this is run), however I'm not sure of a faster, more efficient way to do this.

If you guys have any suggestions I would appreciate them very much!

Outcomes