gedih3.egi.spatial#
EGI (EASE Grid Index) Spatial Module
This module provides spatial operations for EGI indices including: - Coordinate extraction from hashes - Geometry generation (points and polygons) - Neighbor finding (pixel ring) - Child pixel enumeration - Area of Interest (AOI) tile generation
Functions#
|
Clamp coordinates to EPSG:6933 valid bounds. |
|
Get the coordinate of an EGI pixel. |
|
Get coordinates for multiple EGI pixels (vectorized). |
|
Get the bounding polygon of an EGI pixel. |
|
Get the 8 neighboring pixels (ring) around an EGI pixel. |
|
Generate outer tiles (level 12) covering an area of interest. |
|
Convert EGI hashes to a GeoDataFrame. |
|
Map EGI tiles to intersecting H3 partition cells using spatial index. |
Module Contents#
- gedih3.egi.spatial.check_crs_limits(x: float | numpy.typing.NDArray[numpy.floating], y: float | numpy.typing.NDArray[numpy.floating]) Tuple[float | numpy.typing.NDArray[numpy.floating], float | numpy.typing.NDArray[numpy.floating]][source]#
Clamp coordinates to EPSG:6933 valid bounds.
- Parameters:
- xfloat or array
X coordinate(s) in EPSG:6933
- yfloat or array
Y coordinate(s) in EPSG:6933
- Returns:
- tuple
(x, y) clamped to valid bounds
- gedih3.egi.spatial.pixel_coordinate(uint_hash: numpy.uint64, center: bool = True, return_point: bool = False) Tuple[float, float] | shapely.geometry.Point[source]#
Get the coordinate of an EGI pixel.
- Parameters:
- uint_hashuint64
EGI hash value
- centerbool
If True, return pixel center; if False, return lower-left corner
- return_pointbool
If True, return a Shapely Point; if False, return (x, y) tuple
- Returns:
- tuple or Point
(x, y) coordinates in EPSG:6933, or Shapely Point
Examples
>>> x, y = pixel_coordinate(hash_val) >>> point = pixel_coordinate(hash_val, return_point=True)
- gedih3.egi.spatial.pixel_coordinates(uint_hash: numpy.typing.NDArray[numpy.uint64], center: bool = True) Tuple[numpy.typing.NDArray[numpy.floating], numpy.typing.NDArray[numpy.floating]][source]#
Get coordinates for multiple EGI pixels (vectorized).
- Parameters:
- uint_hasharray of uint64
EGI hash values
- centerbool
If True, return pixel centers; if False, return lower-left corners
- Returns:
- tuple
(x_array, y_array) coordinates in EPSG:6933
- gedih3.egi.spatial.pixel_shape(uint_hash: numpy.uint64) shapely.geometry.Polygon[source]#
Get the bounding polygon of an EGI pixel.
- Parameters:
- uint_hashuint64
EGI hash value
- Returns:
- Polygon
Shapely polygon representing the pixel bounds
Examples
>>> geom = pixel_shape(hash_val) >>> area_m2 = geom.area
- gedih3.egi.spatial.pixel_ring(uint_hash: numpy.uint64, include_input: bool = False) List[numpy.uint64][source]#
Get the 8 neighboring pixels (ring) around an EGI pixel.
- Parameters:
- uint_hashuint64
EGI hash value (center pixel)
- include_inputbool
If True, include the input pixel in the result
- Returns:
- list of uint64
EGI hashes of neighboring pixels (up to 8)
Notes
Pixels at the edge of the projection bounds will have fewer than 8 neighbors. The function correctly handles tile boundary crossings.
- gedih3.egi.spatial.aoi_tiles(region: geopandas.GeoDataFrame | None = None) geopandas.GeoDataFrame[source]#
Generate outer tiles (level 12) covering an area of interest.
- Parameters:
- regionGeoDataFrame, optional
Area of interest. If None, returns all global tiles.
- Returns:
- GeoDataFrame
Tiles indexed by EGI level-12 hash with polygon geometries
- Raises:
- ValueError
If region has no CRS defined
Examples
>>> # Get tiles for a specific region >>> region = gpd.read_file("study_area.shp") >>> tiles = aoi_tiles(region) >>> >>> # Get all global tiles >>> all_tiles = aoi_tiles()
- gedih3.egi.spatial.to_geodataframe(uint_hash_iter: List[numpy.uint64] | numpy.typing.NDArray[numpy.uint64], return_polygons: bool = True) geopandas.GeoDataFrame[source]#
Convert EGI hashes to a GeoDataFrame.
- Parameters:
- uint_hash_iterlist or array of uint64
EGI hash values
- return_polygonsbool
If True, return polygon geometries; if False, return point centroids
- Returns:
- GeoDataFrame
GeoDataFrame indexed by EGI hash with geometry column
Examples
>>> gdf = to_geodataframe(egi_hashes, return_polygons=True)
- gedih3.egi.spatial.egi_h3_intersection(egi_tiles: geopandas.GeoDataFrame, h3_gdf: geopandas.GeoDataFrame) dict[source]#
Map EGI tiles to intersecting H3 partition cells using spatial index.
- Maps each EGI tile to the union of:
H3 cells whose polygon geometrically intersects the EGI tile, AND
the ring-1 neighbors of those cells that are valid partitions.
Adding ring-1 neighbors closes a silent data-loss class on the EGI extraction path. The H3 database stores each shot in the partition cell_to_parent(latlng_to_cell(lon, lat, finer_res), partition_res), but partition assignment via geometric overlap of the H3 polygon uses the L3 latlng_to_cell boundary — and these two functions disagree at H3 cell boundaries (boundary-precision differs across resolutions). Shots at a partition boundary can therefore land in a storage cell whose polygon does not overlap their true EGI tile, so the unexpanded intersection silently misses them — observed in production: a single L3 partition with 1.84M shots had 84k (~5%) stored under a partition whose polygon did not intersect their true L12 tile. Including ring-1 neighbors closes this gap because the “fat-partition” extent is bounded by one neighbor-cell width.
- Parameters:
- egi_tilesGeoDataFrame
EGI tiles (typically level 12), indexed by EGI hash
- h3_gdfGeoDataFrame
H3 partition cells, indexed by H3 ID (string)
- Returns:
- dict
Mapping of EGI tile hash -> list of H3 IDs (with ring-1 expansion).
Examples
>>> egi_tiles = aoi_tiles(region) >>> h3_gdf = h3_parts_to_gdf(h3_ids) >>> egi_to_h3 = egi_h3_intersection(egi_tiles, h3_gdf) >>> for egi_id, h3_list in egi_to_h3.items(): ... # Load data from h3_list files for egi_id tile