I need to select from a group of scalebars. For example, I have a 1 mile scale bar for scale 1:24000 and a bar set to feet for 1:1200)
I had similar code working in ArcMap. I am trying to port to ArcPro.
#Here is a snippet of the relevant code
sb = self.find_scalebar(scale) # Using a scale 24000, find the scalebar element in the layout
default_scalebar_element.visible = True
if sb != default_scalebar_element:
default_scalebar_element.visible = False # Hide the default
# Move the desired scalebar into the layout
sb.elementPositionY = x
sb.elementPositionY = y
sb.visible = True # Make sure it's visible
print(scale, x, y, sb.elementPositionX, sb.elementPositionY)
Lines 7,8 SHOULD change the scalebar position. They don't, what gets printed in 10 is this
24000 21.87 16.6 26.18 16.6 <--- x value DID NOT CHANGE??
The scale bar is still off the printout, which is 18x24" so the above code successfully detects it needs to fix the scale (line 4), turns OFF the default scalebar but then fails to move the selected scalebar.
When running in a debugger, I can override the value after line 7 runs and push the value of X and voila! the scalebar appears. It's just lines 7,8 that fail.
WHY DOES IT FAIL? Very mysterious.
Running the script results in this
Running the script in the debugger and manually setting X results in this; no code was changed.
4000 21.87 16.6 21.87 16.6 <--- value from print statement shows the new setting forced in
To rule out unlikely interference from the debugger I ran it from the command line too. Still failed. I used ArcGIS Pro 3.2.2 and the standard unmodified conda environment arcgispro-py3
Solved! Go to Solution.
I found a workaround. Still no idea why setting X,Y fails but the workaround was pretty direct. I use CIM to copy the correct settings into the scalebar that shows on the map.
default_scalebar_element = self.scalebars['Scalebar Default']
sb = self.find_scalebar(scale)
default_scalebar_element.visible = True
if sb != default_scalebar_element:
# Copy settings from desired scalebar
sb_cim = sb.getDefinition("V3")
df_cim = default_scalebar_element.getDefinition("V3")
df_cim.unitLabel = sb_cim.unitLabel
df_cim.units = sb_cim.units
default_scalebar_element.setDefinition(df_cim)
default_scalebar_element.elementWidth = sb.elementWidth
I want a non-programmer to be able to make changes to the scalebar settings without modifying the Python and I think this gets us close to that.
Setting the elementWidth in line 11 works for some reason 🙂 and is required so that the width of the bar works out to be exactly one mile.
I found a workaround. Still no idea why setting X,Y fails but the workaround was pretty direct. I use CIM to copy the correct settings into the scalebar that shows on the map.
default_scalebar_element = self.scalebars['Scalebar Default']
sb = self.find_scalebar(scale)
default_scalebar_element.visible = True
if sb != default_scalebar_element:
# Copy settings from desired scalebar
sb_cim = sb.getDefinition("V3")
df_cim = default_scalebar_element.getDefinition("V3")
df_cim.unitLabel = sb_cim.unitLabel
df_cim.units = sb_cim.units
default_scalebar_element.setDefinition(df_cim)
default_scalebar_element.elementWidth = sb.elementWidth
I want a non-programmer to be able to make changes to the scalebar settings without modifying the Python and I think this gets us close to that.
Setting the elementWidth in line 11 works for some reason 🙂 and is required so that the width of the bar works out to be exactly one mile.