Accessing features using the FeatureSet JSON
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()
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.