Skip to content

eii.client

Google Earth Engine interface for EII data access.

Data Retrieval

Core retrieval functions for EII data.

This module provides the main interface for extracting Ecosystem Integrity Index data from pre-computed GEE assets.

get_stats(geometry, aggregation_method='min_fuzzy_logic', include_components=True, scale=300, stats=None, percentiles=None, compute_mode='precomputed', npp_year_range=OBSERVED_NPP_YEAR_RANGE, include_seasonality=True, natural_npp_asset_path=NATURAL_NPP_ASSET_PATH, observed_npp_asset_path=OBSERVED_NPP_ASSET_PATH, structural_asset_path=None, bii_year=DEFAULT_BII_YEAR, absolute_diff_percentile='p95', output_format='dict')

Extract EII values or statistics for a given geometry.

Parameters:

Name Type Description Default
geometry Geometry

AOI geometry (ee.Geometry/Feature/FeatureCollection, GeoPandas, shapely, or bbox tuple).

required
aggregation_method AggregationMethod

EII aggregation method. Defaults to "min_fuzzy_logic".

'min_fuzzy_logic'
include_components bool

If True, include statistics for functional, structural, and compositional integrity. Defaults to True.

True
scale int

Resolution in meters for the reduction. Defaults to 300.

300
stats list[str] | None

Statistics to compute. Supported: "mean", "median", "min", "max", "std". Defaults to ["mean"].

None
percentiles list[int] | None

Optional list of percentiles (0-100) to include.

None
compute_mode ComputeMode

"precomputed" (default) or "on_the_fly".

'precomputed'
npp_year_range list[str]

Date range for observed NPP (on-the-fly mode).

OBSERVED_NPP_YEAR_RANGE
include_seasonality bool

Include seasonality in functional integrity.

True
natural_npp_asset_path str

Asset for pre-computed natural NPP.

NATURAL_NPP_ASSET_PATH
observed_npp_asset_path str

Asset for observed NPP annual tiles.

OBSERVED_NPP_ASSET_PATH
structural_asset_path str | None

Asset for structural integrity core area.

None
bii_year int

BII year to select for compositional integrity.

DEFAULT_BII_YEAR
absolute_diff_percentile str

Percentile key for NPP absolute difference penalty.

'p95'
output_format OutputFormat

"dict" (default) or "geodataframe".

'dict'

Returns:

Type Description

A structured dictionary or GeoDataFrame depending on output_format.

Point geometries return single values; area geometries return summary

statistics in nested format: {"eii": {"mean": ..., "min": ...}}.

Example

import ee ee.Initialize() polygon = ee.Geometry.Rectangle([-60, -10, -55, -5]) stats = get_stats(polygon, stats=["mean", "min", "max"]) print(stats)

Source code in src/eii/client/retrieve.py
def get_stats(
    geometry: ee.Geometry,
    aggregation_method: AggregationMethod = "min_fuzzy_logic",
    include_components: bool = True,
    scale: int = 300,
    stats: list[str] | None = None,
    percentiles: list[int] | None = None,
    compute_mode: ComputeMode = "precomputed",
    npp_year_range: list[str] = OBSERVED_NPP_YEAR_RANGE,
    include_seasonality: bool = True,
    natural_npp_asset_path: str = NATURAL_NPP_ASSET_PATH,
    observed_npp_asset_path: str = OBSERVED_NPP_ASSET_PATH,
    structural_asset_path: str | None = None,
    bii_year: int = DEFAULT_BII_YEAR,
    absolute_diff_percentile: str = "p95",
    output_format: OutputFormat = "dict",
):
    """
    Extract EII values or statistics for a given geometry.

    Args:
        geometry: AOI geometry (ee.Geometry/Feature/FeatureCollection, GeoPandas,
            shapely, or bbox tuple).
        aggregation_method: EII aggregation method. Defaults to "min_fuzzy_logic".
        include_components: If True, include statistics for functional,
            structural, and compositional integrity. Defaults to True.
        scale: Resolution in meters for the reduction. Defaults to 300.
        stats: Statistics to compute. Supported: "mean", "median", "min", "max",
            "std". Defaults to ["mean"].
        percentiles: Optional list of percentiles (0-100) to include.
        compute_mode: "precomputed" (default) or "on_the_fly".
        npp_year_range: Date range for observed NPP (on-the-fly mode).
        include_seasonality: Include seasonality in functional integrity.
        natural_npp_asset_path: Asset for pre-computed natural NPP.
        observed_npp_asset_path: Asset for observed NPP annual tiles.
        structural_asset_path: Asset for structural integrity core area.
        bii_year: BII year to select for compositional integrity.
        absolute_diff_percentile: Percentile key for NPP absolute difference penalty.
        output_format: "dict" (default) or "geodataframe".

    Returns:
        A structured dictionary or GeoDataFrame depending on output_format.
        Point geometries return single values; area geometries return summary
        statistics in nested format: {"eii": {"mean": ..., "min": ...}}.

    Example:
        >>> import ee
        >>> ee.Initialize()
        >>> polygon = ee.Geometry.Rectangle([-60, -10, -55, -5])
        >>> stats = get_stats(polygon, stats=["mean", "min", "max"])
        >>> print(stats)
    """
    stats = _validate_stats_params(stats, percentiles)
    geometry = normalize_client_input(geometry, target="geometry")
    layers = get_layers(
        layers="all" if include_components else "eii",
        aggregation_method=aggregation_method,
        compute_mode=compute_mode,
        geometry=geometry,
        npp_year_range=npp_year_range,
        include_seasonality=include_seasonality,
        natural_npp_asset_path=natural_npp_asset_path,
        observed_npp_asset_path=observed_npp_asset_path,
        structural_asset_path=structural_asset_path,
        bii_year=bii_year,
        absolute_diff_percentile=absolute_diff_percentile,
    )
    eii_image = layers["eii"]

    is_point = _is_point_geometry(geometry).getInfo()
    geometry_type = geometry.type().getInfo()

    if is_point:
        eii_stats = _reduce_point_values(eii_image, geometry, scale).getInfo()
        values = _format_stats("eii", eii_stats, True, stats, percentiles)
    else:
        eii_stats = _reduce_area_stats(eii_image, geometry, scale, stats, percentiles).getInfo()
        values = _format_stats("eii", eii_stats, False, stats, percentiles)

    if include_components:
        components = {k: v for k, v in layers.items() if k != "eii"}
        for name, image in components.items():
            component_label = name if name.endswith("_integrity") else f"{name}_integrity"
            if is_point:
                comp_stats = _reduce_point_values(image, geometry, scale).getInfo()
                values.update(_format_stats(component_label, comp_stats, True, stats, percentiles))
            else:
                comp_stats = _reduce_area_stats(
                    image, geometry, scale, stats, percentiles
                ).getInfo()
                values.update(_format_stats(component_label, comp_stats, False, stats, percentiles))

    result = {"geometry_type": geometry_type, "values": values}

    if output_format == "geodataframe":
        geo_props = {"geometry_type": result["geometry_type"]}
        geo_props.update(result["values"])
        return _to_geodataframe(geometry, geo_props)

    return result

get_raster(geometry, aggregation_method='min_fuzzy_logic', include_components=True, scale=300, compute_mode='precomputed', npp_year_range=OBSERVED_NPP_YEAR_RANGE, include_seasonality=True, natural_npp_asset_path=NATURAL_NPP_ASSET_PATH, observed_npp_asset_path=OBSERVED_NPP_ASSET_PATH, structural_asset_path=None, bii_year=DEFAULT_BII_YEAR, absolute_diff_percentile='p95', max_area_sq_km=None, max_pixels=None, chunking='auto', tile_size_deg=1.0, tmp_dir=None, out_path=None, output_format='memory', compression=None, max_memory_fraction=0.25, dtype='float64', download_crs='EPSG:4326')

Download EII rasters for an AOI as an xarray Dataset.

Parameters:

Name Type Description Default
geometry Geometry

AOI geometry (ee.Geometry/Feature/FeatureCollection, GeoPandas, shapely, or bbox tuple).

required
aggregation_method AggregationMethod

EII aggregation method.

'min_fuzzy_logic'
include_components bool

If True, include component bands alongside EII.

True
scale int

Resolution in meters for export. Defaults to 300.

300
compute_mode ComputeMode

"precomputed" (default) or "on_the_fly".

'precomputed'
npp_year_range list[str]

Date range for observed NPP (on-the-fly mode).

OBSERVED_NPP_YEAR_RANGE
include_seasonality bool

Include seasonality in functional integrity.

True
natural_npp_asset_path str

Asset for pre-computed natural NPP.

NATURAL_NPP_ASSET_PATH
observed_npp_asset_path str

Asset for observed NPP annual tiles.

OBSERVED_NPP_ASSET_PATH
structural_asset_path str | None

Asset for structural integrity core area.

None
bii_year int

BII year to select for compositional integrity.

DEFAULT_BII_YEAR
absolute_diff_percentile str

Percentile key for NPP absolute difference penalty.

'p95'
max_area_sq_km float | None

Optional upper bound for AOI area before chunking.

None
max_pixels int | None

Optional upper bound for total pixels before chunking.

None
chunking Literal['auto', 'never', 'always']

"auto" (default), "never", or "always".

'auto'
tile_size_deg float

Tile size for chunked downloads in degrees.

1.0
tmp_dir str | None

Optional directory for intermediate downloads.

None
out_path str | None

Optional output path. For chunked downloads, use a directory (multiple files) or a file path for single GeoTIFF streaming output.

None
output_format Literal['memory', 'geotiff']

"memory" (default) or "geotiff".

'memory'
compression str | None

Compression codec for GeoTIFF (default ZSTD).

None
max_memory_fraction float

Fraction of available RAM used for auto chunking.

0.25
dtype Literal['float32', 'float64']

Output dtype for the xarray Dataset.

'float64'
download_crs str

CRS for downloads (default EPSG:4326).

'EPSG:4326'
Band order

"eii", "functional_integrity", "structural_integrity", "compositional_integrity".

Returns:

Type Description

xarray.Dataset when output_format="memory"; otherwise a Path (single download)

or list[Path] (chunked downloads) to the written files.

Source code in src/eii/client/retrieve.py
def get_raster(
    geometry: ee.Geometry,
    aggregation_method: AggregationMethod = "min_fuzzy_logic",
    include_components: bool = True,
    scale: int = 300,
    compute_mode: ComputeMode = "precomputed",
    npp_year_range: list[str] = OBSERVED_NPP_YEAR_RANGE,
    include_seasonality: bool = True,
    natural_npp_asset_path: str = NATURAL_NPP_ASSET_PATH,
    observed_npp_asset_path: str = OBSERVED_NPP_ASSET_PATH,
    structural_asset_path: str | None = None,
    bii_year: int = DEFAULT_BII_YEAR,
    absolute_diff_percentile: str = "p95",
    max_area_sq_km: float | None = None,
    max_pixels: int | None = None,
    chunking: Literal["auto", "never", "always"] = "auto",
    tile_size_deg: float = 1.0,
    tmp_dir: str | None = None,
    out_path: str | None = None,
    output_format: Literal["memory", "geotiff"] = "memory",
    compression: str | None = None,
    max_memory_fraction: float = 0.25,
    dtype: Literal["float32", "float64"] = "float64",
    download_crs: str = "EPSG:4326",
):
    """
    Download EII rasters for an AOI as an xarray Dataset.

    Args:
        geometry: AOI geometry (ee.Geometry/Feature/FeatureCollection, GeoPandas,
            shapely, or bbox tuple).
        aggregation_method: EII aggregation method.
        include_components: If True, include component bands alongside EII.
        scale: Resolution in meters for export. Defaults to 300.
        compute_mode: "precomputed" (default) or "on_the_fly".
        npp_year_range: Date range for observed NPP (on-the-fly mode).
        include_seasonality: Include seasonality in functional integrity.
        natural_npp_asset_path: Asset for pre-computed natural NPP.
        observed_npp_asset_path: Asset for observed NPP annual tiles.
        structural_asset_path: Asset for structural integrity core area.
        bii_year: BII year to select for compositional integrity.
        absolute_diff_percentile: Percentile key for NPP absolute difference penalty.
        max_area_sq_km: Optional upper bound for AOI area before chunking.
        max_pixels: Optional upper bound for total pixels before chunking.
        chunking: "auto" (default), "never", or "always".
        tile_size_deg: Tile size for chunked downloads in degrees.
        tmp_dir: Optional directory for intermediate downloads.
        out_path: Optional output path. For chunked downloads, use a directory
            (multiple files) or a file path for single GeoTIFF streaming output.
        output_format: "memory" (default) or "geotiff".
        compression: Compression codec for GeoTIFF (default ZSTD).
        max_memory_fraction: Fraction of available RAM used for auto chunking.
        dtype: Output dtype for the xarray Dataset.
        download_crs: CRS for downloads (default EPSG:4326).

    Band order:
        "eii", "functional_integrity", "structural_integrity", "compositional_integrity".

    Returns:
        xarray.Dataset when output_format="memory"; otherwise a Path (single download)
        or list[Path] (chunked downloads) to the written files.
    """
    geometry = normalize_client_input(geometry, target="geometry")
    if output_format == "geotiff" and compression is None:
        compression = "ZSTD"
    layers = get_layers(
        layers="all" if include_components else "eii",
        aggregation_method=aggregation_method,
        compute_mode=compute_mode,
        geometry=geometry,
        npp_year_range=npp_year_range,
        include_seasonality=include_seasonality,
        natural_npp_asset_path=natural_npp_asset_path,
        observed_npp_asset_path=observed_npp_asset_path,
        structural_asset_path=structural_asset_path,
        bii_year=bii_year,
        absolute_diff_percentile=absolute_diff_percentile,
    )

    band_images = [layers["eii"].rename("eii")]
    band_names = ["eii"]
    if include_components:
        for name in ("functional", "structural", "compositional"):
            band = layers[name].rename(f"{name}_integrity")
            band_images.append(band)
            band_names.append(f"{name}_integrity")

    image = ee.Image.cat(band_images).clip(geometry)
    area_sq_km = _estimate_area_sq_km(geometry)
    pixel_count = (area_sq_km * 1_000_000) / float(scale * scale)
    estimated_bytes = _estimate_bytes(area_sq_km, scale, len(band_names), dtype)

    available_bytes = _available_memory_bytes()
    auto_max_area = None
    if available_bytes is not None:
        auto_max_area = (available_bytes * max_memory_fraction) / _estimate_bytes(
            1.0, scale, len(band_names), dtype
        )

    effective_max_area = max_area_sq_km if max_area_sq_km is not None else auto_max_area

    exceeds_area = effective_max_area is not None and area_sq_km > effective_max_area
    exceeds_pixels = max_pixels is not None and pixel_count > max_pixels
    exceeds_memory = available_bytes is not None and estimated_bytes > (
        available_bytes * max_memory_fraction
    )

    if chunking == "never" and (exceeds_area or exceeds_pixels or exceeds_memory):
        raise ValueError("AOI exceeds configured limits; enable chunking or increase limits.")

    should_chunk = chunking == "always" or (
        chunking == "auto" and (exceeds_area or exceeds_pixels or exceeds_memory)
    )

    if not should_chunk:
        output_dir = Path(tmp_dir) if tmp_dir else Path(tempfile.mkdtemp())
        output_path = Path(out_path) if out_path else output_dir / "eii_download.tif"
        if output_path.is_dir():
            output_path = output_path / "eii_download.tif"

        _download_image_to_geotiff(image, geometry, scale, download_crs, output_path)
        if output_format == "memory":
            try:
                dataset = _geotiff_to_xarray_dataset(output_path, band_names, dtype)
            finally:
                if out_path is None:
                    shutil.rmtree(output_dir, ignore_errors=True)
        else:
            dataset = None

        if output_format == "geotiff":
            final_path = Path(out_path) if out_path else output_path
            if compression:
                dataset = _geotiff_to_xarray_dataset(output_path, band_names, dtype)
                _write_dataset_to_geotiff(dataset, final_path, compression)
                if final_path != output_path and output_path.exists():
                    output_path.unlink(missing_ok=True)
            return final_path

        dataset.attrs.update(
            {
                "eii_method": aggregation_method,
                "scale_m": scale,
                "area_sq_km": area_sq_km,
            }
        )
        return dataset

    if out_path is not None and output_format != "geotiff" and not Path(out_path).is_dir():
        raise ValueError("Chunked downloads require out_path to be a directory.")

    stream_single_geotiff = (
        output_format == "geotiff" and out_path is not None and not Path(out_path).is_dir()
    )
    output_dir = (
        Path(out_path)
        if out_path and Path(out_path).is_dir()
        else Path(tmp_dir or tempfile.mkdtemp())
    )
    output_dir.mkdir(parents=True, exist_ok=True)

    bounds = geometry.bounds(1).getInfo()["coordinates"][0]
    lons = [coord[0] for coord in bounds]
    lats = [coord[1] for coord in bounds]
    min_lon, max_lon = min(lons), max(lons)
    min_lat, max_lat = min(lats), max(lats)

    datasets = []
    output_paths: list[Path] = []
    tile_idx = 0
    lon = min_lon
    while lon < max_lon:
        next_lon = min(lon + tile_size_deg, max_lon)
        lat = min_lat
        while lat < max_lat:
            next_lat = min(lat + tile_size_deg, max_lat)
            tile_geom = ee.Geometry.Rectangle([lon, lat, next_lon, next_lat])
            tile_path = output_dir / f"eii_tile_{tile_idx}.tif"
            _download_image_to_geotiff(image, tile_geom, scale, download_crs, tile_path)
            if stream_single_geotiff:
                output_paths.append(tile_path)
            elif output_format == "geotiff":
                if compression:
                    dataset = _geotiff_to_xarray_dataset(tile_path, band_names, dtype)
                    compressed_path = output_dir / f"eii_tile_{tile_idx}_compressed.tif"
                    _write_dataset_to_geotiff(dataset, compressed_path, compression)
                    tile_path.unlink(missing_ok=True)
                    output_paths.append(compressed_path)
                else:
                    output_paths.append(tile_path)
            else:
                datasets.append(_geotiff_to_xarray_dataset(tile_path, band_names, dtype))
            tile_idx += 1
            lat = next_lat
        lon = next_lon

    if output_format == "geotiff" and stream_single_geotiff:
        assert out_path is not None
        final_path = Path(out_path)
        _stream_tiles_to_geotiff(
            output_paths,
            final_path,
            [min_lon, min_lat, max_lon, max_lat],
            compression,
            band_names,
        )
        if tmp_dir is None:
            shutil.rmtree(output_dir, ignore_errors=True)
        else:
            for tile_path in output_paths:
                tile_path.unlink(missing_ok=True)
        return final_path

    if output_format == "geotiff":
        return output_paths

    try:
        import xarray as xr
    except Exception as exc:  # pragma: no cover - optional dependency
        raise RuntimeError("xarray is required for raster downloads") from exc

    dataset = xr.combine_by_coords(datasets, combine_attrs="override")
    dataset.attrs.update(
        {
            "eii_method": aggregation_method,
            "scale_m": scale,
            "area_sq_km": area_sq_km,
            "chunked": True,
            "tile_size_deg": tile_size_deg,
        }
    )

    if out_path is None and tmp_dir is None:
        shutil.rmtree(output_dir, ignore_errors=True)

    return dataset

get_layers(layers='all', aggregation_method='min_fuzzy_logic', compute_mode='precomputed', geometry=None, npp_year_range=OBSERVED_NPP_YEAR_RANGE, include_seasonality=True, natural_npp_asset_path=NATURAL_NPP_ASSET_PATH, observed_npp_asset_path=OBSERVED_NPP_ASSET_PATH, structural_asset_path=None, bii_year=DEFAULT_BII_YEAR, absolute_diff_percentile='p95')

Get EII and/or component layers for a given geometry and computation mode.

Parameters:

Name Type Description Default
layers LayerSelection

Which layers to return: "eii", "components", or "all".

'all'
aggregation_method AggregationMethod

EII aggregation method.

'min_fuzzy_logic'
compute_mode ComputeMode

"precomputed" (default) or "on_the_fly".

'precomputed'
geometry Geometry | None

Optional geometry for on-the-fly component calculation.

None
npp_year_range list[str]

Date range for observed NPP (on-the-fly mode).

OBSERVED_NPP_YEAR_RANGE
include_seasonality bool

Include seasonality in functional integrity.

True
natural_npp_asset_path str

Asset for pre-computed natural NPP.

NATURAL_NPP_ASSET_PATH
observed_npp_asset_path str

Asset for observed NPP annual tiles.

OBSERVED_NPP_ASSET_PATH
structural_asset_path str | None

Asset for structural integrity core area.

None
bii_year int

BII year to select for compositional integrity.

DEFAULT_BII_YEAR
absolute_diff_percentile str

Percentile key for NPP absolute difference penalty.

'p95'

Returns:

Type Description
dict[str, Image]

Dictionary of Earth Engine images. Keys include "eii" and/or component

dict[str, Image]

names ("functional", "structural", "compositional").

Example

layers = get_layers(layers="all") eii = layers["eii"].clip(my_polygon)

Source code in src/eii/client/retrieve.py
def get_layers(
    layers: LayerSelection = "all",
    aggregation_method: AggregationMethod = "min_fuzzy_logic",
    compute_mode: ComputeMode = "precomputed",
    geometry: ee.Geometry | None = None,
    npp_year_range: list[str] = OBSERVED_NPP_YEAR_RANGE,
    include_seasonality: bool = True,
    natural_npp_asset_path: str = NATURAL_NPP_ASSET_PATH,
    observed_npp_asset_path: str = OBSERVED_NPP_ASSET_PATH,
    structural_asset_path: str | None = None,
    bii_year: int = DEFAULT_BII_YEAR,
    absolute_diff_percentile: str = "p95",
) -> dict[str, ee.Image]:
    """
    Get EII and/or component layers for a given geometry and computation mode.

    Args:
        layers: Which layers to return: "eii", "components", or "all".
        aggregation_method: EII aggregation method.
        compute_mode: "precomputed" (default) or "on_the_fly".
        geometry: Optional geometry for on-the-fly component calculation.
        npp_year_range: Date range for observed NPP (on-the-fly mode).
        include_seasonality: Include seasonality in functional integrity.
        natural_npp_asset_path: Asset for pre-computed natural NPP.
        observed_npp_asset_path: Asset for observed NPP annual tiles.
        structural_asset_path: Asset for structural integrity core area.
        bii_year: BII year to select for compositional integrity.
        absolute_diff_percentile: Percentile key for NPP absolute difference penalty.

    Returns:
        Dictionary of Earth Engine images. Keys include "eii" and/or component
        names ("functional", "structural", "compositional").

    Example:
        >>> layers = get_layers(layers="all")
        >>> eii = layers["eii"].clip(my_polygon)
    """
    if geometry is not None:
        geometry = normalize_client_input(geometry, target="geometry")

    if compute_mode == "precomputed" and aggregation_method != "min_fuzzy_logic":
        raise ValueError(
            "Only the pre-computed default method is available. "
            "Use compute_mode='on_the_fly' for other aggregation methods."
        )

    include_eii = layers in ("eii", "all")
    include_components = layers in ("components", "all")

    result: dict[str, ee.Image] = {}
    components: dict[str, ee.Image] | None = None

    if include_components:
        if compute_mode == "precomputed":
            mosaic = ee.Image(get_asset_path("components"))
            components = {
                "functional": mosaic.select("functional_integrity"),
                "structural": mosaic.select("structural_integrity"),
                "compositional": mosaic.select("compositional_integrity"),
            }
        elif compute_mode == "on_the_fly":
            functional_result = calculate_functional_integrity(
                aoi=geometry,
                year_range=npp_year_range,
                include_seasonality=include_seasonality,
                natural_npp_asset_path=natural_npp_asset_path,
                observed_npp_asset_path=observed_npp_asset_path,
                absolute_diff_percentile=absolute_diff_percentile,
            )
            structural = _get_structural_integrity_precomputed(
                aoi=geometry,
                asset_path=structural_asset_path,
            )
            compositional = calculate_compositional_integrity(aoi=geometry, year=bii_year)
            components = {
                "functional": functional_result["functional_integrity"],
                "structural": structural,
                "compositional": compositional,
            }
        else:
            raise ValueError("compute_mode must be one of: 'precomputed', 'on_the_fly'")

        result.update(components)

    if include_eii:
        if compute_mode == "precomputed":
            result["eii"] = ee.Image(get_asset_path("eii")).select("eii")
        else:
            if components is None:
                components = get_layers(
                    layers="components",
                    aggregation_method=aggregation_method,
                    compute_mode=compute_mode,
                    geometry=geometry,
                    npp_year_range=npp_year_range,
                    include_seasonality=include_seasonality,
                    natural_npp_asset_path=natural_npp_asset_path,
                    observed_npp_asset_path=observed_npp_asset_path,
                    structural_asset_path=structural_asset_path,
                    bii_year=bii_year,
                    absolute_diff_percentile=absolute_diff_percentile,
                )
            result["eii"] = combine_components(
                functional=components["functional"],
                structural=components["structural"],
                compositional=components["compositional"],
                method=aggregation_method,
            ).rename("eii")

    return result

Asset Management

Google Earth Engine asset paths and metadata for EII data products.

This module contains the paths to pre-computed EII data assets in Google Earth Engine.

get_asset_info(asset_name)

Get full metadata for an asset.

Parameters:

Name Type Description Default
asset_name str

Name of the asset

required

Returns:

Type Description
dict[str, Any]

Dictionary containing asset metadata (path, description, bands, etc.)

get_asset_path(asset_name)

Get the Earth Engine asset path for a given asset name.

Parameters:

Name Type Description Default
asset_name str

Name of the asset (e.g., 'eii', 'components', 'npp_predictions')

required

Returns:

Type Description
str

The full Earth Engine asset path.

Raises:

Type Description
KeyError

If the asset name is not found.

Example

path = get_asset_path("eii") print(path) 'projects/landler-open-data/assets/eii/scores/eii'