I have many mxd's and I want to capture the features that are visible in a specific layer and feed that to another data processing tool. I wrote some code that gets a data frame extents and selects the features in the given extent. This seems to work pretty well. However the issue that I need help with is figuring out how to only select what is displayed. For example, a feature class might be symbolized by category, and have an " symbol value that is not checked, see screen shot.

Is there a way to select only the features from symbols that are visible?

screen shot

  • 1
    Create a definition query to display only those that are symbolised - something like STATUS IN ('Proposed Access Road', 'Existing Road'). Not symbolising something still makes them draw invisibly. Filtering them out using a Definition Query will make them not draw at all (therefore not selectable) – Midavalo Oct 15 '17 at 15:40
  • that would work but each map has different symbols, there are over 200 mxd's so I need to find a way to dynamically produce a query or select by attributes based on the symbols. is there a way to get a list of values from the symbology that could then be plugged into a definition query or a selection by attribute query – Brian Brokling Oct 15 '17 at 20:14

With arcpy you can determine the field and values used in a Unique Value symbol. Using these values you could create a Definition Query, select all your features, then remove the query again. This will mean the only selected features are those that are visible.

import arcpy
mxd = arcpy.mapping.MapDocument("CURRENT")
lyr = arcpy.mapping.ListLayers(mxd)[0]
desc = arcpy.Describe(lyr)

symField = lyr.symbology.valueField
symClassValues = lyr.symbology.classValues
otherValues = lyr.symbology.showOtherValues
exDefQuery = lyr.definitionQuery

if not otherValues:
    for x in desc.fields:
        if x.name == symField:
            print x.type
            fieldType = x.type
    if fieldType in ['SmallInteger', 'Double', 'Integer']:
        newclassvalues = tuple([float(x) for x in symClassValues])
        newclassvalues = tuple([x.encode('UTF8') for x in symClassValues])
    newDefQuery = "{} in {}".format(symField, newclassvalues)
    lyr.definitionQuery = newDefQuery
    print lyr.definitionQuery 

arcpy.SelectLayerByAttribute_management(lyr, 'SWITCH_SELECTION')
lyr.definitionQuery = exDefQuery

You could probably also use the same logic to make Select by Attributes only select those that matched the symbology, rather than using the definition query. This may be a safer route to try particularly if you already have some Definition Queries in place, as any existing Definition Queries will be ignored using my code above without a little modification to add to and then remove from the query.

| improve this answer | |

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.