gedih3.gh3driver#
Functions#
|
|
|
|
|
|
|
|
|
Return the H3 partition cell IDs of a database that may hold shots for |
|
|
|
Write simplified metadata for extracted/aggregated datasets. |
|
|
|
|
|
|
|
|
|
|
|
Load H3-indexed GEDI data from any source. |
|
Aggregate H3-indexed GEDI data to a coarser H3 resolution. |
|
Export a single partition to file with a simple naming convention. |
|
Export a Dask DataFrame to simplified flat files with metadata. |
|
Load EGI-indexed GEDI data from any source. |
|
Aggregate H3-indexed DataFrame to EGI (EASE Grid Index) pixels. |
|
Add EGI pixel geometry to an EGI-indexed DataFrame. |
|
Aggregate GEDI data to EGI (EASE Grid Index) square pixels. |
|
Extract H3-indexed GEDI data with EGI spatial indexing. |
|
Export a single EGI partition to file(s). |
|
Check if a DataFrame is EGI-indexed. |
Determine the spatial index type of a DataFrame. |
|
|
Convert H3-indexed GeoDataFrame to raster. |
|
Rasterize Dask GeoDataFrame partitions to individual GeoTIFF files. |
|
Sample raster pixel values at GEDI shot locations. |
Module Contents#
- gedih3.gh3driver.gh3_select_partitions(source, region=None)[source]#
Return the H3 partition cell IDs of a database that may hold shots for
region.This is the canonical, overhang-safe way to determine which partition files a region touches, and the function external consumers should use when reading the H3 database directly (i.e. not through
gh3_load()). It applies the same ring-1 expansiongh3_loaduses internally.H3 partitions are not geometrically inclusive of the shots stored in them: a shot is filed under
cell_to_parent(latlng_to_cell(lon, lat, index_res), partition_res), whose polygon a boundary shot can sit outside of by up to ~0.18 x the partition’s edge length (~11 km at partition level 3). Selecting partitions by an exact polygon intersection therefore silently drops boundary shots (~5% of a boundary partition’s shots observed in production). The ring-1 expansion applied here closes that gap; it is guaranteed sufficient because the overhang is far smaller than one cell width. See the “Parent/Child Nesting Caveat” in the H3 Indexing docs for the full explanation.- Parameters:
- sourcestr
Path to an H3 database (the directory holding
gedih3_build_log.json).- regionstr | list | GeoDataFrame | GeoSeries | shapely geometry, optional
ROI as a vector-file path /
"W,S,E,N"string,[W, S, E, N]bbox list, geopandas object, or shapely geometry (EPSG:4326). WhenNone(default), every partition in the database is returned.
- Returns:
- list[str]
Sorted H3 partition cell IDs at the database’s partition level.
- Raises:
- GediDatabaseNotFoundError
If
sourcehas no readable build log / partition list.
Examples
>>> ids = gh3_select_partitions('/data/h3db', region='roi.shp') >>> ids[:2] ['83804cfffffffff', '838041fffffffff'] >>> # Map ids -> files when reading outside gh3_load: >>> import glob >>> files = [f for i in ids ... for f in glob.glob(f'/data/h3db/h3_03={i}/year=*/*.parquet')]
- gedih3.gh3driver.gh3_write_dataset_meta(opath, index_type='h3', index_level=None, columns=None, source_database=None, query_filter=None, tool=None, file_format='parquet', **kwargs)[source]#
Write simplified metadata for extracted/aggregated datasets.
This creates a single metadata file for user-friendly outputs (not hive-partitioned), making it easy to understand and use the data outside of gedih3 tools.
- Parameters:
- opathstr
Output directory path
- index_typestr
Type of spatial index (‘h3’ or ‘egi’)
- index_levelint
Resolution level of the index
- columnslist
List of data columns
- source_databasestr
Path to source H3 database (if applicable)
- query_filterstr
Query string used for filtering
- toolstr
Name of the tool that created this dataset
- file_formatstr
Output file format (e.g. ‘parquet’, ‘feather’, ‘gpkg’)
- **kwargs
Additional metadata to include
- gedih3.gh3driver.gh3_load(source=None, *, columns=None, region=None, query=None, from_map=True, lazy=True, filters=None)[source]#
Load H3-indexed GEDI data from any source.
Auto-detects whether the source is an H3 database, simplified dataset, or parquet directory and loads accordingly.
- Parameters:
- sourcestr, optional
Path to data source (H3 database, simplified dataset, or parquet dir). If None, falls back to default H3 directory.
- columnslist, optional
Columns to load.
- regionGeoDataFrame or bbox, optional
Spatial filter.
- querystr, optional
Pandas query string for filtering.
- from_mapbool
Use from_map loading for H3 databases (default True).
- lazybool
If True (default), return Dask DataFrame. If False, return computed pandas DataFrame.
- filterslist, optional
PyArrow predicate pushdown filters (conjunctive list of
(column, op, value)tuples), applied as per-file row-group pushdown during the read. Works for H3 databases and simplified parquet datasets, and combines (AND) withregionwhen both are given.
- Returns:
- dask GeoDataFrame or GeoDataFrame
Loaded data (lazy by default, eager if lazy=False).
- Raises:
- GediValidationError
If the source is an EGI-indexed dataset (use
egi_load()instead).- GediDatabaseNotFoundError
If no valid data source is found.
Examples
>>> import gedih3.gh3driver as gh3 >>> ddf = gh3.gh3_load( ... source='/path/to/h3_database', ... columns=['agbd_l4a', 'rh_098_l2a'], ... region='region.shp', ... ) >>> ddf.compute().head()
- gedih3.gh3driver.gh3_aggregate(gh3_df, target_res=5, agg='mean', columns=None, query=None, add_geometry=True, repartition=False, partition_level=None, **kwargs)[source]#
Aggregate H3-indexed GEDI data to a coarser H3 resolution.
Uses map_partitions for efficient processing when data is loaded with from_map=True (each partition corresponds to a single H3 partition cell).
- Parameters:
- gh3_dfdask GeoDataFrame
H3-indexed GEDI data loaded via gh3_load()
- target_resint
Target H3 resolution level (0-15, lower = coarser)
- aggstr, list, dict, or callable
Aggregation specification (same as pandas groupby.agg)
- columnslist, optional
Columns to aggregate (if None, all numeric columns)
- querystr, optional
Pandas query string for filtering before aggregation
- add_geometrybool
If True, add H3 polygon geometries to output
- repartitionbool
If True, repartition by H3 partition column for export
- partition_levelint, optional
Explicit H3 partition level. Used as fallback when the DataFrame lacks h3_XX columns (e.g., loaded from a simplified dataset).
- **kwargs
Additional arguments passed to aggregation function
- Returns:
- dask GeoDataFrame
H3-indexed aggregated data.
- Raises:
- H3ValidationError
If
target_resis not a valid H3 resolution (0–15).- GediAggregationError
If spatial aggregation fails.
- gedih3.gh3driver.gh3_export_part(df, odir, fmt='parquet', is_file_path=False, part_col=None, group_by_partition=False, naming_partition_level=None)[source]#
Export a single partition to file with a simple naming convention.
Creates user-friendly output files named by partition ID (e.g., ‘abc123.parquet’), not hive-style directories.
- Parameters:
- dfDataFrame or GeoDataFrame
Data partition to export
- odirstr
Output directory or file path
- fmtstr
Output format (‘parquet’, ‘gpkg’, ‘geojson’, ‘csv’, etc.)
- is_file_pathbool
If True, odir is treated as a complete file path
- part_colstr, optional
Partition column name to use for naming. If None, auto-detect.
- group_by_partitionbool
If True and part_col is specified, group data by partition column and write separate files for each unique partition ID within this Dask partition. Use this after shuffling data by partition column (via set_index) to ensure each unique partition ID is in exactly one Dask partition, avoiding file collision issues.
- naming_partition_levelint, optional
H3 resolution level for deriving file names via cell_to_parent. Used when no partition column is available (e.g., aggregated data).
- Returns:
- str
Output file path(s). Comma-separated if multiple files written.
- gedih3.gh3driver.gh3_export(ddf, output, fmt='parquet', merge=False, show_progress=True, drop_internal=False, write_metadata=True, source_database=None, tool=None, h3_partition_level=None, **metadata_kwargs)[source]#
Export a Dask DataFrame to simplified flat files with metadata.
This is the high-level export function that encapsulates the full export pipeline: persist, write partition files, and write dataset metadata. It replaces the boilerplate pattern of map_partitions + persist + progress + gh3_write_dataset_meta.
- Parameters:
- ddfdask DataFrame or GeoDataFrame
Data to export. Should already be persisted if it represents an expensive computation (e.g., aggregation result).
- outputstr
Output directory path
- fmtstr
Output format (‘parquet’, ‘feather’, ‘gpkg’, etc.)
- mergebool
If True, compute and write a single merged file instead of per-partition files.
- show_progressbool
If True and a Dask distributed client is available, show progress bar.
- drop_internalbool
If True, drop internal columns (h3_XX, egiXX, _egi_x/y, shot_number*) before export. Default False — internal columns are kept so downstream tools can join on shot_number or spatial indexes.
- write_metadatabool
If True, write dataset metadata file.
- source_databasestr, optional
Path to source H3 database (recorded in metadata).
- toolstr, optional
Name of the tool creating this dataset (recorded in metadata).
- h3_partition_levelint, optional
H3 resolution level to use for naming output files. When provided, files are named by the parent cell at this level (via h3.cell_to_parent). Useful for aggregated data where the original partition column was lost. If None, auto-detected from source_database metadata when available.
- **metadata_kwargs
Additional key-value pairs to include in the dataset metadata. Common keys: query_filter, aggregation, egi_index_level, egi_partition_level, h3_partition_level, image_source, etc.
- Returns:
- list of str
Paths to output files created.
Examples
>>> import gedih3.gh3driver as gh3 >>> ddf = gh3.gh3_load(source='/db', columns=['agbd_l4a'], region='roi.shp') >>> gh3.gh3_export(ddf, '/tmp/test_export/') >>> >>> # Merged export >>> gh3.gh3_export(ddf, '/tmp/merged/', merge=True) >>> >>> # With metadata >>> gh3.gh3_export(ddf, '/tmp/out/', source_database='/db', tool='my_script', ... query_filter='quality_flag == 1')
- gedih3.gh3driver.egi_load(source=None, *, columns=None, region=None, query=None, index_level=1, partition_level=12, lazy=True)[source]#
Load EGI-indexed GEDI data from any source.
Auto-detects whether the source is an H3 database (direct EGI loading) or a simplified EGI dataset and loads accordingly.
- Parameters:
- sourcestr, optional
Path to data source (H3 database or EGI dataset). If None, falls back to default H3 directory.
- columnslist, optional
Columns to load.
- regionGeoDataFrame or bbox, optional
Spatial filter.
- querystr, optional
Pandas query string for filtering.
- index_levelint
EGI resolution level for fine indexing (1-12, default=1 ~1m). Only used when loading from H3 database.
- partition_levelint
EGI level for output partitioning (1-12, default=12 ~160km). Only used when loading from H3 database.
- lazybool
If True (default), return Dask DataFrame. If False, return computed pandas DataFrame.
- Returns:
- dask GeoDataFrame or GeoDataFrame
EGI-indexed data (lazy by default, eager if lazy=False).
- Raises:
- GediValidationError
If source is an H3 dataset (use
gh3_load()instead).- GediDatabaseNotFoundError
If no valid data source is found.
- EGIValidationError
If
index_levelorpartition_levelis outside [1, 12].
Examples
>>> import gedih3.gh3driver as gh3 >>> ddf = gh3.egi_load( ... source='/path/to/h3_database', ... columns=['agbd_l4a'], ... region='region.shp', ... index_level=1, ... partition_level=12, ... ) >>> agg = gh3.egi_aggregate(ddf, target_level=6, agg='mean')
- gedih3.gh3driver.egi_aggregate_func(df, level, agg='mean', cols=None, x_col='lon_lowestmode', y_col='lat_lowestmode', **kwargs)[source]#
Aggregate H3-indexed DataFrame to EGI (EASE Grid Index) pixels.
This function converts H3-indexed GEDI data to EGI square pixels, which are compatible with GEDI L4B products and standard raster formats.
- Parameters:
- dfDataFrame or GeoDataFrame
H3-indexed GEDI data (GeoDataFrame with Point geometry preferred)
- levelint
Target EGI resolution level (1-12)
- aggstr, list, dict, or callable
Aggregation specification (same as pandas groupby.agg)
- colslist, optional
Columns to aggregate (numeric columns only)
- x_colstr
Longitude column name (default: ‘lon_lowestmode’). Only used if df is not a GeoDataFrame with Point geometry.
- y_colstr
Latitude column name (default: ‘lat_lowestmode’). Only used if df is not a GeoDataFrame with Point geometry.
- **kwargs
Additional arguments passed to aggregation function
- Returns:
- DataFrame or GeoDataFrame
EGI-indexed aggregated data
- gedih3.gh3driver.egi_add_geometry(df, polygons=True)[source]#
Add EGI pixel geometry to an EGI-indexed DataFrame.
- Parameters:
- dfDataFrame
EGI-indexed DataFrame
- polygonsbool
If True, use polygon geometries; if False, use centroids
- Returns:
- GeoDataFrame
GeoDataFrame with geometry column
- gedih3.gh3driver.egi_aggregate(gh3_df, target_level=6, agg='mean', columns=None, query=None, add_geometry=True, x_col='lon_lowestmode', y_col='lat_lowestmode', partition_level=12, repartition=False, **kwargs)[source]#
Aggregate GEDI data to EGI (EASE Grid Index) square pixels.
Supports two input types:
EGI-indexed (from egi_load()): Fast path — no shuffle needed, aggregation is purely local within each partition.
H3-indexed (from gh3_load()): Shuffle path — data is repartitioned by EGI tiles before local aggregation.
- Parameters:
- gh3_dfdask GeoDataFrame
GEDI data loaded via egi_load() (EGI-indexed) or gh3_load() (H3-indexed)
- target_levelint
Target EGI resolution level (1-12): - Level 6 (~1km): GEDI baseline - Level 7 (~2km): GEDI threshold - Level 8 (~10km): GEDI wall-to-wall
- aggstr, list, dict, or callable
Aggregation specification (same as pandas groupby.agg)
- columnslist, optional
Columns to aggregate (if None, all numeric columns)
- querystr, optional
Pandas query string for filtering before aggregation
- add_geometrybool
If True, add pixel polygon geometries to output
- x_colstr
Longitude column name for coordinate lookup (shuffle path only)
- y_colstr
Latitude column name for coordinate lookup (shuffle path only)
- partition_levelint
EGI level for output partitioning and data shuffling (1-12, default=12 ~160km). Higher levels = coarser tiles = fewer unique keys = more efficient shuffle. Use smaller values for regions with many variables to reduce file sizes.
- repartitionbool
If True, add partition column for organized export
- **kwargs
Additional arguments passed to aggregation function
- Returns:
- dask GeoDataFrame
EGI-indexed aggregated data
- gedih3.gh3driver.egi_extract(gh3_df, index_level=1, partition_level=12, query=None, add_geometry=True, x_col='lon_lowestmode', y_col='lat_lowestmode')[source]#
Extract H3-indexed GEDI data with EGI spatial indexing.
This function converts H3-indexed GEDI shots to EGI-indexed data without aggregation. It repartitions data by EGI tiles for efficient H3->EGI conversion.
- Parameters:
- gh3_dfdask GeoDataFrame
H3-indexed GEDI data loaded via gh3_load()
- index_levelint
EGI resolution level for fine indexing (1-12, default=1 ~1m)
- partition_levelint
EGI level for output file partitioning and shuffling (1-12, default=12 ~160km). Higher levels = coarser tiles = fewer unique keys = more efficient shuffle.
- querystr, optional
Pandas query string for filtering before extraction
- add_geometrybool
If True, add Point geometries to output (in WGS84/EPSG:4326)
- x_colstr
Longitude column name for coordinate lookup
- y_colstr
Latitude column name for coordinate lookup
- Returns:
- dask GeoDataFrame
EGI-indexed data with all original columns plus EGI index columns
- gedih3.gh3driver.egi_export_part(df, odir, fmt='parquet', is_file_path=False, partition_level=12)[source]#
Export a single EGI partition to file(s).
Splits the data by partition tile and writes one file per unique tile. File names are the EGI hash of the partition tile at the requested level.
- Parameters:
- dfDataFrame or GeoDataFrame
EGI-indexed data partition
- odirstr
Output directory or file path
- fmtstr
Output format (‘parquet’, ‘gpkg’, ‘geojson’, ‘tif’, etc.)
- is_file_pathbool
If True, odir is treated as a complete file path (single output)
- partition_levelint
EGI level used for output file naming (1-12, default=12). Used as a fallback when no egiXX column is present in the DataFrame.
- Returns:
- str
Output file path(s) - comma-separated if multiple files written
- gedih3.gh3driver.is_egi_indexed(df)[source]#
Check if a DataFrame is EGI-indexed.
- Parameters:
- dfDataFrame or GeoDataFrame
DataFrame to check
- Returns:
- bool
True if EGI-indexed, False otherwise
- gedih3.gh3driver.get_spatial_index_type(df)[source]#
Determine the spatial index type of a DataFrame.
- Parameters:
- dfDataFrame or GeoDataFrame
DataFrame to check
- Returns:
- str
‘h3’, ‘egi’, or None
- gedih3.gh3driver.gh3_to_raster(gdf, columns=None, output_path=None, compress='LZW')[source]#
Convert H3-indexed GeoDataFrame to raster.
This is a convenience function that wraps the raster module’s h3_to_raster function with sensible defaults.
- Parameters:
- gdfGeoDataFrame
H3-indexed GeoDataFrame with polygon geometries
- columnslist of str, optional
Columns to rasterize. If None, all numeric columns.
- output_pathstr, optional
If provided, save raster to this path
- compressstr
Compression method for GeoTIFF
- Returns:
- xr.Dataset
Raster dataset
Examples
>>> # Rasterize aggregated data >>> raster = gh3_to_raster(agg_gdf) >>> raster.rio.to_raster("output.tif") >>> >>> # Or save directly >>> raster = gh3_to_raster(agg_gdf, output_path="output.tif")
- gedih3.gh3driver.gh3_rasterize_partitions(ddf, output_dir, columns=None, compress='LZW', show_progress=True, partition_level=None)[source]#
Rasterize Dask GeoDataFrame partitions to individual GeoTIFF files.
- Parameters:
- ddfdask GeoDataFrame
H3-indexed Dask GeoDataFrame
- output_dirstr
Output directory for raster files
- columnslist of str, optional
Columns to rasterize
- compressstr
Compression method for GeoTIFF
- show_progressbool
Show Dask progress bar
- partition_levelint, optional
H3 partition level for grouping/naming tiles. If None, auto-detected from data columns or defaults to treating each partition as one tile.
- Returns:
- list of str
Paths to output files
- gedih3.gh3driver.gh3_sample_raster(image_path, data_source=None, region=None, query=None, band_names=None, band_indices=None, window_ops=None, fillna=None, dropna=False, geo=False, file_format='tif')[source]#
Sample raster pixel values at GEDI shot locations.
Thin wrapper around
imgutils.from_image()for API discoverability. Returns a Dask DataFrame; usegh3_export()to save results.- Parameters:
- image_pathstr
Path to raster file, VRT, or tile directory
- data_sourcestr, optional
Path to H3 database or simplified dataset directory
- regionGeoDataFrame or bbox, optional
Additional spatial filter
- querystr, optional
Pandas query string for filtering shots
- band_nameslist of str, optional
Custom names for output band columns
- band_indiceslist of int, optional
Select specific bands by 0-based index
- window_opslist of dict, optional
Window operation specifications
- fillnafloat, optional
Fill NaN/NoData with this value
- dropnabool
If True, drop rows where all band columns are NaN
- geobool
If True, include geometry in output
- file_formatstr
Raster file extension for tile directory globbing
- Returns:
- dask DataFrame or GeoDataFrame
Sampled raster values at GEDI shot locations
Examples
>>> import gedih3.gh3driver as gh3 >>> ddf = gh3.gh3_sample_raster( ... 'dem.tif', data_source='/path/to/database', ... band_names=['elevation'], geo=True ... ) >>> gh3.gh3_export(ddf, '/tmp/sampled/')