1

When creating a custom tool using a Python script, is there a way to only show layers that, for example, contain a certain word?

For the drop down of the input polygon feature, I only want layers to show that have the word boundary in them.

Is this possible, or does it just automatically show all layers in the document?

Here's a screenshot of what I'm talking about:

enter image description here

It's a bad example because it only shows one layer, but image lots, and lots of layers.

3
  • 1
    Have you considered using tool validation to do this?
    – PolyGeo
    Apr 15, 2014 at 3:46
  • Yeah, that's the only way I figured it would be possible, but after looking through the documentation I can't see anything that would work. Am I missing something?
    – ianbroad
    Apr 15, 2014 at 3:47
  • 1
    It is what I would try and not what I have tried for this specific example. If you tag it with tool-validation you are likely to attract the audience that is most skilled in that area.
    – PolyGeo
    Apr 15, 2014 at 3:50

1 Answer 1

4

You need to use tool validation for this. For custom Python script tool (that has two input parameters - string with filter value list and string with filter value list for feature layers in the currently open map document).

enter image description here

import arcpy
class ToolValidator(object):
  """Class for validating a tool's parameter values and controlling
  the behavior of the tool's dialog."""

  def __init__(self):
    """Setup arcpy and the list of tool parameters."""
    self.params = arcpy.GetParameterInfo()

  def initializeParameters(self):
    """Refine the properties of a tool's parameters.  This method is
    called when the tool is opened."""
    return

  def updateParameters(self):
    """Modify the values and properties of parameters before internal
    validation is performed.  This method is called whenever a parameter
    has been changed."""
    if self.params[0].value:
        upd_list = []
        mxd = arcpy.mapping.MapDocument(r"CURRENT")
        df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]
        for lyr in arcpy.mapping.ListLayers(mxd, "*{0}*".format(self.params[0].value), df):
            upd_list.append(lyr.name)
        self.params[1].filter.list = upd_list    
    return

  def updateMessages(self):
    """Modify the messages created by internal validation for each tool
    parameter.  This method is called after internal validation."""
    return

For Python toolbox tool:

class FilterLayerNameTool(object):
    def __init__(self):
        """Define the tool (tool name is the name of the class)."""
        self.label = "FilterLayerNameTool"
        self.description = "FilterLayerNameTool"
        self.canRunInBackground = False

    def getParameterInfo(self):
        """Define parameter definitions"""
        in_filter = arcpy.Parameter(
            displayName="Input filter word",
            name="in_filter",
            datatype="GPString",
            parameterType="Required",
            direction="Input")
        in_filter.filter.type = "ValueList"
        in_filter.filter.list = ["Boundary","Border"]

        in_fc = arcpy.Parameter(
            displayName="Input Features",
            name="in_features",
            datatype="GPString",
            parameterType="Optional",
            direction="Input")
        in_fc.filter.type = "ValueList"
        in_fc.filter.list = []

        parameters = [in_filter,in_fc]
        return parameters

    def isLicensed(self):
        """Set whether tool is licensed to execute."""
        return True

    def updateParameters(self, parameters):
        """Modify the values and properties of parameters before internal
        validation is performed.  This method is called whenever a parameter
        has been changed."""
        if parameters[0].value:
            upd_list = []
            mxd = arcpy.mapping.MapDocument(r"CURRENT")
            df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]
            for lyr in arcpy.mapping.ListLayers(mxd, "*{0}*".format(parameters[0].value), df):
                upd_list.append(lyr.name)
            parameters[1].filter.list = upd_list
        return

    def updateMessages(self, parameters):
        """Modify the messages created by internal validation for each tool
        parameter.  This method is called after internal validation."""
        return

    def execute(self, parameters, messages):
        """The source code of the tool."""
        return
2
  • I never thought of using a string. I use a similar method in listing certain fields from a feature class. This should work for what I need. I'll have to test it to see if the user can still drag a layer from the TOC over into the parameter. Thanks!
    – ianbroad
    Apr 15, 2014 at 14:42
  • 2
    No problem, @ian. It seems as using strings is the only way to get use of filters in the way you want. You won't be able to drag any layer from the TOC into a parameter of String type. Apr 15, 2014 at 14:49

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.