Python and ArcGIS Pro
This tutorial will give a brief introduction to the use of the Python programming language in ArcGIS Pro.
Python is an cross-platform, open-source, general purpose programming language developed by Dutch programmer Guido van Rossum and first released in 1991. Compared to many other computer languages, Python is comparatively easy to use and is commonly used for interacting with and customizing software.
ArcPy is a module that provides functions, classes, and methods for performing "geographic data analysis, data conversion, data management, and map automation with Python" (ESRI 2022).
There are some significant limits to what you can do with ArcPy, and it is primarily useful for automating detailed, repetitive, or tedious tasks (Zandbergen 2020, pp 356).
Python code can be executed in a variety of different ways in an ESRI environment:
- Python window commands
- Python window scripts
- Standalone scripts
- Notebook Scripts
- Toolbox Scripts
- ArcGIS API
Python Window Commands
The ArcGIS Pro Python window allows a user to type in and run individual Python commands.
You start the Python window from Analysis, Python, Python window.
In this example:
- The ArcGISProject() function returns a reference to an ArcGIS Pro project. Passing "current" when the function is called in the Python window returns a reference to the project currently being viewed in ArcGIS Pro.
- The listMaps() method returns a list of maps in the project. Because this project only has one map, we select the first (and only) element of the list to get a reference to that map.
- The addDataFromPath() method adds a feature service as a layer. This particular layer is created from a feature service of US power plants from the US Department of Energy that has been published in the University of Illinois ArcGIS Online organization.
aprx = arcpy.mp.ArcGISProject('current') streetmap = aprx.listMaps()[0] streetmap.addDataFromPath("https://services.arcgis.com/GL0fWlNkwysZaKeV/arcgis/rest/services/Minn_2020_Power_Plants/FeatureServer")
Python Window Scripts
Tasks in ArcGIS Pro commonly require sequences of operations, and those operations can be performed using sequences of Python expressions. A script is a sequence of commands collected into a single text file that can be run by the software. Scripts can be used to organize complex sequences of commands (workflows) and automate tedious tasks.
The advantages of using scripts instead of the ArcGIS Pro graphical user interface (GUI) include:
- Reusable: If you need to rerun a sequence of steps on new or updated data, it is much easier to just rerun a script rather than have to go through complex GUI interactions multiple times.
- Reproducible: If you need to debug or validate the results from a complex sequence of steps, rerunning a script can reproduce those steps exactly, as opposed to interactions with a GUI that can be difficult to remember and are error prone.
- Extensible: When needs change, scripts can be easily modified to meet those new needs.
- Descriptive: Scripts provide documentation of the steps required to perform a task.
However, there are disadvantages as well:
- Specialized knowledge: Scripting requires specialized knowledge both of the scripting language and the software environment in which those scripts are used.
- Obfuscation: Scripts are often written in a confusing and inefficient manner, especially by novice writers. The code can obscure the underlying logic.
- Software and version dependence: Scripts are dependent on the libraries they call. When the underlying software changes, the scripts may need to be modified. This can disincentivize keeping software up to date, and can be expensive and time consuming if the original script writer is no longer with your organization.
Script files can be executed from the ArcGIS Pro Python console by right-clicking on the console prompt line and selecting Load Data.
Standalone Scripts
You may encounter situations where you would like to be able to run a script without having to go through the effort of starting ArcGIS Pro and clicking buttons to run your script. An example might be an automation of a the same task on multiple files.
Notebook Scripts
Notebooks are interleaved cells of code and descriptive text that are useful for presenting the results of data analyzed with Python code.
Notebooks are good places to put scripts that are specific to particular projects, since notebooks are saved with project packages.
Toolbox Scripts
Scripts that represent generalizable tasks can be incorporated into tools with parameters that allow execution in the same manner as native tools from the ArcGIS Pro toolboxes.
Toolboxes are good places to put scripts that can be useful across multiple different projects.
ArcGIS API
ArcGIS API for Python is a "library for performing GIS visualization, analysis, data management, and GIS system administration tasks" (ESRI 2022).
- Behind the scenes, this libraries utilize the ArcGIS Rest API for interacting with ArcGIS Online and ArcGIS Enterprise servers.
- Accordingly, you use the ArcGIS API for Python when working with internet-based services and applications rather than when working with ArcGIS Pro desktop software.
- A similar library for JavaScript is the ArcGIS API for JavaScript.
Example Code
The following is sequence of Python code that demonstrates usage of ArcPy functions.
The imagined scenario is that you work for a city department of transportation. The DOT is planning to resurface a street and wants to mail flyers that businesses and residential building managers can post so customers and residents can plan for disruptions to access. You need to create a list of addresses of businesses and residences on or near the construction project.
Acquire the Data
The data used in this example will be address points and street midlines from the Lake County, Illinois Open Data and Records Hub https://data-lakecountyil.opendata.arcgis.com/.
- Search for and Download Address Points. This format should be a Shapefile to make import easier. Lake County uses a Web Mercator projection for their data, which can be confusing with CSV files.
- Search for and Download Street Centerlines. The format should be Shapefile to fully represent line features.
- Use the Windows Explorer to find the Downloads directory.
- Open the .zip archives and extract the CSV and shapefile.
- Right click on the Downloads directory to get the full file path. In this example, it is located on a network drive that begins with an IP address.
Start a New Project
All the source and output data will be kept together in a single project.
- From the opening screen start a new project with a new map.
- Give the project a meaningful name.
- Under Project, Options find the project directory so you can know where to place the script.
Start the Script
Start a new script and save it into the main project directory.
- Open a Python editor. This example uses the standard IDLE editor included with Python installation.
- Start the script with contain comment lines giving the purpose of the script, the programmer (you), and the last revision date. This metadata is important so that you or someone who inherits this script will know what it does in the future.
- Save the script in the project folder.
- The first code line should load the ArcPy library.
- Create a variable for the current project using the ArcGISProject() function.
- Create a variable for the first map in the project. If you have multiple maps, can add a name parameter to the listMaps() function call.
# Example join script # Michael Minn - 8/31/2022 import arcpy aprx = arcpy.mp.ArcGISProject('current') street_map = aprx.listMaps()[0]
Import the Shapefiles
Shapefiles can be added to maps by passing the name of the .shp file in the shapfile to the map function addDataFromPath().
- The data_path you use will be dependent on the location of your downloaded shapefiles.
- Note that because Python uses the backslash (\) as an escape character, you need to use double backslashes in place of the normal single backslashes in your file path names.
- We also give the layer a more concise name than the shapefile name.
data_path = "\\\\192.168.100.3\\DeptUsers\\minn2\\Downloads" street_path = data_path + "\\Street_Centerlines.shp" street_layer = street_map.addDataFromPath(street_path) street_layer.name = "streets" addr_path = data_path + "\\Address_Points.shp" addr_layer = street_map.addDataFromPath(addr_path) addr_layer.name = "addresses"
Select the Join Feature
A definition query is "a request that examines feature or tabular attributes based on user-selected criteria and displays only those features or records that satisfy the criteria" (ESRI 2022).
This definition query selects the 700 - 900 blocks of North Butrick Street.
The FromAddr_L and ToAddr_L fields in this data set indicate the range of street numbers on the left side of each street segment feature. The exact names of these parameters may vary depending on your data source.
street_layer.definitionQuery = "(WHOLE_NAME = 'N Butrick St') " \ "AND (FromAddr_L >= 700) " \ "AND (ToAddr_L <= 999) " \ "AND (IncMuni_L = 'WAUKEGAN')"
Select and Export
The SelectLayerByLocation() tool can be used to select the address points (addr_layer) within 50 meters of the construction site (the selected street segments in the street_layer).
The ExportFeatures() tool can them be used to export the selected address points to a new feature class. By default, the out_features parameter (second parameter) is placed in the project database under the given name.
The listLayers() function is then used to find the original address point layer and hide it so that only the new layer of affected addresses is visible.
arcpy.management.SelectLayerByLocation(addr_layer, "WITHIN_A_DISTANCE", street_layer, "50 meters") arcpy.conversion.ExportFeatures(addr_layer, "affected") street_map.listLayers("addresses")[0].visible = 0
Export the Attributes
You can export the attribute table for the affected locations to a .csv file of addresses that can be imported into Word to create cover letters or mailing labels.
arcpy.conversion.TableToTable("affected", data_path, "affected.csv")
Google Street View
If you want to view the area in Google Maps street view for ground truthing, Right-click on the map and select Copy Coordinates and copy those coordinates into the Google Maps search bar.
Load Code
Although the videos above demonstrate running sets of commands interactively from the console, the point of collecting them in a script is to be able to run them directly from the file.
You can run an entire file from the Python wiindow by right-clicking on the console prompt, selecting Load Code, and pressing the enter key when the commands load.
Notebook
Although notebooks are commonly used for presenting data analysis, they can also be used to store special purpose scripts so they are saved as part of project packages.
- Start a new notebook with Insert, New Notebook.
- Enter the code into the top cell.
- Press the Run button to run the code.
- A completion message will be displayed at the bottom of the notebook when the code completes
- Notebooks are saved in the project and can be accessed through the Catalog Pane.
Standalone Scripts
There may be occasions where you would like to be able to run scripts without having to start and monitor ArcGIS Pro.
While the simple script used in this tutorial is not a particularly useful example, a few tweaks to the code will allow it to be run as a "standalone" script.
- Since the script is being run outside of ArcGIS Pro, there is no current project. So the call to ArcGISProject() will need to specify an existing .aprx file. The project is only used as a workspace and is not modified, but ArcPy cannot create a temporary project, so an existing project will need to be used.
- You can find the path to the .aprx file by right-clicking on the .aprx file and showing the Properties.
- Since we are not modifying the project, the ExportFeatures() of the selected addresses will need to go to an explicitly specified shapefile rather than the project database.
- Likewise, when exporting the .csv with TableToTable() the shapefile must be specified as the source table.
# Standalone join script # Michael Minn - 8/31/2022 import arcpy aprx = arcpy.mp.ArcGISProject('\\\\192.168.100.3\\DeptUsers\\minn2\\Documents\\ArcGIS\\Projects\\Street Work\\Street Work.aprx') street_map = aprx.listMaps()[0] data_path = "\\\\192.168.100.3\\DeptUsers\\minn2\\Downloads" street_path = data_path + "\\Street_Centerlines.shp" street_layer = street_map.addDataFromPath(street_path) street_layer.name = "streets" addr_path = data_path + "\\Address_Points.shp" addr_layer = street_map.addDataFromPath(addr_path) addr_layer.name = "addresses" street_layer.definitionQuery = "(WHOLE_NAME = 'N Butrick St') AND (FromAddr_L >= 700) AND (ToAddr_L <= 999)" arcpy.management.SelectLayerByLocation(addr_layer, "WITHIN_A_DISTANCE", street_layer, "50 meters") arcpy.conversion.ExportFeatures(addr_layer, data_path + "\\affected.shp") arcpy.conversion.TableToTable(data_path + "\\affected.shp", data_path, "affected.csv")
When ArcPy is installed, a version of IDLE with an appropriate run time environment is also installed that will allow "standalone" scripts to run outside of ArcGIS Pro.
- Right click on the script and select Edit with IDLE (ArcGIS Pro), and then run the module.
- In this case we can monitor the Downloads directory to observe the locking of the source shapefiles, the creation of the new shapefile, and the export of the .csv file.
- The lock files will be deleted when Python shell is restarted or closed.