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.

11
  • 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. Commented Nov 11, 2014 at 22:21
  • 1
    I think investigating tool validation should be your starting point on this but I think your question would benefit by including a picture/sketch of your desired tool dialog. Also, it looks to me like you are writing a Python script tool in a standard toolbox rather than a Python Toolbox - can you confirm that detail, please?
    – PolyGeo
    Commented Nov 11, 2014 at 23:04
  • 1
    There are advanced dialog options, I think one of them is a definition query which would require the user to do the hard work of creating the definition query. The options on the tool dialog are limited; PolyGeo's suggestion is likely to be your only real hope without having to create an add-in (which may not be a bad thing, they're quite useful and there are much more options) you could try downloading the model and exporting it to python to see how it works (or doesn't) modelbuilder has a special relationship with the dialog that isn't always available in python. Commented Nov 11, 2014 at 23:15
  • 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
    Commented Nov 11, 2014 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
    Commented Nov 12, 2014 at 14:35

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.