Create a new Feature Layer in an ArcGIS Online Hosted Feature Service from a Feature Set using the ArcGIS API for Python

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.

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. Use code AFP01CM50 for 50% off the price of the course!

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

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")
				
			
				
					## 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")
				
			

Leave a Comment

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