I am trying to automate updates to a polyline hosted feature layer in AGOL using an API. I think I have the format of the json to update correct, however, I'm having trouble with the final step of pushing the updates to the existing hosted feature layer (line 39).
# Main function to fetch API, decode polylines, and publish to ArcGIS Online
def main():
# Make request to API
response = requests.get(api_url)
if response.status_code == 200:
# Assuming API response is JSON with 'features' containing polyline data
features = response.json()
# Extract features from the API data
#features = api_data.get('features', [])
#if not features:
# print("No features found in API response.")
# return
try:
# Truncate existing features in the feature layer
feature_layer.manager.truncate()
# Prepare new features to add
geojson_features = []
for feature in features:
encoded_polyline = feature.get('EncodedPolyline')
description = feature.get('Description')
if encoded_polyline and description:
# Decode polyline from 'EncodedPolyline' field
decoded_polyline = decode_polyline(encoded_polyline)
# Convert to GeoJSON Feature format
geojson_feature = to_geojson_feature(decoded_polyline, description)
geojson_features.append(geojson_feature)
# Add new GeoJSON features to the feature layer
print(json.dumps(geojson_features))
result = feature_layer.edit_features(adds=json.dumps(geojson_features))
print(f"Features updated successfully in ArcGIS Online hosted feature layer.")
except Exception as e:
print(f"Failed to update feature layer: {str(e)}")
else:
print("Failed to fetch data from API.")
This is what the print(json.dumps(geojson_features)) returns:
[{"type": "Feature", "geometry": {"type": "LineString", "coordinates": [[40.77248, -111.8377], [40.77254, -111.83776], [40.7728, -111.83804], [40.77248, -111.8377]]}, "properties": {"Description": "Blue Detour"}},
***I removed most of the coordinates for simplicity, and only included the first feature, the rest of the features have the same format
This is what is returned for the feature_layer.edit_features(adds=json.dumps(geojson_features)):
pass in features as list of Features, dicts or PropertyMap Parameters not valid for edit_features
You are passing in a string when you use json.dumps. Try this instead and see if it makes a difference:
feature_layer.edit_features(adds=geojson_features)
When I swap that out, I get the following error:
Failed to update feature layer: Cannot perform operation. Invalid operation parameters. 'adds' parameter is invalid Object reference not set to an instance of an object. (Error Code: 400)
Ah, sorry I think I missed before that you were appending GeoJSON features. I believe you have to convert to esri json format. Something like this:
[ { "attributes": { "a": 1, "b": 1970.0, "c": 1.0, }, "geometry": { "paths": [
[
[-97.06138, 32.837],
[-97.06133, 33.836],
[-98.2, 34.834],
[-97, 40]
]
],
"spatialReference": {"wkid": 4326} }
},
...
]
You may refer to this documentation to get a sense of the geometry format you need: Geometry objects | ArcGIS REST APIs | ArcGIS Developers
Thank you -- I think I'm getting closer but I'm still having some difficulty. I've transformed to the appropriate format (I think), and I eliminated the attributes/ids for simplicity for now, but I am still getting an error. The format that I get which I'm trying to use in the .edit_features(adds=) is:
{'geometry': {'hasZ': False, 'hasM': False, 'paths': [[(40.77248, -111.8377), (40.77254, -111.83776), (40.7728, -111.83804), (40.7728, -111.83804), (40.77248, -111.8377)], [(40.76466, -111.84503), (40.76455, -111.84494), (0.76478, -111.84513), (40.76466, -111.84503)], [(40.76418, -111.8268), (40.76413, -111.82683), (40.76417, -111.82681)]], 'spatialReference': {'wkid': 4326}}}
With this I get the error:
Failed to update feature layer: 0
Maybe the issue is coming from me using the .decode() method from the polyline library to return my paths?
Possibly? It looks like it might be getting confused about the tuples in your coordinates:
[[(40.77248, -111.8377)...
Replace all parentheses with the corresponding open/closing square bracket and I think you should be close.
Unfortunately that didn't fix it 😕. I still get "Failed to update feature layer: 0" even when I replaced the tuples with lists.
Just to simplify things further, how about if you just remove all the extra stuff and send in this?
{
"geometry": {
"paths": [
[
[
40.77248,
-111.8377
],
[
40.77254,
-111.83776
],
[
40.7728,
-111.83804
],
[
40.7728,
-111.83804
],
[
40.77248,
-111.8377
]
]
]
}
}
I think you had some nesting going on before.
This is what I get:
Remember it's expecting a list so it has to be adds=[temp_line]