gedih3.egi.core#

EGI (EASE Grid Index) Core Module

This module provides the fundamental hash encoding and decoding functions for the EGI spatial indexing system. The hash encodes spatial location and resolution level into a single uint64 value.

Hash Structure (uint64):

level * 1e18 + px_outer * 1e15 + py_outer * 1e12 + px_inner * 1e6 + py_inner

  • level (1-12): Resolution level encoded in digits 19-20

  • px_outer: Outer tile X index (0-215) encoded in digits 16-18

  • py_outer: Outer tile Y index (0-90) encoded in digits 13-15

  • px_inner: Inner pixel X index within tile encoded in digits 7-12

  • py_inner: Inner pixel Y index within tile encoded in digits 1-6

Data Type Considerations:
  • Hash values MUST use np.uint64 for 64-bit precision

  • Intermediate calculations use appropriate uint16/uint32 to prevent overflow

  • Coordinate divisions must use exact type casting to preserve precision

Functions#

hasher(→ Union[numpy.uint64, ...)

Construct EGI hash from component parts.

to_hash(→ Union[numpy.uint64, ...)

Convert EPSG:6933 coordinates to EGI hash.

from_hash(→ Tuple[Union[int, ...)

Decode EGI hash into its component parts.

get_level(→ Union[int, ...)

Extract the resolution level from an EGI hash.

get_scale(→ Union[float, ...)

Get the pixel size in meters for an EGI hash.

to_parent(→ Union[numpy.uint64, ...)

Convert EGI hash to a coarser (parent) resolution level.

get_children(→ List[numpy.uint64])

Get all child pixels at a finer resolution.

pixels_per_tile(→ Union[int, float])

Calculate the number of pixels per outer tile at a given level.

validate_hash(→ bool)

Validate that an EGI hash is well-formed.

Module Contents#

gedih3.egi.core.hasher(level: int | numpy.typing.NDArray[numpy.integer], px_outer: int | numpy.typing.NDArray[numpy.uint16], py_outer: int | numpy.typing.NDArray[numpy.uint16], px_inner: int | numpy.typing.NDArray[numpy.uint32], py_inner: int | numpy.typing.NDArray[numpy.uint32]) numpy.uint64 | numpy.typing.NDArray[numpy.uint64][source]#

Construct EGI hash from component parts.

This is the core hash construction function. It combines level, outer tile coordinates, and inner pixel coordinates into a single uint64 hash.

Parameters:
levelint or array

Resolution level (1-12)

px_outerint or array

Outer tile X index (0-215)

py_outerint or array

Outer tile Y index (0-90)

px_innerint or array

Inner pixel X index within tile

py_innerint or array

Inner pixel Y index within tile

Returns:
np.uint64 or ndarray of uint64

EGI hash value(s)

Notes

All inputs must be the same shape or broadcastable. The function preserves exact integer arithmetic using uint64 throughout.

gedih3.egi.core.to_hash(x: float | numpy.typing.NDArray[numpy.floating], y: float | numpy.typing.NDArray[numpy.floating], level: int = 1) numpy.uint64 | numpy.typing.NDArray[numpy.uint64][source]#

Convert EPSG:6933 coordinates to EGI hash.

Parameters:
xfloat or array

X coordinate(s) in EPSG:6933 (meters from origin)

yfloat or array

Y coordinate(s) in EPSG:6933 (meters from origin)

levelint

Target EGI resolution level (1-12), default=1

Returns:
np.uint64 or ndarray of uint64

EGI hash value(s)

Notes

Outer-tile and inner-pixel indices are derived independently in the float domain — matching the reference easegridindex grid alignment so existing on-disk data stays interpretable — but we then carry any boundary overflow from px_inner into px_outer. OUTER_RES (~160143.2 m) is not exactly representable in float64, so for coordinates at or just below a tile boundary, x_offset // OUTER_RES rounds down to tile N-1 while x_offset % OUTER_RES // scale returns SCALE_FACTOR (one past the valid inner range). Left uncorrected, those out-of-range inner indices propagate through to_parent as spurious non-zero inner indices at coarser levels, producing boundary-shadow cells at every level. The carry folds the overflow back into the proper outer tile so px_inner is always in [0, SCALE_FACTOR). Non-boundary inputs are unaffected.

Coordinates must be in EPSG:6933 projection. Do NOT use this function with WGS84 coordinates - reproject first.

Examples

>>> # Single coordinate
>>> hash_val = to_hash(-8000000.0, 4000000.0, level=6)
>>>
>>> # Array of coordinates
>>> x = np.array([-8000000.0, -7000000.0])
>>> y = np.array([4000000.0, 3500000.0])
>>> hashes = to_hash(x, y, level=6)
gedih3.egi.core.from_hash(uint_hash: numpy.uint64 | numpy.typing.NDArray[numpy.uint64]) Tuple[int | numpy.typing.NDArray[numpy.integer], float | numpy.typing.NDArray[numpy.floating], numpy.uint16 | numpy.typing.NDArray[numpy.uint16], numpy.uint16 | numpy.typing.NDArray[numpy.uint16], numpy.uint32 | numpy.typing.NDArray[numpy.uint32], numpy.uint32 | numpy.typing.NDArray[numpy.uint32]][source]#

Decode EGI hash into its component parts.

Parameters:
uint_hashuint64 or array of uint64

EGI hash value(s) to decode

Returns:
tuple

(level, scale, px_outer, py_outer, px_inner, py_inner) - level: Resolution level (1-12) - scale: Pixel size in meters - px_outer: Outer tile X index - py_outer: Outer tile Y index - px_inner: Inner pixel X index - py_inner: Inner pixel Y index

Examples

>>> level, scale, px_o, py_o, px_i, py_i = from_hash(hash_val)
gedih3.egi.core.get_level(uint_hash: numpy.uint64 | numpy.typing.NDArray[numpy.uint64]) int | numpy.typing.NDArray[numpy.integer][source]#

Extract the resolution level from an EGI hash.

Parameters:
uint_hashuint64 or array of uint64

EGI hash value(s)

Returns:
int or array

Resolution level(s)

gedih3.egi.core.get_scale(uint_hash: numpy.uint64 | numpy.typing.NDArray[numpy.uint64]) float | numpy.typing.NDArray[numpy.floating][source]#

Get the pixel size in meters for an EGI hash.

Parameters:
uint_hashuint64 or array of uint64

EGI hash value(s)

Returns:
float or array

Pixel size(s) in meters

gedih3.egi.core.to_parent(uint_hash: numpy.uint64 | numpy.typing.NDArray[numpy.uint64], parent_level: int) numpy.uint64 | numpy.typing.NDArray[numpy.uint64][source]#

Convert EGI hash to a coarser (parent) resolution level.

This function rescales the inner pixel coordinates to the parent resolution while preserving the outer tile coordinates.

Parameters:
uint_hashuint64 or array of uint64

EGI hash value(s) to convert

parent_levelint

Target parent resolution level (must be >= current level)

Returns:
uint64 or array of uint64

EGI hash(es) at parent resolution

Raises:
ValueError

If parent_level is finer than current level

Examples

>>> # Convert from level 1 to level 6
>>> parent_hash = to_parent(fine_hash, parent_level=6)
gedih3.egi.core.get_children(uint_hash: numpy.uint64 | numpy.typing.NDArray[numpy.uint64], children_level: int = -1) List[numpy.uint64][source]#

Get all child pixels at a finer resolution.

Parameters:
uint_hashuint64

EGI hash value (parent pixel)

children_levelint

Target resolution level for children. Negative values are relative to parent level (e.g., -1 = one level finer)

Returns:
list of uint64

EGI hashes of all child pixels

Raises:
ValueError

If children_level is not finer than parent level

Examples

>>> children = get_children(parent_hash, children_level=-1)
>>> fine_children = get_children(level6_hash, children_level=1)
gedih3.egi.core.pixels_per_tile(uint_hash_or_level: numpy.uint64 | int) int | float[source]#

Calculate the number of pixels per outer tile at a given level.

Parameters:
uint_hash_or_leveluint64 or int

Either an EGI hash or a resolution level (1-12)

Returns:
int or float

Number of pixels along one edge of an outer tile

gedih3.egi.core.validate_hash(uint_hash: numpy.uint64 | numpy.typing.NDArray[numpy.uint64]) bool[source]#

Validate that an EGI hash is well-formed.

Parameters:
uint_hashuint64 or array of uint64

EGI hash value(s) to validate

Returns:
bool

True if valid, False otherwise