3

Using ArcGIS 10.2.2 and Python. I have a script that currently counts the number of points (representing crimes) in each zip code area, and writes that value to a new column in the FC that contains zip code boundaries.

Basically, the user inputs a point FC (crimes) and a polygon FC (zip boundaries), and the tool writes the number of crimes in each zip code boundary to a new field in the zip boundaries polygon FC.

What I would like to do is improve this code by allowing the user to choose the categories (which is contained in a separate field in the crimes point FC) of crimes that get counted for each zip code boundary. For example, rather than just counting all crimes, I would like the user to be able to select, say, Aggravated Assaults and Grand Theft (two of many values contained within the Category field of the Crimes FC) and have the tool only count those points.

# Import ArcPy Site Package
# Set environments settings: workspace location
import arcpy, sys


# Define location of farms and census sub division feature classes
crimes = arcpy.GetParameterAsText(0)
zip_parcels = arcpy.GetParameterAsText(1)
workspace = arcpy.GetParameterAsText(2)
new_field = arcpy.GetParameterAsText(3)
new_field_alias = arcpy.GetParameterAsText(4)


# Check if the field named new_field exists in the 'zip_parcels'
# feature class. If it exists, delete it.
if arcpy.ListFields(zip_parcels, new_field):
    sys.exit(arcpy.AddError("Error: Field Already Exists"))

# Create a new 'NumOfFarms' field in the 'zip_parcels' feature class    
arcpy.AddField_management(zip_parcels, new_field, 'Long', '', '', '', new_field_alias)

# Create temporary feature layers
crimes_lyr = arcpy.MakeFeatureLayer_management(crimes,'crimes_lyr')
zip_parcels_lyr = arcpy.MakeFeatureLayer_management(zip_parcels,'zip_parcels_lyr')

# Create an update cursor to access and update the temporary
# census subdivision feature layer.  For each sub division (or
# row), the NumOfFarms field will be updated
fields = ['ZIPCODE',new_field]
with arcpy.da.UpdateCursor(zip_parcels_lyr,fields) as cur:
    for row in cur:

        # Create a query to select a census sub division that will dictate which farms
        # are selected
        zip_parcels = row[0]
        where = '"ZIPCODE" = \'{}\''.format(zip_parcels)
        arcpy.SelectLayerByAttribute_management(zip_parcels_lyr,'NEW_SELECTION',where)     

        # Select the farms that intersect (or are within) the selected census sub
        # division and count how many are selected
        arcpy.SelectLayerByLocation_management(crimes_lyr,'WITHIN',zip_parcels_lyr)
        number_of_crimes = int(arcpy.GetCount_management(crimes_lyr).getOutput(0))

        # Populate the NumOfFarms field with the counted number of selected farms, which
        # also updates the the field in the csd feature class
        row[1] = number_of_crimes
        cur.updateRow(row)

Please excuse some of the commenting - it sometimes says farms and census subdivisions because I used this for a different project and have been slowly modifying it.

Where I need help is how to generate a multivalue checklist within the script tool GUI (when you double click the script in ArcCatalog sidebar) that lists all of the unique values within the Category field of the crime point FC. The checkboxes (field values) that the user selects will dictate the crimes that get counted.

Additionally, I would like to add that I have tried the solution listed here: http://blogs.esri.com/esri/arcgis/2012/07/16/generating-a-multivalue-choice-list/

This solution crashes Arc every single time and I feel there must be some easier way accomplish this task.

  • There are two ways of getting each unique value, assuming that is where you're having difficulty, one is to start with an empty list then cursor through the features adding the values to the list if not value in list: using list.append the other is to use summary statistics (count the OIDs) and case field of value then open that table and cursor though it (you can delete the temp table as soon as the cursor is closed). As for your definition query use the in operator but you will need to reformat the list like ('value1','value2'...) to select multiple types in your input layer. – Michael Stimson Nov 11 '14 at 22:21
  • Great - but how do I get these values to appear in the tool when the user selects the field that they want to get the unique values from? – ge0m3try Nov 11 '14 at 22:23
  • What are you using to create the form? Is it QT, PyWin or other I don't know of? That I think would be better posted on Stack Overflow : I've got a bunch of values, how to put that on a form? – Michael Stimson Nov 11 '14 at 22:27
  • 1
    It is best to include all relevant details within your question. Otherwise, in this case, it amounts to "Can you troubleshoot the code at another site?". As you will see here your question body is what we focus on. The simpler and clearer you can make that the better it is for potential answerers. You can use the edit button beneath your question to revise it at any time. – PolyGeo Nov 11 '14 at 23:15
  • 1
    Along PolyGeo's suggestion, if you are looking to do a python toolbox (.pyt) some of the answers here might be helpful. – jbosq Nov 12 '14 at 14:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.