Esri / arcgis-python-api

Documentation and samples for ArcGIS API for Python
https://developers.arcgis.com/python/
Apache License 2.0
1.88k stars 1.1k forks source link

Spatially enabled dataframe (SEDF) cant be inserted as a featurelayer into an existing feature service when created without gis context in the first place (result in AttributeError: 'GeoAccessor' object has no attribute '_gis') #2068

Open vmarquar opened 4 days ago

vmarquar commented 4 days ago

Describe the bug When creating a SEDF from a dict without having a gis-context there in the first place (or by creating a SEDF with any other method, e.g. derived from a pd.merge()), following bug occurs: AttributeError: 'GeoAccessor' object has no attribute '_gis'

To Reproduce Steps to reproduce the behavior:

import pandas as pd
from arcgis.features import GeoAccessor, GeoSeriesAccessor
from arcgis.geometry import Geometry
from arcgis.gis import GIS

# Convert dictionary to DataFrame
data = {
    'name': ['Location A', 'Location B'],
    'latitude': [34.05, 40.71],
    'longitude': [-118.24, -74.01]
}
df = pd.DataFrame(data)

# Create a geometry column using latitude and longitude
df['SHAPE'] = [{'x': lon, 'y': lat} for lon, lat in zip(df['longitude'], df['latitude'])]

# Convert DataFrame to a Spatially Enabled DataFrame (SeDF)
sedf = pd.DataFrame.spatial.from_xy(df, x_column='longitude', y_column='latitude', sr=4326)

# Set the spatial reference (optional)
sedf.spatial.set_geometry('SHAPE')

# Check if its really a SEDF
assert type(sedf) == pd.DataFrame, "not a pd.Dataframe class!"
assert type(sedf.spatial) == GeoAccessor, "there is no 'spatial' namespace. Not a valid SEDF!"

# Print the SeDF
print(sedf)

# Insert the SEDF to an existing feature service
FEATURE_SERVICE_ITEM_ID = "<<<ADD A VALID ITEM ID HERE>>>"
gis = GIS("home")
feature_service_item = gis.content.get(FEATURE_SERVICE_ITEM_ID)
new_sublayer_name = "my new featurelayer name from a example sedf"

feature_service_item = sedf.spatial.insert_layer(feature_service = feature_service_item,
                                                gis=gis,
                                                service_name=new_sublayer_name)

#<<< OR ALTERNATIVELY BY OMITTING THE gis=gis argument>>>
feature_service_item = sedf.spatial.insert_layer(feature_service = feature_service_item,
                                                service_name=new_sublayer_name)

both variations of sedf.spatial.insert_layer() result in this error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/tmp/ipykernel_19/781633500.py in <cell line: 0>()
----> 1 feature_service_item = sedf.spatial.insert_layer(feature_service = feature_service_item,
      2                                                 gis=gis,
      3                                                 service_name=new_sublayer_name)

/opt/conda/lib/python3.11/site-packages/arcgis/features/geo/_accessor.py in insert_layer(self, feature_service, gis, sanitize_columns, service_name)
   2553         if (
   2554             gis.users.me.username != service.owner
-> 2555             and "portal:admin:updateItems" not in self._gis.users.me.privileges
   2556         ):
   2557             raise AssertionError(

AttributeError: 'GeoAccessor' object has no attribute '_gis'

Expected behavior The newly created sedf should be added as a new feature layer inside the existing featureservice.

Platform (please complete the following information):

Additional context The abovemention error was tested using a default / basic ArcGIS Notebook inside AGOL and additionally inside a custom windows 11 conda environment.

nanaeaubry commented 3 days ago

@vmarquar Thanks for reporting. This is due to a typo and not the gis being instantiated afterwards. We will put in a fix