4

I would like to automatically display a featureclass as different layers based on a specific field. I've seen a few tools online and on XToolsPro under the category of Split by Attributes, but they create multiple NEW shapefiles or feature classes.

What I would like is for a way to make multiple "layers" that show different views based on definition queries, but I would like all the definition queries to be created automatically based on the change in a specific field.

So for example, for a field "State", there would be multiple copies of the same layer created, but the definition query in each layer says State="TX", State="AK", etc.

  • 1
    Please edit the question to contain the code you've written so far. – Vince Jun 30 '15 at 15:36
  • Sadly I don't know how to code this. Was hoping someone may have created this at some point. Thanks. – Tx_Dan Jun 30 '15 at 15:51
  • 3
    If you don't demonstrate any effort to attempt a solution ("due diligence"), you might find that others may not either. – Vince Jun 30 '15 at 16:13
  • This would make a nice ArcPy training exercise is using a SearchCursor, layer objects and their definitionQuery property, and AddLayer - but why would you want to have these layers (and/or layer files?)? i.e. what is the use case? – PolyGeo Jun 30 '15 at 23:57
  • Would be useful in the gas transmission industry – Barbarossa Jul 1 '15 at 13:44
3

I've certainly created something like this; it's a great use for definition queries. Here's a copy/paste/modification from a tool I've written. You'll have to look up how to create a script tool in a toolbox. When you do, make two parameters, one to hold the input shapefile/feature class (type = Feature Class or Layer), and one to enter the "layer by" field (type = String). Then, use this code in the script that's associated with the tool:

import arcpy

## get user input
datasource = arcpy.GetParameterAsText(0)
field = arcpy.GetParameterAsText(1)

## make the mxd and data frame objects
mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd)[0]

## make list of unique values in field
unique_values = set([row[0] for row in arcpy.da.SearchCursor(datasource,field)])
unique_values.sort()

## iterate through the values, and make layers for each one
fieldname = arcpy.AddFieldDelimiters(datasource, field)
for value in unique_values:
    query = "{0} = '{1}'".format(fieldname,value)
    layer = arcpy.mapping.Layer(datasource)
    layer.name = value
    layer.definitionQuery = query
    arcpy.mapping.AddLayer(df, layer, "BOTTOM")

This is very bare-bones, and you could add a bunch of bells and whistles. First thing I'd do is go in the ToolValidator for the script tool itself and add these lines to the updateParameters function:

def updateParameters(self):

    if self.params[0].value:
        fieldnames = [f.name for f in arcpy.ListFields(self.params[0].value)]
        self.params[1].filter.list = fieldnames

Now you'll have a dropdown in the tool dialog with the field names, so you won't have to carefully type the field name (because the script will not work with improper case!)

Regarding use cases: this is the skeleton of a tool I used to create multi-layered kml files... automate the creation of a bunch of layers like this, apply a standardized symbology to each layer, and use the map to KML tool on the map document to create the output. Wonderfully useful for sharing data with non-GIS users.

  • what does set do in set([row[0] for row..? Does that compress the list into just its unique elements? +1 BTW, a good tutorial on modifying definition queries and adding layers. – Michael Stimson Jul 1 '15 at 2:24
  • yes, that's what set does. just try print set([1,2,2]) in IDLE or the python console and you'll see. – mr.adam Jul 1 '15 at 14:04
  • 1
    Why not have datasource = arcpy.GetParameter(0) and set the type as Feature Layer, then set the parameter 2's type as field, obtained from parameter 1? You will not have to modify the updateParameters and you have an object to work with, as opposed to a string. – Barbarossa Jul 2 '15 at 17:33
  • That sounds very promising, I just haven't done it. Though, getting the parameters as text is completely sufficient, and you need the name of the field, not the field object, anyway. – mr.adam Jul 2 '15 at 17:40
  • 1
    I only mention it because those with little experience with ToolValidator class may have trouble with it. – Barbarossa Jul 2 '15 at 17:57

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.