Accessing features using the FeatureSet JSON

Dr. Huidae Cho
Institute for Environmental and Spatial Analysis...University of North Georgia

1   Add a feature layer

Add your feature layer.

filename = r'P:\YOUR_PATH\roadsmajor.shp'

prj = arcpy.mp.ArcGISProject('CURRENT')
m = prj.activeMap
m.addDataFromPath(filename)

2   Create a feature set

The FeatureSet class takes the name of a table optionally.

fs = arcpy.FeatureSet('roadsmajor')

Omitting a table name creates an empty feature set.

fs = arcpy.FeatureSet()

The FeatureSet class provides the load and save methods and the JSON property.

fs.load(filename) # full path
# or
fs.load('roadsmajor') # layer name

Create a copy of the feature layer.

fs.save(r'P:\YOUR_PATH\copy.shp')

3   JavaScript Object Notation (JSON)

JSON is a lightweight data-interchange format.”

Let’s try.

# value
123

# key/value pairs
{"key1": "value1", "key2": "value2"}

# array
[1, 2, 3]

# array of key/value pairs
[{"key1": "value1", "key2": "value2"}, {"key3": "value3"}, "value4"]

4   Converting the feature set JSON string to a Python object

A loaded feature set contains the attributes and geometries of all the features in the layer in the JSON property.

The JSON property is NOT a JSON object nor a Python object. It’s a “serialized”-JSON string, which is not easy to navigate and manipulate. We can “deserialize” the JSON string into a Python object using the json module. Check the JSON and Python translation table.

type(fs.JSON)

import json

fsjson = json.loads(fs.JSON)

# let's see what keys we have here
fsjson.keys()

Check An overview of the JSON toolset.

5   FeatureSet object

The FeatureSet object contains Feature objects.

  • geometryType
  • spatialReference
  • fields
  • features

6   Listing all fields

The fields key contains an array of fields.

for i in range(len(fsjson['fields'])):
  field = fsjson['fields'][i]
  # print field name and data type
  print(f'{field["name"]}:\t{field["type"]}')

7   Accessing individual feature attributes using JSON

The features key contains an array of features.

for i in range(len(fsjson['features'])):
  print(f'---------- feature {i} ----------')
  f = fsjson['features'][i]
  for j in range(len(f['attributes'])):
    # not all items are indexable
    # f['attributes'] is a dictionary
    key = list(f['attributes'].keys())[j]
    attr = f['attributes'][key]
    print(f'{key}:\t{attr}')

8   Accessing individual feature geometries using JSON

for i in range(len(fsjson['features'])):
  print(f'---------- feature {i} ----------')
  f = fsjson['features'][i]
  # polyline geometry
  geom = f['geometry']
  # multiple paths
  paths = geom['paths']
  for j in range(len(paths)):
    print(f'---------- path {j} ----------')
    # for each path
    path = paths[j]
    for k in range(len(path)):
      point = path[k]
      # print each point in the path
      print(f'{point[0]}, {point[1]}')

Unfortunately, you cannot modify feature attributes or geometries using the JSON property because it is read-only.