|
DOC
|
@MarcoBoeringa I jumped on this as soon as it was brought to my attention. I didn't try the other blocks of code but they were using variables and settings that had missing context, therefore, I focused on your comment concerning the use of a dict to set label class CIM properties. Testing layer files is easy enough and I will try that but your comment "there is a *lot* more going on" could be the missing pieces. We can't debug until we can reproduce the issue.
... View more
2 weeks ago
|
0
|
0
|
945
|
|
DOC
|
@MarcoBoeringa I did the best I could to simulate your scenario without having your data or complete scripts. I can NOT reproduce. Everything works on the background or foreground threads. I can talk with the labeling team to see if the smoking gun you suggest could have been caused by changes made during 3.6 development. Here is the script ran from a script tool. It ran against a single polygon feature layer with 10 label classes. I only set the priorities for half of them and set the other half using an incremented value. import arcpy
if __name__ == "__main__":
p = arcpy.mp.ArcGISProject('current')
m = p.listMaps('Map')[0]
l = m.listLayers('States_WithRegions')[0]
l_cim = l.getDefinition('V3')
labelPriorityByLayerDict = {'New England' : 1, 'Pacific': 2, 'Mountain' : 3, 'South Atlantic' : 4, 'West North Central' :5}
i = 6
for cimLabelClass in l_cim.labelClasses:
if type(cimLabelClass).__name__ == "CIMLabelClass":
try:
if cimLabelClass.priority == -1:
if cimLabelClass.name in labelPriorityByLayerDict:
before = cimLabelClass.priority
cimLabelClass.priority = labelPriorityByLayerDict[cimLabelClass.name]
arcpy.AddMessage(f'Changing {cimLabelClass.name} from {str(before)} to {cimLabelClass.priority}')
else:
before = cimLabelClass.priority
cimLabelClass.priority = i
arcpy.AddMessage(f'Changing {cimLabelClass.name} from {str(before)} to {cimLabelClass.priority}')
i += 1
except:
arcpy.AddWarning("*** WARNING ***: Failed to set label ranking")
pass
l.setDefinition(l_cim) It would be really helpful to know if the script above fails for you against your data after making the necessary changes. Jeff - arcpy.mp Team
... View more
2 weeks ago
|
0
|
0
|
1010
|
|
DOC
|
@MarcoBoeringa I appreciate your effort reporting your findings but I don't have enough to reproduce. The snippet of code you most recently provided is not complete. I prefer not to guess. I modified the original code you provided to GET the labelclass.name and it is returning values as expected. The regression could be caused by a combination of events. Is there any way you can provide a more complete, simplified and reproducible ppkx with the script tool. My email is jbarrette@esri.com Jeff - arcpy.mp Team
... View more
2 weeks ago
|
0
|
0
|
1044
|
|
DOC
|
@MarcoBoeringa , I'm on the arcpy.mp team and tested your label class CIM edits / Foreground scenario and was NOT able to reproduce on Win 11. I even tried in on a Win10 machine this morning. I tried old projects that had tbx files and a new 3.6 project with atbx files. Each project has a map with a feature layer with multiple label classes. Each label class had a SQL Query that shows state names for different regions. The following code is part of a script tool and ran fine in all cases in the background and in the foreground. I think its identical to your script unless you have more lines that might be part of the issue. import arcpy
if __name__ == "__main__":
p = arcpy.mp.ArcGISProject('current')
m = p.listMaps('Map')[0]
l = m.listLayers('States_WithRegions')[0]
l_cim = l.getDefinition('V3')
i = 1
for cimLabelClass in l_cim.labelClasses:
if type(cimLabelClass).__name__ == "CIMLabelClass":
try:
#cimLabelClass.priority = i
arcpy.AddMessage(cimLabelClass.priority)
except:
arcpy.AddWarning("*** WARNING ***: Failed to set label ranking")
pass
i += 1
l.setDefinition(l_cim) If you run exactly this code, you still see the issue? Can you think of anything special about your layer, the label classes, etc, that could be unique. Jeff - arcpy.mp team
... View more
2 weeks ago
|
0
|
0
|
1121
|
|
POST
|
I know this is a really old post but I was going through some old emails, etc and came across this thread. I've helped people address this issue (differently than AlterField) and want to paste that code here as an option for people to try. Basically, if there are NO field descriptions (e.g., a layer was just added), then another option is to use MakeFeatureLayer. The MakeFeatureLayer result has the CIM properties. You make the changes and than copy those changes back to the original layer. There are pre3.4 and 3.4 and beyond options. def updateCIMFields(l, cimLyr):
fList = ["SQKM", "POP2001", "Shape_Length", "Shape_Area"]
for fd in cimLyr.featureTable.fieldDescriptions:
if fd.fieldName in fList:
fd.numberFormat.roundingOption = "esriRoundNumberOfDecimals"
fd.numberFormat.roundingValue = 0
fd.numberFormat.zeroPad = True
fd.numberFormat.useSeparator = True
l.setDefinition(cimLyr)
return cimLyr
p = arcpy.mp.ArcGISProject('current')
m = p.listMaps()[0]
lyr = m.listLayers('Provinces')[0]
lyr_cim = lyr.getDefinition('V3')
if len(lyr_cim.featureTable.fieldDescriptions) == 0: #NO CIM field info present
print('No CIM Field Info')
mkLyr = arcpy.management.MakeFeatureLayer(lyr)[0]
mkLyr_cim = mkLyr.getDefinition('V3')
mkLyr_cim = updateCIMFields(mkLyr, mkLyr_cim)
#Copy CIM information and remove temporary layer
#lyr_cim.featureTable.fieldDescriptions = mkLyr_cim.featureTable.fieldDescriptions ###for 3.3 and prior
#lyr.setDefinition(lyr_cim) ###for 3.3 and prior
lyr.pasteProperties(mkLyr, 'FIELD_PROPERTIES') ###for 3.4 and prior
m.removeLayer(mkLyr)
else: #CIM field info present
print('CIM Field Info Pre-Exists')
lyr_cim = updateCIMFields(lyr, lyr_cim)
lyr.setDefinition(lyr_cim) Jeff - arcpy.mp Team
... View more
2 weeks ago
|
0
|
0
|
48
|
|
IDEA
|
@Jeff-Reinhart thanks for your feedback! I'd like to get additional feedback if possible. First, anything that involves working with views via arcpy.mp, it is documented that these members only work for scripts that run within the application (in-process). "Views" really don't exist when referencing a project by path (out-of-process). Given that, we really try to limit the number of in-process only properties and methods. Our main focus is automation and less application customization but we recognize the needs. Second, currently we have ArcGISProject.closeViews() that takes an enum of project item types (i.e., maps, layouts, and reports). So in your "My Layout" example you could have something like: p = arcpy.mp.ArcGISProject("CURRENT")
lyt = p.listLayouts('My Layout')[0]
p.closeViews('LAYOUT') #This closes all layout views
lyt.openView() #This opens AND activates your view One of the limitations, in this example, is it closes all layout views, 'My Layout', 'Your Layout' 'Everybodys Layout' etc. Probably more of an issue with Map items. But what if we extended closeViews() to include a wildcard filter: p.closeViews('LAYOUT', wildcard='My Layout') #This would close any views specific to My Layout The above would close all instances of My Layout but then your would call openView to open AND activate it. A possible problem with isOpen is the layout may be open but it might NOT be active. That would require we add additional in-process only methods like .makeActive, which again, we would like to avoid.
... View more
3 weeks ago
|
0
|
0
|
166
|
|
POST
|
@BinhLe2 could you provide a little more detail, screenshots, and perhaps more of your script? There are probably a number of ways to approach this, but the summary doesn't provide enough context. A map series page order is based on an internal index number based on the sort field. If you export a map series (with or without Python) the pages should follow that order. Are you exporting to a single file, multiple files? Again, having more context will help us identify if there is a bug. Jeff - arcpy.mp team
... View more
11-14-2025
10:24 AM
|
0
|
0
|
90
|
|
IDEA
|
Hello @JamesPoeschel , As a stop gap prior to this idea being considered by the layout team, you could use a simple Python script to automate the process. Paste the following in the Python window (be sure to edit the layout name): p = arcpy.mp.ArcGISProject('current')
lyt = p.listLayouts('LAYOUT NAME GOES HERE')[0]
for txt in lyt.listElements('text_element'):
txt.name = txt.text Note, this would need to be tested very thoroughly with your own layouts. A few problematic situations that immediately come to mind are 1) long paragraph text elements, 2) dynamic text elements, and 3) text elements that have identical strings will still be forced to have unique names etc. Jeff - arcpy.mp team
... View more
10-16-2025
12:36 PM
|
0
|
0
|
190
|
|
IDEA
|
Based on the responses in the thread and knowing that we are not able to close a specific active view for reasons described above, we are going to close this idea until we get a well defined use case. Jeff - arcpy.mp team
... View more
08-25-2025
01:24 PM
|
0
|
0
|
378
|
|
IDEA
|
@wtfineberg I believe there is a misunderstanding between changing a Map's default Extent property vs changing the extent of an active MapView. Map.defaultCamera - Modifying the defaultCamera will not affect an existing view. This property is only applied when a new MapView is opened or a new MapFrame is inserted into a layout. You can change the extent of an active MapView using the Camera object, not the defaultCamera property. I've modified the code above slightly to change the active MapView's extent. aprx = arcpy.mp.ArcGISProject('current')
map_view = aprx.activeView
layer = map_view.map.listLayers('GreatLakes')[0]
arcpy.management.SelectLayerByAttribute(layer, "NEW_SELECTION", f"NAME = 'Lake Superior'")
map_view.camera.setExtent(map_view.getLayerExtent(layer, True)) Notice, I'm using activeView, NOT activeMap. ActiveView returns a MapView object whereas activeMap returns a Map object. It is from the active view that I get the associated map and then reference a layer. If I were to then type: m = aprx.listMaps('Map')[0]
m.defaultCamera = map_view.camera The next time I go to open a new map view for the 'Map', it will be zoomed to Lake Superior. Jeff
... View more
08-25-2025
01:09 PM
|
0
|
0
|
238
|
|
IDEA
|
I marked this as Already Offered in that there is an arcpy.mp sample that accomplishes this and this is unlikely to go into the core product due to how specialized and custom the requirement is. Below is a link to a sample. It extends map series and includes layout element into the same table that drives the map series. The placement of layout elements are simply placed in fields in a table. https://www.arcgis.com/home/item.html?id=82b99b5593e54e57b740e3898fb14c5f Please review and I hope it helps. Jeff - arcpy.mp and Layout SDK teams
... View more
06-27-2025
08:02 AM
|
0
|
0
|
403
|
|
POST
|
@JasonBennett I'm glad it worked. Comparing the before and after is super useful especially if you minimize the changes to the absolute necessary steps between saves. Sometime you might see new objects are introduced and that is when you would might need to use CreateCIMObjectFromClassName. It is covered in this topic: https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/python-cim-access.htm Jeff
... View more
06-05-2025
11:20 AM
|
1
|
0
|
754
|
|
POST
|
Hello @JasonBennett , I just tried the following and it works for me. I find the best approach to learning where stuff is persisted in the CIM is to create a before and after result that can be compared using an application that shows differences (e.g. WinMerge). So what I did first was export my Best Fit map series to a PAGX file. Then I changed my options to use Center and Maintain Scale and exported to a PAGX again with a different name. I use WinMerge to compare the two text files (tip, if you rename the *.pagx to *.json, the formatting may look cleaner). When I compare the differences, I see that the map series CIM has a "extentOptions" property and I changed it from "BestFit" to the "ExtentCenter" enum. Then I updated the map series mapframe camera scale property. Here is the code I used to make the changed to my map series. #Reference project and layout
p = arcpy.mp.ArcGISProject('current')
lyt = p.listLayouts('*_MS')[0]
#First, change the map series extent option
ms = lyt.mapSeries
ms_cim = ms.getDefinition('V3')
ms_cim.extentOptions = 'ExtentCenter' #Center and Maintain Scale
ms.setDefinition(ms_cim)
#Now change the scale of the map frame (via the camera object)
mf = lyt.listElements('mapframe_element', 'Map Frame')[0]
cam = mf.camera.scale
cam.scale = 5000000 I hope this was helpful, Jeff - arcpy.mp team
... View more
06-05-2025
09:21 AM
|
3
|
1
|
762
|
|
POST
|
@StephanieStedman have you tried the following ArcGISProject members added at Pro 3.3. - listToolboxes - updateToolboxes() https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/arcgisproject-class.htm Adding folder connections and databases work the same. Code Sample 4 in the link above. A very simplified for adding a single toolbox is: p = arcpy.mp.ArcGISProject('current')
tbxs = p.toolboxes
tbxs.append({'toolboxPath': r"C:\Temp\MyToolbox.atbx, 'isDefaultToolbox': False})
p.updateToolboxes(tbxs)
You could even start with an empty toolbox dictionary but be sure to make one (and only one) of them the default toolbox. Jeff - arcpy.mp team
... View more
05-14-2025
01:19 PM
|
1
|
1
|
692
|
|
POST
|
Please refer to the solution provided under the following idea: https://community.esri.com/t5/arcgis-pro-ideas/vary-symbology-by-rotation-accessible-by-arcpy/idi-p/939228 Jeff - arcpy.mp and Layout (SDK) teams
... View more
05-08-2025
10:37 AM
|
0
|
0
|
364
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 06-05-2025 11:20 AM | |
| 3 | 06-05-2025 09:21 AM | |
| 1 | 05-14-2025 01:19 PM | |
| 2 | 04-24-2025 07:54 AM | |
| 1 | 03-15-2025 07:19 PM |
| Online Status |
Offline
|
| Date Last Visited |
Friday
|