Select to view content in your preferred language

Grey out surrounding raster area?

558
3
02-19-2026 08:53 AM
Bud
by
Legendary Contributor

In ArcGIS Pro, is there an easy way to grey out the surrounding raster area around a "light of day" rectangle?

Bud_0-1771519845618.png

Idea: Draw attention to an area of a map by fading the periphery

3 Replies
geo-theo
New Contributor

The easiest approach would be to duplicate the raster layer, clip the top copy to your desired 'Light Of Day' rectangle, and then remove color bands from the bottom raster.

  1. Copy raster (in contents pane > right click raster feature layer > copy).
  2. Paste raster as new layer (in map > right click > paste).
  3. With your original raster now as the bottom layer, grey it out with a grayscale raster function (Imagery tab > Raster Functions > Grayscale). Or you could just make it look faded out (Appearance tab > set transparency to something like 75%).
  4. With your new raster now as the top layer, you want to clip it to a rectangle polygon to serve as your Light Of Day view (like cropping a photo to a predetermined size). To do this, create a new feature class (call it something like "LoD_clip") and draw your rectangle polygon directly with the feature class editing (or convert an existing rectangle area to a polygon). Use the clip tool (input feature: raster layer / clip to: LoD_clip) and it will output a new layer that is just your raster within the bounds of the clip's rectangle window.
  5. Uncheck visibility of (or simply remove) the unclipped color raster, leaving you with the full-color clipped raster at the top, and the greyed-out raster at the bottom of the drawing order.

This should be the simplest way to get everything inside the Light Of Day rectangle to stay full color while everything outside appears greyed-out.

Robert_LeClair
Esri Esteemed Contributor

The Clip function—ArcGIS Pro | Documentation raster function in ArcGIS Pro could also be a solid workflow to consider too.  Use the Inside/Outside parameter to screen out the surrounding AOI/box.  Place the new result in-memory layer on top of the original then set a transparency for the original layer.

0 Kudos
BrennanSmith1
Frequent Contributor

Not quite what you asked, but we often need to do something similar, with a greyed out "reverse mask" around various watershed polygons. We have this function set up to turn any polygon / feature class into a cutout of itself, inside a circular buffer of whatever distance. If you pass it fields, you can use these reverse masks inside a Map Series too, to highlight specific regions as you loop through.

This would require that your graphics layer be a feature class. 

import arcpy
import os

def create_reverse_mask(input_fc, output_name, buffer_dist=10000, fields=[]):
    """
    Creates a 'cutout' mask from input polygons and adds it to the map 
    with 75% transparent grey symbology.
    
    input_fc    : Layer in TOC, or path to feature class
    output_name : Can be a full path, or just the name (in which case, save to scratchGDB)
    buffer_dist : Map Units. Set as big as needed for layout
    fields      : Define the fields to copy over from input (or leave empty)
    """
    # Prevent double-adding to TOC
    arcpy.env.addOutputsToMap = False
    
    # --- Path Handling ---
    if os.path.isabs(output_name):
        out_dir = os.path.dirname(output_name)
        out_base = os.path.basename(output_name)
        output_fc = output_name
    else:
        out_dir = arcpy.env.scratchGDB
        out_base = output_name
        output_fc = os.path.join(out_dir, out_base)

    # --- Initialize Feature Class ---
    if not arcpy.Exists(output_fc):
        sr = arcpy.Describe(input_fc).spatialReference
        arcpy.management.CreateFeatureclass(
            out_path=out_dir, 
            out_name=out_base, 
            geometry_type="POLYGON", 
            template=input_fc,
            spatial_reference=sr
        )
        print(f"Created: {output_fc}")

    # --- Processing ---
    cursor_fields = ["SHAPE@"] + fields
    with arcpy.da.InsertCursor(output_fc, cursor_fields) as i_cursor:
        with arcpy.da.SearchCursor(input_fc, cursor_fields) as s_cursor:
            for row in s_cursor:
                geom = row[0]
                if geom:
                    buff = geom.buffer(buffer_dist)
                    mask_geom = buff.difference(geom)
                    i_cursor.insertRow((mask_geom,) + row[1:])

    # --- Symbology (CIM) ---
    aprx = arcpy.mp.ArcGISProject("CURRENT")
    m = aprx.activeMap
    
    # Manually add the layer so we can grab the object
    new_lyr = m.addDataFromPath(output_fc)
    cim = new_lyr.getDefinition('V3')
    
    # 25% Opaque = 75% Transparent
    grey_fill = [128, 128, 128, 25] 
    
    # Iterate through symbol layers to update fill and disable stroke
    for sl in cim.renderer.symbol.symbol.symbolLayers:
        if isinstance(sl, arcpy.cim.CIMSolidFill):
            sl.color.values = grey_fill
        if isinstance(sl, arcpy.cim.CIMSolidStroke):
            sl.enable = False
            
    new_lyr.setDefinition(cim)
    print(f"Done. Layer '{out_base}' added.")

# Example Call:
#create_reverse_mask("lightofdaypolygon", "reversemask", 100000)