I am trying to get the extent from all bookmarks in an aprx-document - when ArcGISA Pro is NOT open.
I am able to get the X,Y,Z and scale, but not the extent. I have tried 2 approached which both fails, and a third approach where I doubt the result.
GetBookMarks1 fails in the line "extent = mapCam.getExtent()"
GetBookMarks2 fails in the line "mv.zoomToBookmark(b)"
Does anyone have a good idea?
Is it possible to calculate the extent using the camera-properties as it is done in GetBookMarks3?
****************************************************************************
import arcpy
# Get APRX.
aprx = arcpy.mp.ArcGISProject(PATH)
layouts = aprx.listLayouts()
for layout in layouts:
map_frames = layout.listElements("MAPFRAME_ELEMENT")
for mf in map_frames:
print(f"Map Frame: {mf.name}")
map_obj = mf.map
bookmarks = map_obj.listBookmarks()
for bookmark in bookmarks:
print(f"Bookmark: {bookmark.name}")
mf.zoomToBookmark(bookmark)
print(mf.camera.getExtent())
But it seems like the only way to iterate through bookmarks on Map objects would be by using the "activeView"... which I don't think is accessible outside of Pro; from the MapView docs:
"The MapView returned from the activeView property is the only way to change the extent of the Camera associated with a map view."
If we can't change the Camera, I don't think updating the bookmarks would be possible, and therefore we can't get an extent that changes along with bookmark updates.
My guess for why this might be is that while the application is running, there can be an activeView, the dimensions of which are partly determined by how big your TOC, Catalog Pane, etc. are. When the software is not open, I don't think each APRX stores that information regarding window/sidebar size. So, a "Map" object alone (you need the "MapView") can't have an extent, and therefore, neither can a bookmark; not without it currently being open and used. Unless, that map is embedded on a map frame that does have specific boundaries (the map frame box on the layout sheet).
Just my thoughts based on the documentation.
@VinceE , point taken regarding using the "Insert/Edit code sample".
I needed to get extent of the bookmarks from the aprx-document , because I want to create the same bookmarks in a webmap - it was part of an automated featureservice publishing process.
The code below does the trick
# -*- coding: utf-8 -*-
import arcpy, json
from arcpy._mp import Map, ArcGISProject
from arcpy.cim.CIMMap import CIMMap, CIMBookmark, CIMViewCamera
def GetBookMarks3(aprxDocument:str, wkid:int) -> dict:
outputSR = arcpy.SpatialReference(wkid)
mapkey = "Maps"
result:dict = {mapkey:{}}
ap = ArcGISProject(aprxDocument)
for ma in ap.listMaps():
m:Map = ma
mapDef:CIMMap = m.getDefinition("V3")
sr = arcpy.SpatialReference(mapDef.spatialReference["wkid"])
bookmarks:list = []
for bo in mapDef.bookmarks:
b:CIMBookmark = bo
cam:CIMViewCamera = b.camera
xMin = cam.x - cam.viewportWidth / 2
xMax = cam.x + cam.viewportWidth / 2
yMin = cam.y - cam.viewportHeight / 2
yMax = cam.y + cam.viewportHeight / 2
array:arcpy.Array = arcpy.Array()
array.add(arcpy.Point(xMin, yMin))
array.add(arcpy.Point(xMax, yMax))
polyline:arcpy.Polyline = arcpy.Polyline(array, sr).projectAs(outputSR)
extent:arcpy.Extent = polyline.extent
bookmark:dict = {"name":b.name, "extent":json.loads(extent.JSON)}
bookmarks.append(bookmark)
result[mapkey][m.name]=bookmarks
return result
aprxDocument:str = r"<Your Path>"
wkid:int = 4326
bookmarks = GetBookMarks3(aprxDocument, wkid)
bookmarks_string = json.dumps(bookmarks, indent=4)
print(bookmarks_string)
Thanks for the response, I stand corrected! This is very interesting. I have not explored Esri's CIM nearly enough, clearly.
To visualize this for myself, I took some derived bookmark extents (from your code, and using my own scratch APRX) and built them as polygons in a new feature class. Sure enough, the geometry of the new polygons matches the original camera (viewport? I might be confusing the terminology) at the time the bookmark was saved, taking into account the limitations on map size (on screen) based on surrounding windows like Table of Contents and/or docked Catalog panes.
As an example, the polygon on the left represents the extent of a bookmark saved with a normal, more wide-screen view of the map. The polygon on the right represents a bookmark that was saved when I expanded my docked toolbars way out, limiting the actual view of the map.
Thanks again for the reply.