To this point, we've talked about automating geoprocessing tools, updating GIS data, and reading text files. However, we've not covered anything about working with a Pro project file. There are many tasks that can be performed on a project file that are well-suited for automation. These include:
- finding and replacing text in a layout or series of layouts; for example, a copyright notice for 2018 becomes 2019;
- repairing layers that are referencing data sources using the wrong paths; for example, your map was sitting on a computer where all the data was in C:\data and now it is on a computer where all the data is in D:\myfolder\mydata.
- printing a series of maps or data frames;
- exporting a series of maps to PDF and joining them to create a "map book";
- making a series of maps available to others on ArcGIS Server.
Pro projects are binary files, meaning they can't be easily read and parsed using the techniques we covered earlier in this lesson. Prior to the release of ArcGIS Desktop 10.0, the only way to automate anything with a map document (Desktop's analog to the Pro project) was to use ArcObjects, which was challenging for beginners and required using a language other than Python. ArcGIS Desktop 10.0 introduced a mapping module for automating common tasks with map documents. The development of ArcGIS Pro led to a very similar module, though enough differences resulted such that a new mp module was created.
The arcpy.mp module
arcpy.mp is a module you can use in your scripts to work with Pro projects. Please take a detour at this point to read the Esri Introduction to arcpy.mp.
The most important object in this module is ArcGISProject. This tells your script which Pro project you'll be working with. You can obtain an ArcGISProject object by referencing a path, like this:
project = arcpy.mp.ArcGISProject(r"C:\data\Alabama\UtilityNetwork.aprx")
Notice the use of r in the line above to denote a string literal. In other words, if you include r right before you begin your string, it's safe to use reserved characters like the single backslash \. I've done it here because you'll see it in a lot of the Esri examples with arcpy.mp.
Instead of directly using a string path, you could alternatively put a variable holding the path. This would be useful if you were iterating through all the project files in a folder using a loop, or if you previously obtained the path in your script using something like arcpy.GetParameterAsText().
It can be convenient to work with arcpy.mp in the Python window in Pro. In this case, you do not have to put the path to the project. There's a special keyword "CURRENT" that you can use to get a reference to the currently-open project.
project = arcpy.mp.ArcGISProject("CURRENT")
Once you get a project, then you do something with it. Let's look at this example script, which updates the year in a layout text element, then exports the layout to a PDF, and scrutinize what is going on. I've added comments to each line.
# Create an ArcGISProject object referencing the project you want to update project = arcpy.mp.ArcGISProject(r"C:\GIS\TownCenter_2015.aprx") # Get layout lyt = project.listLayouts() # only 1 layout in project # Loop through each text element in the layout for textElement lyt.listElements("TEXT_ELEMENT"): # Check if the text element contains the out of date text if textElement.text == "GIS Services Division 2018": # If out of date text is found, replace it with the new text textElement.text = "GIS Services Division 2019" # Export the updated layout to a PDF lyt.ExportToPDF(r"C:\GIS\TownCenterUpdate_2016.pdf") # Clean up the MapDocument object by deleting it del mxd
The first line in the above example gets an ArcGISProject project object referencing C:\GIS\TownCenter_2015.aprx. The example then uses the ArcGISProject object's listLayouts() method to retrieve a Python list of the layouts saved in the project. This project happens to have just one layout. Getting a reference to that layout still requires using listLayouts(), but using  to get the first (and only) object from the list. The Layout object in turn has a listElements() method that can be used to retrieve a list of its elements. Notice that the script asks for a specific type of element, "TEXT_ELEMENT". (Examine the documentation for the Layout class to understand the other types of elements you can get back using the listElements() method.)
The method returns a Python list of TextElement objects representing all the text elements in the map document. You know what to do if you want to manipulate every item in a Python list. In this case, the example uses a for loop to check the TextElement.text property of each element. This property is readable and writeable, meaning if you want to set some new text, you can do so by simply using the equals sign assignment operator as in textElement.text = "GIS Services Division 2019"
The ExportToPDF method is very simple in this script. It takes the path of the desired output PDF as its only parameter. If you look again at the Layout class's page in the documentation, you'll see that the ExportToPDF() method has a lot of other optional parameters, such as whether to embed fonts, that are just left as defaults in this example.
The best way to learn arcpy.mp is to try to use it. Because of its simple, "one-line-fix" nature, it's a good place to practice your Python. It's also a good way to get used to the Python window in Pro, because you can immediately see the results of your actions.
Although there is no arcpy.mp component to this lesson's project, you're welcome to use it in your final project. If you've already submitted your final project proposal, you can amend it to use arcpy.mp by emailing and obtaining approval from the instructor/grading assistant. If you use arcpy.mp in your final project, you should attempt to incorporate several of the functions or mix it with other Python functionality you've learned, making something more complex than the "one line fix" type of script I mentioned above.
By now, you'll probably have experienced the reality that your code does not always run as expected on the first try. Before you start running arcpy.mp commands on your production projects, I suggest making backup copies.
Here are a few additional places where you can find excellent help on learning arcpy.mp:
- Zandbergen chapter 10. The mapping module has changed a fair bit from ArcMap to Pro, but I recommend that you skim this chapter to see the types of tasks that the module can address.
- The Mapping module book in the ArcGIS Pro Help
- Intro to Map Automation technical workshop from the 2019 Esri User Conference