Buffer Points in ArcGIS Online and Append into a Polygon Feature Layer 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 including data and attribute updates. In this post we will focus on updating a Polygon Feature Layer based on buffering points from another Feature Layer. This blog post took its inspiration from an Esri Community question posed by username ChristopherCounsell which you can find here.

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 also need to import some components of the geometry module; Point to help feed our points into the buffer function, and LengthUnits which is an enum helper (we will also use this in the buffer function)

				
					## import GIS which provides the gateway entry to your AGOL
from arcgis.gis import GIS

## components of the geometry module
from arcgis.geometry import Point, buffer, LengthUnits


				
			

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 Objects

We require the Feature Service Item object that represents the Feature Service that contains the Point and Polygon layers. In the example below, they two layers are within the same Feature Service. We get the both the Point Feature Layer and Polygon Feature Layer as FeatureLayer objects, and we also get the Spatial Reference for each layer.

				
					## get the feature service that contains the layers as an Item object
fs_item = agol.content.get("FS_ITEM_ID")

## the point FeatureLayer object that contains teh points to buffer
pt_lyr = fs_item.layers[0]

## the polygon FeatureLayer that represents where the buffers will be added
ply_lyr = fs_item.layers[1]

## the srs of the point layer and ploygon layers as Integer objects
pt_srs = pt_lyr.properties.extent.spatialReference.latestWkid
ply_srs = pt_lyr.properties.extent.spatialReference.latestWkid
				
			

Get the FeatureSet

We use the query() method for the FeatureLayer object to return a FeatureSet that contains the attributes of interest and the point geometry for each record.

We want the field that contains the buffer distances to buffer each individual point by, and the GlobalID so we can add to the buffered polygon. You do not need to have a field that contains the buffer distances if you are going to perform a uniform buffer for all points.

				
					## query the point FeatureLayer and return a FeatureSet
points_fs = pt_lyr.query(
    where = "1=1",
    out_fields = ["buff_dist", "GlobalID"],
    return_geometry = True
)
				
			

Create the List of Dictionaries

Our FeatureSet is a list containing feature information; our attributes and geometry. We create a Point geometry object from the geometry of the feature and we want the buff_dist for two reasons, to buffer the point by that distance, and to add it to the polygon record, we also wand to at the GlobalID to the polygon record.

The main event! For each point from the FeatureSet, we buffer that point. The buffer() function returns a list of geometries, which is important to note.

We need to create a dictionary that represents the polygon feature to add. This consists of our geometry and attributes. Notice with the geometry we are access the first element of the buffer_geom list returned from the buffer() function.

On each iteration we add the polygon record to the polygon Feature Layer with the esit_features() mehod. You could of course store all records in a list and the call the edit_features() once outside of the list.

If there are thousands of records, you might want to divide the edit_features() call into chunks of 2000 features to avoid errors.

				
					## iterate over each point from the point layer
for point in points_fs:
    ## the point geometry
    p = Point(point.geometry)
    ## the distance to buffer
    d = point.attributes["buff_dist"]
    ## the GUID for the point
    g = point.attributes["GlobalID"]

    ## buffer the point by the buff_dist field and return the polygon geometry
    ## NOTE: returned as a list of gemetries
    buffer_geom = buffer(
        geometries=[p],
        in_sr= pt_srs,
        distances = [d],
        unit = LengthUnits.METER.value,
        out_sr = ply_srs
    )

    ## the dictionary that represents the record to add to the polygon buffer layer
    ## NOTE: access the first entry in the buffer_geom list
    f = {
        "geometry": buffer_geom[0],
        "attributes": {
            "buff_dist" : d,
            "guid_match" : g
        }
    }

    ## add the polygon buffer to the layer
    ply_lyr.edit_features(adds=[f])
				
			
Buffer Points and Add to Polygon Layer in ArcGIS Online

At Final Draft Mapping we provide comprehensive courses for automating tasks within ArcGIS Pro and ArcGIS Online with ArcPy and the ArcGIS API for Python. Courses range from beginner to advanced workflows and all paid courses provide extra support where you can ask questions. Automation within ArcGIS is a highly sought after skill, by adding these skills to your arsenal you are placing yourself at the forefront of that demand. 

We appreciate our blog readers, you can get 25% off any (non-sale) course at any time with the code FDMBLOG25

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.

				
					from arcgis.gis import GIS
from arcgis.geometry import Point, buffer, LengthUnits

################################################################################
## Access ArcGIS Online ########################################################

agol = GIS("home")

################################################################################
## Required Objects ############################################################

## get the feature service that contains the layers as an Item object
fs_item = agol.content.get("FS_ITEM_ID")

## the point FeatureLayer object that contains teh points to buffer
pt_lyr = fs_item.layers[0]

## the polygon FeatureLayer that represents where the buffers will be added
ply_lyr = fs_item.layers[1]

## the srs of the point layer and ploygon layers as Integer objects
pt_srs = pt_lyr.properties.extent.spatialReference.latestWkid
ply_srs = pt_lyr.properties.extent.spatialReference.latestWkid

################################################################################
## Get the Point FeatureSet Object #############################################

## query the point FeatureLayer and return a FeatureSet
points_fs = pt_lyr.query(
    where = "1=1",
    out_fields = ["buff_dist", "GlobalID"],
    return_geometry = True
)

################################################################################
## Buffer the Points ###########################################################

## iterate over each point from the point layer
for point in points_fs:
    ## the point geometry
    p = Point(point.geometry)
    ## the distance to buffer
    d = point.attributes["buff_dist"]
    ## the GUID for the point
    g = point.attributes["GlobalID"]

    ## buffer the point by the buff_dist field and return the polygon geometry
    ## NOTE: returned as a list of gemetries
    buffer_geom = buffer(
        geometries=[p],
        in_sr= pt_srs,
        distances = [d],
        unit = LengthUnits.METER.value,
        out_sr = ply_srs
    )

    ############################################################################
    ## Add Polygons to the Polygon FeatureLayer ################################

    ## the dictionary that represents the record to add to the polygon buffer layer
    ## NOTE: access the first entry in the buffer_geom list
    f = {
        "geometry": buffer_geom[0],
        "attributes": {
            "buff_dist" : d,
            "guid_match" : g
        }
    }

    ## add the polygon buffer to the layer
    ply_lyr.edit_features(adds=[f])

################################################################################
print("\nSCRIPT COMPLETE")
				
			

Leave a Comment

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