Select to view content in your preferred language

Bookmarks not working after script with CIM objects

251
3
2 weeks ago
CordulaGöke
Frequent Contributor

I have a script to adjust the scale bar and grid as CIM objects. After I ran this script, the manual use of bookmarks is not working anymore. I cannot set bookmarks nor zoom to existing bookmarks.  Do I need to release the CIM objects, update or something else? When I close and reopen the map, everything is fine. I need to go manually through all bookmarks before export.

0 Kudos
3 Replies
CordulaGöke
Frequent Contributor

I just realized, when I simply go to the last extent, the extent indicator in the overview map does not update.

0 Kudos
BrennanSmith1
Frequent Contributor

If you could share a code snippet that might help.  Are you using "CURRENT" or a file path to define the project variable?

0 Kudos
CordulaGöke
Frequent Contributor

@BrennanSmith1  good point .  First I thought it had solved itself, but after I zoomed and ran the rescaling of scalebar and grid several times, zoom to bookmarks stopped working. Yes I use aprx = arcpy.mp.ArcGISProject("CURRENT") in a jupyter notebook. It is the first project where I zoom manually through bookmarks and I also added the update_grid() only recently.

import arcpy
import os
import pandas as pd

aprx = arcpy.mp.ArcGISProject("CURRENT")

arcpy.env.workspace = os.path.dirname(aprx.filePath)
arcpy.env.addOutputsToMap = False
 
def update_scalebar():
    # Get the layout's CIM definition
    lyt_cim = lyt.getDefinition("V3")
    mf_camera_scale = mf.camera.scale

    for elm in lyt_cim.elements:
        if elm.name == "Scale Bar":
            elm.unitLabel = "km"
            elm.labelFrequency = "Divisions"
            elm.division = round(mf_camera_scale / 80000, 0)
            elm.divisions = 2
            elm.subdivisions = 2

    # Apply the updated CIM definition back to the layout
    lyt.setDefinition(lyt_cim)

 

def update_grid():    
    mf_camera_scale=mf.camera.scale
    minute = 1 / 60
    # Standard intervals in degrees
    standard_intervals = [1, 2, 5, 10, 15, 30]  # in minutes
    standard_degrees = [m * minute for m in standard_intervals]
    
    # Estimate based on scale
    estimated_minutes = round(mf_camera_scale / 3000000 * 60) 
    estimated_degrees = estimated_minutes * minute
    
    # Find closest standard interval
    grid_interval = round(estimated_degrees,0)+min(standard_degrees, key=lambda x: abs(x - estimated_degrees))
    
    cim_lyt = lyt.getDefinition("V3")
    print(grid_interval)
    for elm in cim_lyt.elements:
        if elm.name == 'Map Frame':
            for grd in elm.grids:
                grd.isAutoScaled = False  # Ensure manual control
    
                for grdLn in grd.gridLines:
                    if grdLn.name == "Ticks":
                        if grdLn.gridLineOrientation == "EastWest":
                            grdLn.pattern.interval = grid_interval/2  # Latitude ticks
                        elif grdLn.gridLineOrientation == "NorthSouth":
                            grdLn.pattern.interval = grid_interval # Longitude ticks
                    if grdLn.name == "Labels":
                      if grdLn.gridLineOrientation == "EastWest":
                          grdLn.pattern.interval = grid_interval  # Latitude ticks
                      elif grdLn.gridLineOrientation == "NorthSouth":
                        grdLn.pattern.interval = grid_interval*2 # Longitude ticks
    
    lyt.setDefinition(cim_lyt)
lyt = aprx.listLayouts('Layout')[0]
mf = lyt.listElements("MAPFRAME_ELEMENT",'Map Frame')[0]

map_obj = mf.map
update_scalebar()
update_grid()

 

0 Kudos