The arcpy.mapping.Layer
object does not expose the selection symbol property according to the docs of the Layer
:
Not all layer properties are accessible through the Layer object.
There are many properties available in the ArcMap Layer Properties
dialog box that are not exposed to the arcpy scripting environment
(for example, display properties, field aliases, selection symbology,
and so on).
Adding duplicate layers pointing to the same data source and setting the definition queries sounds really cumbersome, particularly when I don't know beforehand what layers I will need to run selection on.
I have solved it in another way.
I pre-create three layers for each of the shape types (point, polyline, and polygon) using the necessary selection symbology.
Before the export of the map document, I duplicate the layer that I will run selections on and update its symbology using the .lyr
file.
Then I set definition query on the dummy layer that will serve as a selection symbol layer only.
All of this is done programmatically, so the only thing I really need to supply is the name of the layer that selections will run on.
The full script:
'''
Script that demonstrates how to use predefined layer files (.lyr)
to change the selection symbol for any map document layer. The
selection symbol is not exposed via `arcpy.mapping.Layer` object, so
it is necessary to emulate the selection using another layer drawn
on top of the layer that you targeting your selection against.
The script assumes that you have prepared beforehand 3 layers (.lyr
files) for each shape type (point, polyline, polygon).
'''
import arcpy
import arcpy.mapping as mp
#----------------------------------------------------------------------
def get_layer_shape_type(mxd, layer_name):
"""return shape type of layer in the operational map document"""
lyr = mp.ListLayers(mxd, layer_name)[0]
return arcpy.Describe(lyr).shapeType.lower()
#----------------------------------------------------------------------
def main():
# name of the layer that will have selections
base_layer_name = 'cities'
# name of the layer that will be drawn on top emulating the selection symbol
select_layer_name = base_layer_name + '_selection'
mxd = arcpy.mapping.MapDocument(r'C:\GIS\Temp\export_selection.mxd')
df = mp.ListDataFrames(mxd)[0]
# get the right layer based on shape type of the base layer
lyr_template = arcpy.mapping.Layer(r'C:\GIS\Temp\{}.lyr'.format(
get_layer_shape_type(mxd, base_layer_name)))
# copy the TOC layer that will have selections to the top of TOC
arcpy.mapping.AddLayer(df, mp.ListLayers(mxd, base_layer_name)[0], 'TOP')
# rename the newly copied layer
mp.ListLayers(mxd, base_layer_name)[0].name = select_layer_name
# update the symbology of the newly copied layer to have the needed
# selection symbol
mp.UpdateLayer(
df,
mp.ListLayers(mxd, select_layer_name)[0],
lyr_template,
symbology_only=True)
print mp.ListLayers(mxd)
# [<map layer u'cities_selected'>, <map layer u'cities'>]
lyr_base = mp.ListLayers(mxd, base_layer_name)[0]
lyr_selection = mp.ListLayers(mxd, select_layer_name)[0]
# doing selection on the base layer
arcpy.SelectLayerByAttribute_management(
in_layer_or_view=lyr_base,
selection_type='NEW_SELECTION',
where_clause=" STATE_NAME = 'Oregon' ")
df.zoomToSelectedFeatures()
print lyr_base.getSelectionSet()
#[3129L, 3130L, 3131L, 3132L]
# limiting the features to be drawn in the layer with selection symbol
lyr_selection.definitionQuery = "OBJECTID in ({})".format(
','.join([str(i) for i in lyr_base.getSelectionSet()]))
# clearing selection of the base layer
arcpy.SelectLayerByAttribute_management(
in_layer_or_view=lyr_base, selection_type='CLEAR_SELECTION')
# exporting the map
arcpy.RefreshActiveView()
mp.ExportToPNG(mxd, r'C:\GIS\Temp\sel_prog_{}.png'.format(base_layer_name))
main()