Table of Contents
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 components of ArcGIS Online such as Feature Layers within a Feature Service. In this blog post we will focus on using the ArcGIS API for Python to query a subset of records from a Feature Layer in one Feature Service, and create a new Feature Layer in another Feature Service containing the subset of records.
Unlock the full potential of ArcGIS Online by mastering the art of efficient Content Management with the ArcGIS API for Python. In this comprehensive course, you will embark on a journey to streamline your geospatial workflows, enhance data organization, and maximize the impact of your ArcGIS Online platform.
Geospatial Professionals, GIS Analysts, Data Managers, and enthusiasts will discover the power of automation and script-based operations to efficiently manage content in ArcGIS Online. Throughout this course, you will gain practical, hands-on experience in leveraging the ArcGIS API for Python to perform a wide range of content management tasks with ease.
arcgis modules
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 FeatureLayer
class to create a FeatureLayer
object which we can query to return a subset of records known as a Feature Set. The FeatureLayerCollection
class represents a Feature Service in ArcGIS Online and will enable us to create a new Feature Layer in our Feature Service of choice.
## provides access to ArcGIS Online
from arcgis.gis import GIS
## creates a FeatureLayer object to create a FeatureSet from
from arcgis.features import FeatureLayer
## represents a Feature Service
from arcgis.features import FeatureLayerCollection
Accessing ArcGIS Online
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")
## Access AGOL
agol = GIS(
url = "https://your_organisation.maps.arcgis.com/",
username = "Your_Username",
password = "Your_Password"
)
Required inputs
A few user inputs to cater for.
- The Item ID for the Feature Service that contains the Feature Layer of interest.
- The index of the layer within the Feature Service.
- The Item ID for the Feature Service that we want to add the new layer to.
- The name of the new layer.
- The SQL query required to subset the records from the layer of interest.
## the item id for the feature service that contains the layer to query
fs_item_id = "FS_ITEM_ID"
## the index of the layer to query (0 if only one layer or the first layer)
lyr_idx = 0
## the item id for the feature service to add the new feature layer to
add_lyr_item_id = "FS_ITEM_ID"
## the name of the new feature layer
lyr_name = "NEW_FEATURE_LAYER"
## the feature layer query
fl_query = "SQL_QUERY"
Get the Feature Set
We first need to get the Feature Service ArcGIS Online item that contains the Feature Layer as an Item object. From this Item object we create a FeatureLayer object targeting the layer that we wish to get a subset of records from (via the layer index).
We query the Feature Layer which returns a Feature Set.
## get the feature service item that contains the layer to query
fs_item = agol.content.get(fs_item_id)
## get the layer of interest to query
## get the layer of interest to query
fl = FeatureLayer.fromitem(
item = fs_item,
layer_id = lyr_idx
)
## get the feature set
fs = fl.query(fl_query)
Create the new Feature Layer
Time for some magic! We need to create a dictionary definition representing the new Feature Layer to add to the Feature Service. We take information from the Feature Layer where the subset of records originate from such as the symbology, fields, and geometry type for examples. The FeatureLayerCollection class enables us to inject this definition as a new FeatureLayer using the add_to_definition() method.
fl_properties = dict(fl.properties)
## get the feature service item to create new feature layer for
add_lyr_item = agol.content.get(add_lyr_item_id)
## create feature layer definition
fl_definition = {
"type" : "Feature Layer",
"name" : lyr_name,
"geometryType": fl_properties["geometryType"],
"drawingInfo" : fl_properties["drawingInfo"],
"fields" : fl_properties["fields"],
"indexes": fl_properties["indexes"],
"objectIdField": fl_properties["objectIdField"],
"uniqueIdField": fl_properties["uniqueIdField"],
}
## create FLC object
flc = FeatureLayerCollection.fromitem(add_lyr_item)
## update the JSON definition fof the feature service to include the layer
flc.manager.add_to_definition({"layers": [fl_definition]})
Add in the records from the Feature Set
Now that we have updated the definition, we will re-grab the Item object for the Feature Service that now contains the new Feature Layer. We get the new Feature Layer as a FeatureLayer object and we add in the subset of data from the original Feature Layer using the edit_features() method.
If you have over 2000 records in the subset, you might need to break the edit_features() call into chunks to avoid errors in API calls and timeouts.
## re-get the updated item object
add_lyr_item = agol.content.get(add_lyr_item_id)
## get the layer of interest
fl = [lyr for lyr in add_lyr_item.layers if lyr.properties.name == lyr_name][0]
## populate with data
fl.edit_features(adds=fs.features)
Geospatial Professionals, GIS Analysts, and enthusiasts will discover the power of automation and script-based operations to efficiently interact and update WebMaps in ArcGIS Online. Throughout this course, you will gain practical, hands-on experience in leveraging the ArcGIS API for Python to perform a wide range of WebMap tasks with ease.
We will dissect WebMaps for all that they are and by the end of this course you will be comfortable with manipulating the JSON, which is the behind the scenes configuration of a WebMap, to produce scripts for workflows where there is currently no API Python method, such as grouping layers.
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.
## provides access to ArcGIS Online
from arcgis.gis import GIS
## creates a FeatureLayer object to create a FeatureSet from
from arcgis.features import FeatureLayer
## represents a Feature Service
from arcgis.features import FeatureLayerCollection
################################################################################
## API Reference Links:
## https://developers.arcgis.com/python/api-reference/arcgis.gis.toc.html#gis
## https://developers.arcgis.com/python/api-reference/arcgis.gis.toc.html#arcgis.gis.ContentManager.get
## https://developers.arcgis.com/python/api-reference/arcgis.features.toc.html#featurelayer
## https://developers.arcgis.com/python/api-reference/arcgis.features.toc.html#arcgis.features.FeatureLayer.fromitem
## https://developers.arcgis.com/python/api-reference/arcgis.features.toc.html#arcgis.features.FeatureLayer.query
## https://developers.arcgis.com/python/api-reference/arcgis.features.toc.html#featurelayercollection
## https://developers.arcgis.com/python/api-reference/arcgis.features.managers.html#featurelayercollectionmanager
## https://developers.arcgis.com/python/api-reference/arcgis.features.managers.html#arcgis.features.managers.FeatureLayerCollectionManager.add_to_definition
## https://developers.arcgis.com/python/api-reference/arcgis.features.toc.html#arcgis.features.FeatureLayer.edit_features
##
## API Version: 2.1.0.2, 2.2.0.1, 2.3.0
##
################################################################################
################################################################################
## ACCESS ARCGIS ONLINE ########################################################
agol = GIS("home")
################################################################################
## USER INPUTS #################################################################
## the item id for the feature service that contains the layer to query
fs_item_id = "FS_ITEM_ID"
## the index of the layer to query (0 if only one layer or the first layer)
lyr_idx = 0
## the item id for the feature service to add the new feature layer to
add_lyr_item_id = "FS_ITEM_ID"
## the name of the new feature layer
lyr_name = "NEW_FEATURE_LAYER"
## the feature layer query
fl_query = "SQL_QUERY"
################################################################################
## GET FEATURE SET INFORMATION #################################################
## get the feature service item that contains the layer to query
fs_item = agol.content.get(fs_item_id)
## get the layer of interest to query
## get the layer of interest to query
fl = FeatureLayer.fromitem(
item = fs_item,
layer_id = lyr_idx
)
## get the feature set
fs = fl.query(fl_query)
################################################################################
## CREATE NEW FEATURE LAYER ####################################################
fl_properties = dict(fl.properties)
## get the feature service item to create new feature layer for
add_lyr_item = agol.content.get(add_lyr_item_id)
## create feature layer definition
fl_definition = {
"type" : "Feature Layer",
"name" : lyr_name,
"geometryType": fl_properties["geometryType"],
"drawingInfo" : fl_properties["drawingInfo"],
"fields" : fl_properties["fields"],
"indexes": fl_properties["indexes"],
"objectIdField": fl_properties["objectIdField"],
"uniqueIdField": fl_properties["uniqueIdField"],
}
## create FLC object
flc = FeatureLayerCollection.fromitem(add_lyr_item)
## update the JSON definition fof the feature service to include the layer
flc.manager.add_to_definition({"layers": [fl_definition]})
################################################################################
## ADD RECORDS #################################################################
## re-get the updated item object
add_lyr_item = agol.content.get(add_lyr_item_id)
## get the layer of interest
fl = [lyr for lyr in add_lyr_item.layers if lyr.properties.name == lyr_name][0]
## populate with data
fl.edit_features(adds=fs.features)
################################################################################
print("\nSCRIPT COMPLETE")