Select to view content in your preferred language

Python Script for Layer Annotation

102
3
Friday
Labels (1)
HaileyTimmons
Emerging Contributor

I am working on building a script to annotate one of our layers and am having some issues with it. 

My main issue is it keeps defaulting to a reference scale of 1:24,000, however I need it to keep scale with the map which it is not doing. The reference scale changes, so I can't have a set reference scale, how do i fix this? I know it probably has to do with the Ensure map reference scale section, however I don't know how to fix it to use whatever the map is currently at.

Below is the script I am using.

# -*- coding: utf-8 -*-
import arcpy

def Model():
arcpy.env.overwriteOutput = True

Input_Map = "Map"
Stores_Sales_Label = "Stores - Sales Label"
Annotation_Group_Layer_Name = "Stores___Sales_LabelAnno"

print("Opening current project and map...")
aprx = arcpy.mp.ArcGISProject("CURRENT")
current_map = aprx.listMaps(Input_Map)[0]
print(f"Current map: {current_map.name}")

default_gdb = aprx.defaultGeodatabase
print(f"Using default geodatabase: {default_gdb}")

# ---------------------------
# Ensure map has a reference scale
# ---------------------------
if not current_map.referenceScale or current_map.referenceScale == 0:
# Try to get current active view scale
active_view = current_map.defaultView
if active_view and hasattr(active_view, "camera"):
scale = active_view.camera.scale
if scale is None or str(scale) == 'nan':
scale = 24000 # fallback default
print("Active view scale is NaN. Using fallback scale 1:24000.")
current_map.referenceScale = int(scale)
aprx.save()
print(f"Map reference scale was missing. Set to current view scale: 1:{int(scale)}")
else:
# Fallback if no active view
current_map.referenceScale = 24000
aprx.save()
print("No active view. Map reference scale set to fallback 1:24000.")

conversion_scale = current_map.referenceScale
print(f"Using ACTIVE MAP reference scale: 1:{conversion_scale}")

# ---------------------------
# Get target layer
# ---------------------------
target_layers = [lyr for lyr in current_map.listLayers() if lyr.name == Stores_Sales_Label]
if not target_layers:
raise ValueError(f"Layer '{Stores_Sales_Label}' not found in map.")

label_layer = target_layers[0]
print(f"Found label layer: '{label_layer.name}'")

# ---------------------------
# Get feature layer under label layer
# ---------------------------
if hasattr(label_layer, "supportedLayers") and label_layer.supportedLayers:
source_feature_layer = label_layer.supportedLayers[0]
print(f"Using underlying feature layer: {source_feature_layer.name}")
extent_obj = arcpy.Describe(source_feature_layer).extent
else:
print("Label layer has no supported source layers. Using full map extent.")
extent_obj = current_map.defaultView.camera.getExtent()

print(f"Using extent: {extent_obj.XMin}, {extent_obj.YMin}, {extent_obj.XMax}, {extent_obj.YMax}")

# ---------------------------
# Remove old annotation group
# ---------------------------
for lyr in current_map.listLayers():
if lyr.isGroupLayer and lyr.name == Annotation_Group_Layer_Name:
current_map.removeLayer(lyr)
print(f"Removed existing annotation group: {Annotation_Group_Layer_Name}")
break

# ---------------------------
# Convert labels to annotation
# ---------------------------
print("Running ConvertLabelsToAnnotation...")
arcpy.cartography.ConvertLabelsToAnnotation(
input_map=current_map,
conversion_scale=conversion_scale,
output_geodatabase=default_gdb,
extent=extent_obj,
output_group_layer=Annotation_Group_Layer_Name,
which_layers="SINGLE_LAYER",
single_layer=label_layer
)

# ---------------------------
# Turn on annotation + zoom
# ---------------------------
anno_groups = [lyr for lyr in current_map.listLayers()
if lyr.isGroupLayer and lyr.name == Annotation_Group_Layer_Name]

if anno_groups:
anno_group = anno_groups[0]
anno_group.visible = True
print(f"Annotation group '{Annotation_Group_Layer_Name}' is now visible.")

try:
active_view = current_map.defaultView
anno_children = anno_group.listLayers()

if not anno_children:
print("No annotation layers inside group. Cannot zoom.")
else:
anno_feature_layer = anno_children[0]
anno_extent = arcpy.Describe(anno_feature_layer).extent

if active_view and hasattr(active_view, "camera"):
active_view.camera.setExtent(anno_extent)
print("Zoomed to new annotation extent.")

except Exception as e:
print(f"Could not zoom to annotation: {e}")
else:
print(f"Could not find annotation group '{Annotation_Group_Layer_Name}'.")

print("Annotation process completed successfully!")

# Run the model
Model()
3 Replies
DanPatterson
MVP Esteemed Contributor

Code formatting ... the Community Version - Esri Community

people will then see proper formatting and can comment with reference to line numbers


... sort of retired...
0 Kudos
HaileyTimmons
Emerging Contributor

Thank you! I corrected it.

0 Kudos
DuncanHornby
MVP Notable Contributor

Your reformatting is not right, you have collapsed all the indentation so its impossible to determine your loop structures which ultimate dictates logic of your code. Please improve.

0 Kudos