.edit_features() overwrites geometries

408
4
Jump to solution
03-13-2024 08:16 AM
Labels (2)
BlakeMunshell
New Contributor II

Hi all, this is a re-upload of a previously asked question that I could have worded better. My issue is that when I use the FeatureLayer.edit_features(updates=FeatureSet) method, it is overwriting my geometries. I have done this with several layers now, and it seems to be an issue exclusively with polygons. 

Here is my script, broken up with images of my outputs: 

 

polygon_layer_get = gis.content.get("8c1e457fea0341aeb9c29cdf3a1dd64c") # dummy shapefile I made for testing
polygon_layer = polygon_layer_get.layers[0]
df = polygon_layer.query().sdf

 

BlakeMunshell_0-1710342590732.png

For now, notice that the geometry is intact. 

 

# dummy function where I overwrite a single value
unscored_df = df[(df['scored'] < 1) | df['scored'].isna()]
df = unscored_df.copy()
df['scored'] = 1
# pandas df to geopandas gdf
polygon_df = gpd.GeoDataFrame(df, geometry="SHAPE", crs="EPSG:4326")
# gpd gdf to sedf
polygon_sedf = GeoAccessor.from_geodataframe(polygon_df, column_name="SHAPE")

 

BlakeMunshell_1-1710342749562.png

If we look at the SEDF, the SHAPE is still intact. 

 

# sedf to feature set
polygon_fs = polygon_sedf.spatial.to_featureset()

 

BlakeMunshell_2-1710342819893.png

If we look at the FS, we can see the geometry field is still intact. 

 

polygon_layer.edit_features(updates=polygon_fs)

 

BlakeMunshell_3-1710342871924.png

And finally, we edit the features with no issues. But now, if I re-run the first part to load in the polygon data: 

BlakeMunshell_4-1710342944933.png

All the SHAPEs are None, and looking in AGOL confirms these are now empty records. 

 

Any ideas? 

 

0 Kudos
1 Solution

Accepted Solutions
BlakeMunshell
New Contributor II

Thank you for your solution, although that specific line

return_geometry = False,

forces all geometry as "None", whether I have already broken the layer or not. But for now, adding this line after converting back to a FeatureSet: 

 

 

polygon_fs_updated = [
    {
        "SHAPE": feature.geometry,
        "attributes": feature.attributes
    }
    for feature in original_features
]

 

 

did end up fixing the issue. Thanks for your help though! 

View solution in original post

0 Kudos
4 Replies
jcarlson
MVP Esteemed Contributor

GeoPandas and the ArcGIS Python API don't really play nice in my experience.

What are you doing to the geometry, and how are you using GeoPandas as part of that process?

- Josh Carlson
Kendall County GIS
0 Kudos
BlakeMunshell
New Contributor II

Hi Josh, 

I am not doing anything to the geometry itself, I just need to keep track of which features have been scored or not scored. I am really only using GeoPandas because the .query().sdf makes a GeoDataFrame already, and GeoPandas is my go-to data manipulation library. 

I'm not totally convinced GeoPandas is to blame here, because printing "polygon_fs" (the feature set that was created from the dataframe) still has the spatial data. Now that I think about it, I think my issue might be because the feature set is storing the geometry as "geometry" instead of "SHAPE". 

BlakeMunshell_0-1710346826927.png

However, .edit_features() doesn't have any field mapping unfortunately. I am trying to loop through the feature set (since it is basically a list of dictionaries), but there are some complications. I'll keep chugging away at this route until someone smarter than me suggests something else. 

0 Kudos
jcarlson
MVP Esteemed Contributor

Nah, that shouldn't matter. "geometry" is just how you send spatial information to the REST endpoint.

Honestly, if you aren't messing with the shapes at all, just drop that column before you submit the edits. Any fields you omit from your edit, including the geometry, are simply left untouched.

You could have a layer with 100 fields, but if your dataframe only has 2 of those fields present, when you submit the FeatureSet, those are the only two fields that will be updated. It's a feature we rely on quite a lot, actually, as we have scripts that update subsets of columns on a number of layers.

A couple notes on the code. You can ask for the query to give you a dataframe directly, and you can have it omit unnecessary fields right from the start:

df = polygon_layer.query(
    out_fields = ['the', 'fields', 'you', 'need', 'for', 'scoring'],
    return_geometry = False,
    as_df = True
)

 Try either limiting your geometry that way, or else just dropping the SHAPE column prior to submitting the edits, see what happens.

- Josh Carlson
Kendall County GIS
0 Kudos
BlakeMunshell
New Contributor II

Thank you for your solution, although that specific line

return_geometry = False,

forces all geometry as "None", whether I have already broken the layer or not. But for now, adding this line after converting back to a FeatureSet: 

 

 

polygon_fs_updated = [
    {
        "SHAPE": feature.geometry,
        "attributes": feature.attributes
    }
    for feature in original_features
]

 

 

did end up fixing the issue. Thanks for your help though! 

0 Kudos