gedih3.egi.core =============== .. py:module:: gedih3.egi.core .. autoapi-nested-parse:: 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 .. !! processed by numpydoc !! Functions --------- .. autoapisummary:: gedih3.egi.core.hasher gedih3.egi.core.to_hash gedih3.egi.core.from_hash gedih3.egi.core.get_level gedih3.egi.core.get_scale gedih3.egi.core.to_parent gedih3.egi.core.get_children gedih3.egi.core.pixels_per_tile gedih3.egi.core.validate_hash Module Contents --------------- .. py:function:: hasher(level: Union[int, numpy.typing.NDArray[numpy.integer]], px_outer: Union[int, numpy.typing.NDArray[numpy.uint16]], py_outer: Union[int, numpy.typing.NDArray[numpy.uint16]], px_inner: Union[int, numpy.typing.NDArray[numpy.uint32]], py_inner: Union[int, numpy.typing.NDArray[numpy.uint32]]) -> Union[numpy.uint64, numpy.typing.NDArray[numpy.uint64]] 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: **level** : int or array Resolution level (1-12) **px_outer** : int or array Outer tile X index (0-215) **py_outer** : int or array Outer tile Y index (0-90) **px_inner** : int or array Inner pixel X index within tile **py_inner** : int or array Inner pixel Y index within tile :Returns: np.uint64 or ndarray of uint64 EGI hash value(s) .. rubric:: Notes All inputs must be the same shape or broadcastable. The function preserves exact integer arithmetic using uint64 throughout. .. !! processed by numpydoc !! .. py:function:: to_hash(x: Union[float, numpy.typing.NDArray[numpy.floating]], y: Union[float, numpy.typing.NDArray[numpy.floating]], level: int = 1) -> Union[numpy.uint64, numpy.typing.NDArray[numpy.uint64]] Convert EPSG:6933 coordinates to EGI hash. :Parameters: **x** : float or array X coordinate(s) in EPSG:6933 (meters from origin) **y** : float or array Y coordinate(s) in EPSG:6933 (meters from origin) **level** : int Target EGI resolution level (1-12), default=1 :Returns: np.uint64 or ndarray of uint64 EGI hash value(s) .. rubric:: 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. .. rubric:: 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) .. !! processed by numpydoc !! .. py:function:: from_hash(uint_hash: Union[numpy.uint64, numpy.typing.NDArray[numpy.uint64]]) -> Tuple[Union[int, numpy.typing.NDArray[numpy.integer]], Union[float, numpy.typing.NDArray[numpy.floating]], Union[numpy.uint16, numpy.typing.NDArray[numpy.uint16]], Union[numpy.uint16, numpy.typing.NDArray[numpy.uint16]], Union[numpy.uint32, numpy.typing.NDArray[numpy.uint32]], Union[numpy.uint32, numpy.typing.NDArray[numpy.uint32]]] Decode EGI hash into its component parts. :Parameters: **uint_hash** : uint64 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 .. rubric:: Examples >>> level, scale, px_o, py_o, px_i, py_i = from_hash(hash_val) .. !! processed by numpydoc !! .. py:function:: get_level(uint_hash: Union[numpy.uint64, numpy.typing.NDArray[numpy.uint64]]) -> Union[int, numpy.typing.NDArray[numpy.integer]] Extract the resolution level from an EGI hash. :Parameters: **uint_hash** : uint64 or array of uint64 EGI hash value(s) :Returns: int or array Resolution level(s) .. !! processed by numpydoc !! .. py:function:: get_scale(uint_hash: Union[numpy.uint64, numpy.typing.NDArray[numpy.uint64]]) -> Union[float, numpy.typing.NDArray[numpy.floating]] Get the pixel size in meters for an EGI hash. :Parameters: **uint_hash** : uint64 or array of uint64 EGI hash value(s) :Returns: float or array Pixel size(s) in meters .. !! processed by numpydoc !! .. py:function:: to_parent(uint_hash: Union[numpy.uint64, numpy.typing.NDArray[numpy.uint64]], parent_level: int) -> Union[numpy.uint64, numpy.typing.NDArray[numpy.uint64]] 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_hash** : uint64 or array of uint64 EGI hash value(s) to convert **parent_level** : int 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 .. rubric:: Examples >>> # Convert from level 1 to level 6 >>> parent_hash = to_parent(fine_hash, parent_level=6) .. !! processed by numpydoc !! .. py:function:: get_children(uint_hash: Union[numpy.uint64, numpy.typing.NDArray[numpy.uint64]], children_level: int = -1) -> List[numpy.uint64] Get all child pixels at a finer resolution. :Parameters: **uint_hash** : uint64 EGI hash value (parent pixel) **children_level** : int 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 .. rubric:: Examples >>> children = get_children(parent_hash, children_level=-1) >>> fine_children = get_children(level6_hash, children_level=1) .. !! processed by numpydoc !! .. py:function:: pixels_per_tile(uint_hash_or_level: Union[numpy.uint64, int]) -> Union[int, float] Calculate the number of pixels per outer tile at a given level. :Parameters: **uint_hash_or_level** : uint64 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 .. !! processed by numpydoc !! .. py:function:: validate_hash(uint_hash: Union[numpy.uint64, numpy.typing.NDArray[numpy.uint64]]) -> bool Validate that an EGI hash is well-formed. :Parameters: **uint_hash** : uint64 or array of uint64 EGI hash value(s) to validate :Returns: bool True if valid, False otherwise .. !! processed by numpydoc !!