Zoom to Extent in ArcGIS Pro with ArcPy: What you need to know.

In this blog post we will assess using ArcPy to zoom to a layer or a selection for

  • a MapFrame in a Layout view, and
  • a Map view

If you are interested in learning ArcPy, check out this course!

We are using ArcGIS Pro 3.2

Zoom to Layer in a Layout MapFrame

For this example, we have one layer called Ireland & UK, a layout named Map Layout, with a MapFrame named Main MapFrame, and our Map view is also named Ireland & UK. We can see that the map is zoomed out and we want to zoom in to the entire layer.

From the Analysis tab > press the dropdown arrow beside Python > select Python Window

The Python Interpreter window will open. We need to use ArcPy to create an ArcGISProject object which gives us access to the open APRX. From this ArcGISProject object we can access the Map Layout as a Layout object, and from our Layout object we an access a MapFrame object which has a Map object as a property and from that Map object we can access our Layer object for which we want to zoom to. You got all that yeah! Its in the code below.

## access the open APRX
aprx = arcpy.mp.ArcGISProject("CURRENT")

## access our layout named Map Layout
lyt = aprx.listLayouts("Map Layout")[0]

## access the MapFrame named Main Mapframe
mf = lyt.listElements('MAPFRAME_ELEMENT', "Main Mapframe")[0]

## access the Ireland & UK layer using the map from the MapFrame and the map listLayers method.
lyr = mf.map.listLayers("Ireland & UK")[0]

We will use the Minimum Bounding Geometry geoprocessing tool to get a polygon envelop that represents that area to zoom to. We supply in our layer object which represents the Ireland & UK layer and we will use the memory workspace to store the temporary bounding feature.

bbox = arcpy.management.MinimumBoundingGeometry(lyr, "memory\\bbox", "ENVELOPE", "ALL")

Although we are using the memory workspace to create a temporary feature class, the information is added to our map as shown below.

We want to get the extent object for this bounding box. We can use Python list comprehension and the SearchCursor to get the geometry object using the SHAPE@ token, and we use the extent property for the geometry to retrieve the extent object.

extent = [row[0].extent for row in arcpy.da.SearchCursor(bbox, "SHAPE@")][0]

We will apply the extent to the MapFrame camera object using the camera setExtent() method, and to clean up we delete the temporary bounding box layer.

## zoom to the extent of the bounding box
mf.camera.setExtent(extent)

## delete the bounding box geometry
arcpy.management.Delete(bbox)

Our MapFrame is now zoomed to our layer.

Zoom to Selection in a Layout MapFrame

Very similar workflow except this time we will place a selection on the layer using the Select Layer by Attribute tool.

## access the open APRX
aprx = arcpy.mp.ArcGISProject("CURRENT")

## access our layout named Map Layout
lyt = aprx.listLayouts("Map Layout")[0]

## access the MapFrame named Main Mapframe
mf = lyt.listElements('MAPFRAME_ELEMENT', "Main Mapframe")[0]

## access the Ireland & UK layer using the map from the MapFrame and the map listLayers method.
lyr = mf.map.listLayers("Ireland & UK")[0]

## make a selection
arcpy.management.SelectLayerByAttribute('Ireland & UK', 'NEW_SELECTION', "NAME = 'Ireland'")

Get the Minimum Bounding Box.

bbox = arcpy.management.MinimumBoundingGeometry(lyr, "memory\\bbox", "ENVELOPE", "ALL")

Because we have a selection made, the tool honours the selection and creates the BBOX for Ireland as shown below.

We get the extent object from the bounding box geometry, set the camera object to match the extent, delete our temporary bounding box layer, and optionally, we can remove the selection from the layer.

## get the extent object of the bbox polygon
extent = [row[0].extent for row in arcpy.da.SearchCursor(bbox, "SHAPE@")][0]

## zoom to the extent of the bounding box
mf.camera.setExtent(extent)

## delete the bounding box geometry
arcpy.management.Delete(bbox)

## optionally clear the selection
lyr.setSelectionSet()

Ok, you do not need the Minimum Bounding Box.

I just liked that you could visualize the extent really easy, and you we will need it for attempting to zoom in a Map view. Here’s a alternative that I recommend using the MapFrame getLayerExtent() method.

## access the open APRX
aprx = arcpy.mp.ArcGISProject("CURRENT")

## access our layout named Map Layout
lyt = aprx.listLayouts("Map Layout")[0]

## access the MapFrame named Main Mapframe
mf = lyt.listElements('MAPFRAME_ELEMENT', "Main Mapframe")[0]

## access the Ireland & UK layer using the map from the MapFrame and the map listLayers method.
## only required if making a selection
lyr = mf.map.listLayers("Ireland & UK")[0]

## optionally make a selection
arcpy.management.SelectLayerByAttribute('Ireland & UK', 'NEW_SELECTION', "NAME = 'Ireland'")

## get the extent using the MapFrame getLayerExtent() method which honours a selection if one made
extent = mf.getLayerExtent(lyr)

## update the camera object
mf.camera.setExtent(extent)

## optionally remove any selection made
lyr.setSelectionSet()

With ArcPy, there are generally multiple ways to achieve the same goal. Once you get something that works you can refactor code to something more efficient as you learn more about ArcPy.

Zoom with a Map view

Unfortunately there is still no direct way to zoom, pan, or change the general extent of a Map view in ArcGIS Pro using ArcPy (unless it sneaked in without me knowing), however, here is some information to digest; each Map view has a default extent, this is the extent that the map displays when the map is opened. We can set this default extent, and in a workaround, albeit not the most supreme of workarounds, it is a workaround nonetheless. Also to note, we do not have access to a nice handy getLayerExtent() method for the Map object like we do with the MapFrame object. You can of course first access a MapFrame and get a layer extent and then apply it as the extent in the workflow below rather than using the minimum bounding box, however, they are both extra steps to get your extent object, and not your only two choices, but probably the better of all the choices.

Below is my Ireland & UK map and the default extent that it opens up to.

We can get the default extent via the camera object.

## access the open APRX
aprx = arcpy.mp.ArcGISProject("CURRENT")

## access the map object
m = aprx.listMaps("Ireland & UK")[0]

## get the current extent from the Map camera
extent = m.defaultCamera.getExtent()

## print extents to screen
extent.XMin, extent.YMin, extent.XMax, extent.YMax

The Esri documentation for the camera class clearly states that it cannot update the extent of the Map view in-situ.

Let’s update the default camera to a new extent.

## access our layer of interest
lyr = m.listLayers("Ireland & UK")[0]

## get the bounding box
bbox = arcpy.management.MinimumBoundingGeometry(lyr, "memory\\bbox", "ENVELOPE", "ALL")

## get the extent object of the bounding geometry
extent = [row[0].extent for row in arcpy.da.SearchCursor(bbox, "SHAPE@")][0]

## update the defaultCamera
m.defaultCamera.setExtent(extent)

Delete our temporary bounding box.

arcpy.management.Delete(bbox)

Close all Map views. This is why this is not the greatest of workarounds, if you have multiple Maps open they will all close. It would be nice to have the option to just close a Map view of choice, well, even better if we could just have a way to change the extent of our Map view in the first place.

aprx.closeViews('MAPS')

We then reopen our Map.

m.openView()

And we can see that the default extent has been changed to show the entire layer.

You can repeat the above with a selection made on the layer to zoom to the selection.

Subscribe so you never miss out!

ArcPy Course

Enhance your ArcGIS Pro data management workflows with our ArcPy Course.

Leave a Comment

Your email address will not be published. Required fields are marked *