Saturday 26 March 2016

arcgis 10.0 - Extracting by Attribute Using ModelBuilder with User Input?


Using ModelBuilder, I want to create a tool that will let a user choose the value or values that will be used to extract a shapefile.



I have a parcel layer with a "Parcel_Type" field. I want the user to be able to choose the type of parcel to extract. So if the user wants to extract the parcels with a type "EL" then he would only have to enter "EL" as a variable. If he wants type "EL" and "CDD" he needs to enter them as multi-variables. That would be the only human interaction with the model.


So how can i use those variables in my model?



Answer



This type of operation almost always involves writing a WHERE Clause so I think using at least a little bit of Python is in order.


Also while this is possible to do with ModelBuilder, IMO, creating a Python script tool with custom validation and more control over parameter settings could provide a better user experience -- for example, by making the Field and MultiValue* parameters drop-down menus that you can pick values from instead of having to type them in.


*possibly, actually not sure about MultiValue parameters


However, since that is a more advanced exercise for another topic, I'll stick to the ModelBuilder approach, using Python only to create the WHERE clause:



  1. Create a new model

  2. Create variables (right-click the empty canvas and click Add Variable) for the input Feature Layer, Field, and MultiValue parameters.


  3. Right-click each of these and select Model Parameter

  4. Add a Calculate Value (Data Management) tool to the canvas. Connect the 3 variables to it as preconditions (just for show in this case, but it can make a difference in execution order in other situations).


  5. Double-click the Calculate Value tool to set it up:


    5a. Copy/paste the following into the Expression box (adjust to match your variable names):


    buildWhereClauseMultiValue(r"%Feature Layer%","%Field%","%Values%")

    5b. Copy/paste the following into the Code Block box:


    import arcpy


    def buildWhereClauseMultiValue(table, field, values):
    """Takes a semicolon-delimited list of values and constructs a SQL WHERE
    clause to select those values within a given field and table."""

    # Add DBMS-specific field delimiters
    fieldDelimited = arcpy.AddFieldDelimiters(arcpy.Describe(table).path, field)

    # Split multivalue at semicolons and strip quotes
    valueList = [value[1:-1] if (value.startswith("'") and value.endswith("'")) else value for value in values.split(';')]


    # Determine field type
    fieldType = arcpy.ListFields(table, field)[0].type

    # Add single-quotes for string field values
    if str(fieldType) == 'String':
    valueList = ["'%s'" % value for value in valueList]

    # Format WHERE clause in the form of an IN statement
    whereClause = "%s IN(%s)" % (fieldDelimited, ', '.join(valueList))
    return whereClause


    5c. Set the output data type to be a SQL Expression.


    5d. Click Ok and right click the output variable from the Calculate Value tool and rename it to something more descriptive like "WHERE Clause".



  6. Add a Select Layer By Attribute (Data Management) tool to the canvas. Connect the Feature Layer and WHERE Clause variables to the Select Layer By Attribute tool.


  7. Add a Copy Features (Data Management) tool to the canvas. Connect the output of the Select Layer By Attribute tool to the Copy Features tool. Right click the Output Feature Class variable and check the Model Parameter and (optionally) the Add to Display options.


    At this point it should look something like this: Model Canvas





  8. Under the Model -> Model Properties menu give it a good name and label and save and close it.




  9. Double-click the model in ArcToolbox to bring up the model dialog. Enter your parameters and click OK. It should export the selected features to a new feature class and add it to the map (if you checked "Add to Display" on the output feature class).


    Model Dialog




NOTES:





  • You can always hardcode values and not "parameterize" variables you don't want the user changing like the feature layer or field parameters. I just like having tools that are generic/reusable so I made those model parameters. In fact what I would do is simply drag and drop the generic model into a new model and then set your predefined parameters -- that way you can make several different predefined "wrapper" models, but only have one underlying model doing the work, so if you need to change its functionality, you only have to change it in one place.




  • If you're lucky like I was you won't have to validate the model and supply some dummy data only to remove it after validation (note how all the model elements are blank/white, meaning they're not "ready to run" -- but I was able to run it anyways upon filling out the parameters on the model dialog).




No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...