Select to view content in your preferred language

Annotation Labels and Map Series

731
2
01-05-2023 06:44 AM
HarryBell
Occasional Contributor

Hello.

I have some Map Series pages at varying map scales.  

I turn on labelling, which looks OK other than the odd label here and there which I need to amend. 

When I create my annotation layer for the whole layer, the labels appear at just one scale, so on some of the pages they're massive, and others really small.

Is it possible to create an annotation layer for my labels for the whole map series at the size at which they appear on the map when they are simply displaying as normal labels?

Many thanks, Harry

Tags (2)
0 Kudos
2 Replies
MichaelVolz
Esteemed Contributor

Not the most elegant solution, but you can have multiple layers of annotation to handle the various scales and they become active using scale dependency settings.

0 Kudos
JesseWickizer
Esri Contributor

You can use the Tiled Labels To Annotation tool to create annotation features for areas defined in a polygon index layer, using scales set in that index layer. You can use Python to create a layer of polygons mimicking each page in your Map Series. The polygon layer will also include the map series page name and map scale that the Tiled Labels To Annotation tool can use. 

import arcpy
from arcpy import env
import math

# Set the existing feature class that the map series is based on
MapSeriesFc = "C:/temp/test_project/data.gdb/areas"
# Field name containing the name of each page in the Map Series
inputPageNameField = "NAME"
mapSeriesMarginSizePercent = 10
mapSeriesScaleRoundingValue = 10000

# Set the output location and name of the output feature class (the Geodatabase must already exist)
env.workspace = "C:/temp/test_project/data.gdb"
# Name for the new feature class that will be created in the gdb
outputFcName = "MapSeriesExtents"
outputFeatureClass = env.workspace + "/" + outputFcName

# Define the layout and map frame containing the map series
aprx = arcpy.mp.ArcGISProject("CURRENT")
layout = aprx.listLayouts()[0]
mapFrame = layout.listElements("MAPFRAME_ELEMENT", "Main Map Frame")[0]

# Create new feature class to hold the output
arcpy.CreateFeatureclass_management(env.workspace, outputFcName, "POLYGON", "", "DISABLED", "DISABLED", "WGS_1984_Web_Mercator_Auxiliary_Sphere")

# Add fields in the new feature class to store name and scale attributes
arcpy.management.AddField(outputFeatureClass, "MapName", "TEXT", 0, 0, 100)
arcpy.management.AddField(outputFeatureClass, "MapScale", "DOUBLE", None, None)

# An array to store the extent details of each map series page
outputFeatures = []

# Loop through each page in the map series and get the extents of each page
for row in arcpy.da.SearchCursor(MapSeriesFc, ['SHAPE@', inputPageNameField]):
  featureExtent = row[0].extent
  mapName = row[1]
  # Set the map frame to the extent of the feature
  mapFrame.camera.setExtent(featureExtent)
  
  # Get full extent of the page
  pageExtent = mapFrame.camera.getExtent()
  
  # Apply extent padding to mimic the map series padding
  width = (pageExtent.XMax - pageExtent.XMin)
  widthPadding = (width * (mapSeriesMarginSizePercent / 100))
  height = (pageExtent.YMax - pageExtent.YMin)
  heightPadding = (height * (mapSeriesMarginSizePercent / 100))
  
  paddedPageExtent = pageExtent
  paddedPageExtent.XMax = pageExtent.XMax + widthPadding / 2
  paddedPageExtent.XMin = pageExtent.XMin - widthPadding / 2
  paddedPageExtent.YMax = pageExtent.YMax + heightPadding / 2
  paddedPageExtent.YMin = pageExtent.YMin - heightPadding / 2
  mapFrame.camera.setExtent(paddedPageExtent)
  
  # Apply any map scale rounding
  roundedScale = round(mapFrame.camera.scale / mapSeriesScaleRoundingValue) * mapSeriesScaleRoundingValue
  mapFrame.camera.scale = roundedScale
  newPageExtent = mapFrame.camera.getExtent()
  outputFeatures.append((newPageExtent.polygon, mapName, mapFrame.camera.scale))

# Insert the polygon into the feature class
insertCursor = arcpy.da.InsertCursor(outputFeatureClass, ['SHAPE@', "MapName", "MapScale"])
for output in outputFeatures:
	insertCursor.insertRow(output)
del insertCursor

Once the polygon layer is created to mimic your Map Series pages, run the Tiled Labels To Annotation tool with these parameters:

  • Polygon Index Layer: the resulting MapSeriesExtents layer from the script
  • Tile ID Field: MapName (field that was created in the MapSeriesExtents layer)
  • Reference Scale Field: MapScale (field that was created in the MapSeriesExtents layer)

The result of the tool will be new annotation layers with their reference scales added to the names, and each of them added to a separate group like this:

JesseWickizer_0-1672955857730.png

If some of your map frames overlap other map frames you could have label conflicts so you could set the visibility ranges on GroupAnno### layers so they only display at the intended scale.

JesseWickizer_1-1672955857734.png

Or, since you're using a Map Series you could set a Page Query on the annotation layers so only the appropriate annotation layers display for each page in the series. This would be especially useful if multiple pages use the same scale and their frames overlap.

JesseWickizer_2-1672959861309.png

 

 

0 Kudos