Select to view content in your preferred language

Trying to overwrite/update a feature layer using json from an api

298
11
3 weeks ago
GIS_utahDEM
Occasional Contributor II

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

 

 

0 Kudos
11 Replies
EarlMedina
Esri Regular Contributor

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)

0 Kudos
GIS_utahDEM
Occasional Contributor II

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)

@EarlMedina  

0 Kudos
EarlMedina
Esri Regular Contributor

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

0 Kudos
GIS_utahDEM
Occasional Contributor II

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? 

 @EarlMedina 

0 Kudos
EarlMedina
Esri Regular Contributor

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.

0 Kudos
GIS_utahDEM
Occasional Contributor II

Unfortunately that didn't fix it 😕. I still get "Failed to update feature layer: 0" even when I replaced the tuples with lists. 

0 Kudos
EarlMedina
Esri Regular Contributor

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.

0 Kudos
GIS_utahDEM
Occasional Contributor II

This is what I get: 

GIS_utahDEM_0-1720035275167.png

 

0 Kudos
EarlMedina
Esri Regular Contributor

Remember it's expecting a list so it has to be adds=[temp_line]

0 Kudos