2

I use ArcMap and am looking for a way to change the selection color that would be respected when exporting map layouts programmatically using arcpy.mapping.ExportToPNG(). Currently, it is always the light green color (the default selection color in ArcMap).

enter image description here

Changing a selection color in ArcMap (Selection menu > Selection Options) does change the selection color but it is only respected when exporting the layout manually from the File menu or when exporting the layout in the Python window (it respects the selection color set in ArcMap since I am inside a live ArcMap session). Exporting a layout using arcpy though always uses the default light green color for selection.

I have found no other settings in the ArcMap menus that would help and AdvancedArcMapSettings utility does not have any either.

Is there any way to make arcpy export layouts using any other selection color than the default light green one?

4
  • 2
    i think there is a workaround see here: community.esri.com/thread/117867
    – NULL.Dude
    Mar 5, 2018 at 18:11
  • Alternatively you could try to represent your selection as a definition query on a second layer with the same data source.
    – PolyGeo
    Mar 5, 2018 at 19:29
  • @Geo.Dude, thanks a ton for the link, this was helpful and got me started. Mar 6, 2018 at 14:50
  • @PolyGeo, good idea, this has also moved me into the right direction! Mar 6, 2018 at 14:50

1 Answer 1

1

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.

  1. I pre-create three layers for each of the shape types (point, polyline, and polygon) using the necessary selection symbology.

  2. 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.

  3. 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()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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