0

I'm trying to get a df with tree cover loss by year by sector of the DRC using the gee python API. The output feature collection is finally what I want, but I keep getting the following error:


EEException: List.map: Parameter 'list' is required.

During handling of the above exception, another exception occurred:

Exception                                 Traceback (most recent call last)
<ipython-input-12-92980ec1d8af> in <cell line: 42>()
     40 # Map the function over the feature collection
     41 tree_change_over_time_fc = sectors_fc_nonlist.map(calculate_loss_for_feature)
---> 42 tree_change_over_time_fc_gdb = geemap.ee_to_pandas(tree_change_over_time_fc)
     43 
     44 # Print the result

/data/dataiku/dss_data/code-envs/python/geospatial/lib/python3.9/site-packages/geemap/common.py in ee_to_df(ee_object, col_names, sort_columns, **kwargs)
   8951         return df
   8952     except Exception as e:
-> 8953         raise Exception(e)
   8954 
   8955 

Exception: List.map: Parameter 'list' is required.

Here are my Sectors: https://code.earthengine.google.com/?asset=users/darcygray/DRC_sectors

#Read recipe inputs and convert sectors to a feature collection
hansenDataset = ee.Image('UMD/hansen/global_forest_change_2022_v1_10')
Sectors = dataiku.Dataset("Sectors_copy")

def convert_to_geometry(ewkt_string):
    return wkt.loads(ewkt_string)

df = Sectors.get_dataframe()
df = pd.DataFrame(df)
df['geometry'] = df['the_geom'].apply(convert_to_geometry)
gdf = gpd.GeoDataFrame(df, geometry='geometry')
gdf.crs = 'EPSG:4326'
gdf = gdf.iloc[:, 1:]
gdf = gdf.iloc[:10]
sectors_fc_nonlist = geemap.geopandas_to_ee(gdf)
# Define  loss calculation function
def calculate_loss_for_feature(sector):
    geometry = sector.geometry()
    sectorName = sector.get('NOM')
    
    # Reduce the region for the filtered feature
    lossByYear_sector = lossByYear.reduceRegion(
        reducer=ee.Reducer.sum().group(
            groupField=1,
            groupName='lossyear',
        ),
        geometry=geometry,
        scale=30,
        maxPixels=1e9
    )

    stats = ee.List(lossByYear.get('groups'))
    def format_element(el):
        d = ee.Dictionary(el)
        group = ee.Number(d.get('lossyear')).format("20%02d")
        return [group, d.get('sum')]

    stats_formatted = stats.map(format_element)
    stats_flattened = stats_formatted.flatten()
    return ee.Feature(None,{
        'SectorName': sectorName,
        'LossOverTime': stats_flattened}).setGeometry(sector.geometry())

#prep Image
lossImage = hansenDataset.select(['loss'])
lossAreaImage = lossImage.multiply(ee.Image.pixelArea())
lossYear = hansenDataset.select(['lossyear'])
lossByYear = lossAreaImage.addBands(lossYear)

# Map the function over the feature collection
tree_change_over_time_fc = sectors_fc_nonlist.map(calculate_loss_for_feature)
tree_change_over_time_fc_gdb = geemap.ee_to_pandas(tree_change_over_time_fc)

# Print the result
print(tree_change_over_time_fc.get('LossOverTime'))

1 Answer 1

1

Okay I actually got it to work!

The issue was the ee.Dictionary that was being defined inside the function. I changd this to a list, and then I do the manipulation of format downstream.

Here's the updated function:

def calculate_loss_for_feature(sector):
    geometry = sector.geometry()
    sectorName = sector.get('NOM')

    # Reduce the region for the filtered feature
    lossByYear_sector = lossByYear.reduceRegion(
        reducer=ee.Reducer.sum().group(
            groupField=1,
            groupName='lossyear',
        ),
        geometry=geometry,
        scale=30,
        maxPixels=1e9
    )

    # Access the 'groups' from the reducer's output
    stats = ee.List(lossByYear_sector.get('groups'))

    # Create a dictionary to store the results
    feature_properties = {
        'SectorName': sectorName,
        'LossOverTime': stats
    }

    # Create a feature with properties
    feature = ee.Feature(geometry, feature_properties)

    return feature

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.