Select to view content in your preferred language

Update ArcGIS Online WebMap Extent Based on Polygon Feature Geometry with the ArcGIS API for Python

282
2
03-25-2025 08:07 AM
Clubdebambos
MVP Regular Contributor
4 2 282

Introduction

The ArcGIS API for Python is a powerful Python library that allows users to interact with and automate tasks in ArcGIS Online (or Portal). The API is excellent for programmatically creating, maintaining, and updating webmaps in ArcGIS Online. If you have ever had to reset the extent of a WebMap after it has been let out in the wild for a while, then this workflow is for you. Here, we will focus in updating the extent for one WebMap, but you could certainly iterate through as many as required and update each extent individually as you go along. Please note, that this workflow is for the latest Map Viewer in ArcGIS Online (AGOL) and not for the Classic Viewer.

This blog post covers the workflow for version 2.4.0. For a comparison between early versions visit here.

Below is a WebMap zoomed to the extent of Ireland with some layers added. The original map extent focused on Galway over on the west coast. We will use to API to update/reset the map extent using the geometry of the polygon that represents Galway.

 
Clubdebambos_1-1742914223206.png

 

arcgis modules

Versions 2.4.0: The API provides access to your organisations ArcGIS Online via the GIS class in the gis module. This GIS class is the gateway to ArcGIS Online. We will need to import the Map class to create a Map object. The Map class is a part of the map module. This map module provides components for working with 2D and 3D maps and scenes. The Geometry class is imported from the geometry module. The geometry module defines useful geometry types and functions for working with geographic information and GIS functionality.

## import GIS which provides the gateway entry to your AGOL
from arcgis.gis import GIS
## import WebMap from the mapping module
from arcgis.map import Map
## import the Geometry class to get the bounding box for the extent
from arcgis.geometry import Geometry

 

Required Objects

 Some required objects. The WebMap Item ID  for the WebMap you want to update the extent for. The name of the layer as it appears in the WebMap that contains the polygon geometry for the extent. The SQL statement/where clause for limiting the polygon feature returned. 

## the ITEM ID of the WebMap to update
wm_item_id = "WM_ITEM_ID"

## the layer name as it appears in the WebMap
lyr_name = "ENTER LYR NAME"

## the SQL clause to limit the geometry
sql_clause = "ENTER SQL CLAUSE"

 

Get Layer Index Function

 A helper function to get the index of the layer of interest in the WebMap based on the layer name.

def getLayerIndexByName(wm_item, lyr_name):
    try:
        lyr_index = [index for index, lyr in enumerate(wm_item.get_data()["operationalLayers"]) if lyr["title"]==lyr_name][0]
        return lyr_index
    except IndexError:
        return None

 

Accessing ArcGIS Online

Our first port of call is to access your ArcGIS Online via the GIS class. There are a handful of ways to achieve access, if you are logged into your ArcGIS Online in ArcGIS Pro you can simply use "home", otherwise, another common way is to provide the ArcGIS Online URL, followed by your username and password.
 
## Access AGOL
agol = GIS("home")

## OR ##

## Access AGOL
agol = GIS(
    url = "https://your_organisation.maps.arcgis.com/",
    username = "Your_Username",
    password = "Your_Password"
)

 

Create the Map Object

 We first get the WebMap as an Item object and use that Item object to create a Map object. 

## get the WebMap as an Item object
wm_item = agol.content.get(wm_item_id)

## create a WebMap object from the Item object
webmap = Map(wm_item)

 

Get the Bounding Box Information for the Feature of Interest

We get the index of the layer of interest in the WebMap and utilise the new MapContent layers property which will return a list of layers as FeatureLayer objects (only for non-grouped layers). We can then query the FeatureLayer and return the feature of interest. We then get the bounding box of the geometry for that feature.

## get the index for the layer in the webmap
lyr_index = getLayerIndexByName(wm_item, lyr_name)

## MapContent layers property returns a list of feature layers (or group layers)
fl = webmap.content.layers[lyr_index]

## Query the layer to return the feature you want to zoom to.
f = fl.query(where=sql_clause)

## get the minimum bounding of that feature as an envelope
bbox = Geometry(f.features[0].geometry).envelope

 

Update the WebMap Extent

Set the extent property for the Map object to the bounding box and update the Map object with the update() method to commit the change.

## update/add and initialState property to the WebMap
webmap.extent = bbox

## update the WebMap to reflect the new extent
webmap.update()

 

Clubdebambos_2-1742914895092.png

 

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. The code below is presented slightly different than the blog post.

from arcgis.gis import GIS
from arcgis.map import Map
from arcgis.geometry import Geometry

################################################################################
## API Reference Links:
##  https://developers.arcgis.com/python/latest/api-reference/arcgis.gis.toc.html#gis
##  https://developers.arcgis.com/python/latest//api-reference/arcgis.gis.toc.html#arcgis.gis.ContentManager.get
##  https://developers.arcgis.com/python/latest/api-reference/arcgis.map.toc.html#map
##  https://developers.arcgis.com/python/latest/api-reference/arcgis.map.toc.html#arcgis.map.Map.content
##  https://developers.arcgis.com/python/latest/api-reference/arcgis.map.toc.html#mapcontent
##  https://developers.arcgis.com/python/latest/api-reference/arcgis.map.toc.html#arcgis.map.map_widget.MapContent.layers
##  https://developers.arcgis.com/python/api-reference/arcgis.features.toc.html#arcgis.features.FeatureLayer.query
##  https://developers.arcgis.com/python/api-reference/arcgis.geometry.html
##  https://developers.arcgis.com/python/api-reference/arcgis.geometry.html#geometry
##  https://developers.arcgis.com/python/latest/api-reference/arcgis.map.toc.html#arcgis.map.Map.update
##
## Description:
##  Update WebMap with a new Extent
##
## API Version: 2.4.0
##
################################################################################

################################################################################
## REQUIRED OBJECTS ############################################################

## the ITEM ID of the WebMap to update
wm_item_id = "WM_ITEM_ID"

## the layer name as it appears in the WebMap
lyr_name = "ENTER LYR NAME"

## the SQL clause to limit the geometry
sql_clause = "ENTER SQL CLAUSE"

################################################################################
## FUNCTIONS ###################################################################

def getLayerIndexByName(wm_item, lyr_name):
    try:
        lyr_index = [index for index, lyr in enumerate(wm_item.get_data()["operationalLayers"]) if lyr["title"]==lyr_name][0]
        return lyr_index
    except IndexError:
        return None

################################################################################
## ACCESS AGOL #################################################################

agol = GIS("home")

################################################################################
## CREATE MAP OBJECT ###########################################################

## get the WebMap as an Item object
wm_item = agol.content.get(wm_item_id)

## create a WebMap object from the Item object
webmap = Map(wm_item)

################################################################################
## GET BOUNDING BOX INFO #######################################################

## get the index for the layer in the webmap
lyr_index = getLayerIndexByName(wm_item, lyr_name)

## MapContent layers property returns a list of feature layers (or group layers)
fl = webmap.content.layers[lyr_index]

## Query the layer to return the feature you want to zoom to.
f = fl.query(where=sql_clause)

## get the minimum bounding of that feature as an envelope
bbox = Geometry(f.features[0].geometry).envelope

################################################################################
## UPDATE THE EXTENT ###########################################################

## update/add and initialState property to the WebMap
webmap.extent = bbox

## update the WebMap to reflect the new extent
webmap.update()

################################################################################

 

2 Comments
Contributors
About the Author
GIS Consultant with extensive experience utilising skills for GIS project management, quality map production, data management, geospatial analysis, standardisation, and workflow automation across a range of industries such as agriculture, oil & gas, telecommunications and engineering. Going beyond map production there is a passion for the technologies behind GIS, the databases, the programming languages, the analysis and statistical output, and continued professional development associated with GIS. You will mainly find me contributing in the Python and ArcGIS API for Python Communities.