Summary
The MapsurroundElement class provides access to size and positioning properties as well as a reference to the associated map frame.
Discussion
A MapSurroundElement is a layout element that has an associated MapFrame element and is dynamically linked to map frame information. For example, a north arrow is a map surround and is linked to the associated map frame's map rotation, and a scale bar is linked to the map's scale. The listElements method on the Layout class returns a Python list of all possible layout elements. To return a list of only MapSurroundElement objects, use the MAPSURROUND_ELEMENT constant for the element_type parameter. A wildcard value can also be used to further refine the search based on the element name value. It is important to uniquely name each layout element so it can be referenced using ArcPy scripting.
A MapSurroundElement is a generic object with relatively few properties. Many of the properties are related to size and position of the map surround on the layout. The mapFrame property will return a reference to a MapFrame object and from that object, you can access the map frame's map using its map property.
A number of layout elements return a type value of MAPSURROUND_ELEMENT. These include north arrows, scale bars, chart frames, table frames, and possibly other future element types that don't currently have a dedicated object with specialized properties. You can access some of these specialized object properties using Python CIM access. Examples of this are provided in the code samples below. One example of a map surround with specialized methods and properties is LegendElement. It returns an element type value of LEGEND_ELEMENT.
Caution:
In future development, objects with a current type value of MAPSURROUND_ELEMENT may be made into their own specialized object type, which would potentially affect the value of the element's type property and the element_type enumeration list available to the layout listElements method.
The elementPositionX and elementPositionY values are based on the element's anchor position, which is set on the Format tab. The default position depends on the type of map surround. For example, a north arrow's anchor default position is the center point, but a scale bar's default position is the lower left.
You can also create map surrounds using the createMapSurroundElement method on the Layout class. Using this method, you are limited to creating map surround element types based on the map_surround_type input parameter. It's also useful to reference an existing StyleItem element during creation to control how the element appears in the layout. Examples of this are below.
Properties
Property | Explanation | Data Type |
anchor (Read Only) | Returns one of the following string values that represent the current anchor position. To change the value, use the setAnchor method.
| String |
elementHeight (Read and Write) | The height of the element in page units. | Double |
elementPositionX (Read and Write) | The x-location of the element's anchor position. The units assigned or reported are in page units. | Double |
elementPositionY (Read and Write) | The y-location of the element's anchor position. The units assigned or reported are in page units. | Double |
elementRotation (Read and Write) | The element's rotation angle in degrees. Positive values rotate clockwise and negative values rotate counterclockwise. Note:This property does not apply to north arrows because their rotation is based on the rotation of the map. | Double |
elementWidth (Read and Write) |
The width of the element in page units. | Double |
locked (Read and Write) | When set to True, the element cannot be graphically selected in the layout view. | Boolean |
mapFrame (Read and Write) | A reference to the associated MapFrame. | MapFrame |
name (Read and Write) | The name of the element. It is important that all elements have a unique name so they can be uniquely referenced using the wildcard parameter with the listElements function on the Layout object. | String |
type (Read Only) | Returns a value of MAPSURROUND_ELEMENT. | String |
visible (Read and Write) | Returns True if the element is visible on the layout. Rather than having to move unwanted objects off the page before printing or exporting, you can turn the element's visibility on and off. | Boolean |
Method Overview
Method | Explanation |
getDefinition (cim_version) | Returns a map surround element's CIM definition. |
setAnchor (anchor) | The setAnchor method controls the anchor position for a MapSurroundElement value. |
setDefinition (definition_object) | Sets a map surround element's CIM definition. |
Methods
getDefinition (cim_version)
Parameter | Explanation | Data Type |
cim_version | A string that represents the major version of the CIM that will be used.
| String |
Data Type | Explanation |
Object | Returns the CIM definition for a MapsurroundElement value. |
For more information about working with the CIM and samples, see Python CIM access.
setAnchor (anchor)
Parameter | Explanation | Data Type |
anchor | A string that specifies the location of the anchor position.
| String |
Setting the anchor position is helpful because you can control how the element might expand when resized. For example, the default anchor position for a scale bar map surround element is BOTTOM_LEFT_CORNER. If you change the anchor location to TOP_RIGHT_CORNER, changing elementHeight will expand the element downward instead of upward (the default), and changing elementWidth will expand the element to the left.
setDefinition (definition_object)
Parameter | Explanation | Data Type |
definition_object | A modified CIM definition object originally retrieved using getDefinition. | Object |
For more information about working with the CIM and samples, see Python CIM access.
Code sample
The following script finds the MapsurroundElement named ScaleBar and changes its position so the center of the scale bar is located 0.5 page units below and to the center of its associated map frame. Note that the scale bar was authored with its anchor location in the center position. The map frame was authored with its anchor position located to the lower left.
import arcpy
aprx = arcpy.mp.ArcGISProject(r"C:\Projects\YosemiteNP\Yosemite.aprx")
lyt = aprx.listLayouts("Points of Interest")[0]
scaleBar = lyt.listElements("MAPSURROUND_ELEMENT", "ScaleBar")[0]
mf = scaleBar.mapFrame
scaleBar.elementPositionX = mf.elementPositionX + (mf.elementWidth / 2)
scaleBar.elementPositionY = mf.elementPositionY - 0.5
aprx.save()
del aprx
The following script creates a north arrow at a point location on a layout using an Esri system style. Then it uses Python CIM access to modify the calibrationAngle value.
#Page units Centimeters
p = arcpy.mp.ArcGISProject('current')
lyt = p.listLayouts('Layout')[0]
mf = lyt.listElements('MapFrame_Element', 'Map Frame')[0]
naStyle = p.listStyleItems('ArcGIS 2D', 'North_Arrow', 'Compass North 1')[0]
na = lyt.createMapSurroundElement(arcpy.Point(18.5,18), 'North_Arrow', mf,
nArrowStyle, "Compass North Arrow")
na.elementWidth = 2
#CIM modifications - change calibration angle
lyt_cim = lyt.getDefinition('V3')
for elm in lyt_cim.elements:
if elm.name == "Compass North Arrow":
elm.northType = 'TrueNorth'
elm.calibrationAngle = -2.5
lyt.setDefinition(lyt_cim)
The following script creates a scale bar on a layout using a helper function to create a rectangle for its placement and also uses an Esri system style. Then it uses Python CIM access to modify scale bar subdivisions and rounding.
#Helper function to make an envelope from a lower left X, Y, width and height
def MakeRec_LL(llx, lly, w, h):
xyRecList = [[llx, lly], [llx, lly+h], [llx+w,lly+h], [llx+w,lly], [llx,lly]]
array = arcpy.Array([arcpy.Point(*coords) for coords in xyRecList])
rec = arcpy.Polygon(array)
return rec
p = arcpy.mp.ArcGISProject('current')
lyt = p.listLayouts('Layout')[0]
mf = lyt.listElements('MapFrame_Element', 'Map Frame')[0]
#Page units Centimeters
sbName = 'Double Alternating Scale Bar 1 Metric'
sbStyle = p.listStyleItems('ArcGIS 2D', 'Scale_bar', sbName)[0]
sbEnv = MakeRec_LL(1.5, 15, 8, 1)
sb = lyt.createMapSurroundElement(sbEnv, 'Scale_bar', mf, sbStyle, 'New Scale Bar')
#CIM modifications - change number of subdivisions and rounding
lyt_cim = lyt.getDefinition('V3')
for elm in lyt_cim.elements:
if elm.name == 'New Scale Bar':
elm.subdivisions = 2
elm.numberFormat.roundingOption = "esriRoundNumberOfSignificantDigits"
elm.numberFormat.roundingValue = 2
lyt.setDefinition(lyt_cim)
The following script creates a legend on a layout using an Esri system style and a helper function to create a rectangle for its placement. Then it uses Python CIM access to modify the minimum font size.
#Helper function to make an envelope from a upper left X, Y, width and height
def MakeRec_UL(ulx, uly, w, h):
xyRecList = [[ulx, uly], [ulx+w, uly], [ulx+w,uly-h], [ulx,uly-h], [ulx,uly]]
array = arcpy.Array([arcpy.Point(*coords) for coords in xyRecList])
rec = arcpy.Polygon(array)
return rec
p = arcpy.mp.ArcGISProject('current')
lyt = p.listLayouts('Layout')[0]
mf = lyt.listElements('MapFrame_Element', 'Map Frame')[0]
#Page units Centimeters
legStyle = p.listStyleItems('ArcGIS 2D', 'Legend', 'Legend 3')[0]
legEnv = MakeRec_UL(1.5, 14, 18.5, 10)
sb = lyt.createMapSurroundElement(legEnv, 'Legend', mf, legStyle, 'New Legend')
#CIM modifications - change the minimum font size
lyt_cim = lyt.getDefinition('V3')
for elm in lyt_cim.elements:
if elm.name == 'New Legend':
if elm.fittingStrategy == 'AdjustColumnsAndSize':
elm.minFontSize = 8
lyt.setDefinition(lyt_cim)