Table of Contents
Introduction
The Cartographic Information Model (CIM) is a map content specification for cartographic descriptions of GIS datasets and Project components in ArcGIS Pro. Essentially, it is the JSON that represents specifications for maps, scenes, layouts, layers, symbols, and styles in ArcGIS Pro. The best way to view these JSON specification is to save an element to a .*x file format such as .lyrx or .mapx, and then open the file in a viewer such as Notepad or Notepad++. It is necessary to open these files and get an understanding of the structure of the JSON in these files in order to understand how you access and update the properties for an element, such as allowing the assignment of unique numeric IDs for sharing web layers.
In order to publish layers from a Map in ArcGIS Pro to ArcGIS Online, you must have unique numeric IDs assigned to each layer of you will get the following error below when you go to share/publish. What a nightmare if you want to be more efficient and programmatically publish your data but a lot of your Maps have not got unique numeric IDs set! Here comes ArcPy and the CIM to the rescue.
When you export a Map as a .mapx file, you can change the .mapx to .json, and if your viewer has syntax highlighting for JSON like the example below using Notepad++, you can better navigate through the CIM for a better understanding.
Here is the documentation for CIM namespaces.
ArcGIS Pro Definition Query Masterclass with ArcPy & Python
Unlock the power of Definition Queries in ArcGIS Pro through this comprehensive course that dives deep into the intricacies of managing and utilizing definition queries with spatial data using ArcPy and Python scripting. Definition Queries provide a dynamic way to filter and display specific subsets of your data, enabling you to create more insightful maps and analyses. In this course, we will focus exclusively on Definition Queries, covering their creation, modification, and application through hands-on exercises and real-world scenarios. Accredited by the Association for Geographic Information (AGI) for 1 CPD point.
How to access the CIM definition for a Layer with ArcPy
We can use a map object’s getDefinition() function to return a CIM definition. We need to supply the cim_version as a parameter to the getDefinition() function. For ArcGIS Pro 2.x we use “V2” and “V3” for ArcGIS Pro 3.x. The example for this blog post relate to ArcGIS Pro 3.2. The below code snippet returns the CIM definition for a map called “FDM Exploring the Map”.
import arcpy
aprx_path = r""
aprx = arcpy.mp.ArcGISProject(aprx_path)
## access a Map using listMaps to return a list of map objects
## index 0 returns the first map object returned in the list.
m = aprx.listMaps("FDM Exploring the Map")[0]
## use getDefinition to get the CIM
map_cim = m.getDefinition("V3")
Where in the CIM definition is the property of interest?
The CIM for a Map object has a property called “useServiceLayerIDs” that is only present when the Allow assignment of unique numeric IDs for sharing web layers is checked on. Otherwise it is not present in the CIM definition.
TIP: Manually alter the allow assignment of unique numeric IDs checkbox in the Mam properties in ArcGIS Pro save as a .mapx file and open as JSON and look for the “useServiceLayerIDs” property.
"useServiceLayerIDs" : true
Updating CIM definition with Python
The previous Python code snippet showed us how to access the CIM via the getDefinition() function, we will pick up from there. For our first example, we are going to simply change the stroke and fill colors. We use the layer object setDefinition() to update the layer.
## set the useServiceLayerIDs property to True
map_cim.useServiceLayerIDs = True
## save the new CIM definition using the Map object setDefinition()
m.setDefinition(map_cim)
## save the APRX
aprx.save()
Now go forth and iterate through all those APRX files and all those Maps and allow the assignment of unique numeric IDs to make your publishing life easier!
Leverage ArcPy for geospatial data management workflows within ArcGIS Pro. Learn the fundamentals of utilising ArcGIS Pro geoprocessing tools with ArcPy for data management, conversions, and analysis. This course is packed with amazing content that will help you discover the power of automating tasks within the ArcGIS Pro environment. Take your ArcPy skills from beginner to snake charmer. A little code goes a long way, a little ArcPy provides you with an in-demand skill. Sign up now for our highly rated course.
All the code in one place
You can find the entire code workflow below with links to important components in the documentation that were used.
import arcpy
################################################################################
## Esri Documentation:
## https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/arcgisproject-class.htm
## https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/map-class.htm
## https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/python-cim-access.htm
##
##
## ArcGIS Pro Version 3.2.0
##
################################################################################
################################################################################
## INPUT REQUIRED #############################################################
aprx_path = r""
map_name = ""
################################################################################
## ACCESS ARCGIS PRO COMPONENTS ###############################################
aprx = arcpy.mp.ArcGISProject(aprx_path)
## access a Map using listMaps to return a list of map objects
## index 0 returns the first map object returned in the list.
m = aprx.listMaps(map_name)[0]
################################################################################
## ACCESS ATHE MAP CIM ########################################################
## use getDefinition to get the CIM
map_cim = m.getDefinition("V3")
################################################################################
## ALLOW ASSIGNMENT OF UNIQUE NUMERIC LAYER IDS ###############################
## set the useServiceLayerIDs property to True
map_cim.useServiceLayerIDs = True
################################################################################
## UPDATE THE CIM #############################################################
## save the new CIM definition using the Map object setDefinition()
m.setDefinition(map_cim)
################################################################################
## SAVE THE APRX ###### ########################################################
## save the APRX
aprx.save()
################################################################################
print("\nSCRIPT COMPLETE")