h3

    Pure MoonBit implementation of H3 indexing, traversal, and spatial metrics.

    h3
    geospatial
    spatial-index
    hexagon
    Download zip
    Author
    Version
    0.10.1
    License
    Apache-2.0
    Last updated
    last month
    Downloads
    26

    No dependencies

    #MoonBit H3

    A pure MoonBit implementation of the H3 geospatial indexing system. The project follows the official H3 bit layout and validation rules while keeping the API native to MoonBit.

    #Implemented Features

    #Safe H3 cell index handling

    • parse one to sixteen hexadecimal digits
    • validate the complete 64-bit H3 cell layout
    • reject invalid active digits and invalid unused digits
    • enforce the deleted subsequence rule for pentagonal base cells
    • inspect resolution, base cell, index digits, and pentagon status
    • emit a canonical lower-case hexadecimal index

    #Cell hierarchy operations

    • calculate an ancestor at a requested resolution
    • calculate the center descendant at a requested resolution
    • test whether one cell is an ancestor or descendant of another

    #Coordinate conversion

    • decode an H3 cell center to decimal latitude and longitude
    • encode decimal latitude and longitude as the containing H3 cell
    • handle face-edge overages and pentagonal cells
    • expose coordinates through a typed LatLng value

    #Neighbor traversal

    • query all cells within a grid_disk radius
    • return cells in increasing distance order without duplicates
    • handle face crossings and pentagonal deletions
    • bound the radius to prevent unbounded memory growth
    • query a neighbor in a specific H3 direction
    • test adjacency and find the direction between neighboring cells
    • query only the outer ring at an exact distance
    • query every cell together with its grid distance

    #Resolution metrics

    • calculate the total number of cells at a resolution
    • query the official average cell area in square kilometers
    • query the official average edge length in kilometers
    • calculate the great-circle distance between two cell centers
    • calculate exact grid distance within the bounded search radius

    Directed edges, pathfinding, and compact sets are intentionally left for later increments.

    #Installation

    The development module is currently LC6543/h3. If moon whoami returns a different account, replace the namespace before the first mooncakes.io release.

    moon add LC6543/h3@0.10.1

    #Usage

    ///|
    test {
    let index = @h3.H3Index::parse("8928308280fffff").unwrap()
    assert_eq(index.resolution(), 9)
    assert_eq(index.base_cell(), 20)
    assert_eq(index.parent(7).unwrap().to_string(), "872830828ffffff")
    let center = index.to_lat_lng()
    assert_true(center.latitude().is_close(37.77670234943567))
    assert_true(center.longitude().is_close(-122.41845932318309))
    let same_cell = @h3.H3Index::from_lat_lng(
    37.77670234943567, -122.41845932318309, 9,
    ).unwrap()
    assert_eq(same_cell.to_string(), "8928308280fffff")
    assert_eq(index.grid_disk(1).unwrap().length(), 7)
    let neighbor = @h3.H3Index::parse("89283082803ffff").unwrap()
    assert_true(index.is_neighbor_of(neighbor))
    assert_eq(index.grid_ring(1).unwrap().length(), 6)
    assert_eq(index.grid_disk_distances(1).unwrap().length(), 7)
    assert_eq(@h3.resolution_cell_count(9).unwrap(), 4842432842UL)
    assert_true(index.great_circle_distance_km(neighbor).is_close(0.3547928245))
    assert_eq(index.grid_distance_to(neighbor).unwrap(), 1)
    assert_eq(index.to_string(), "8928308280fffff")
    }

    Invalid input is returned as a structured H3Error:

    match @h3.H3Index::parse("8928308280zzfff") {
    Ok(index) => println(index.to_string())
    Err(InvalidCharacter(ch)) => println("invalid character: \{ch}")
    Err(_) => println("invalid H3 index")
    }

    #Runnable Example

    moon run examples/basic

    The example encodes a San Francisco coordinate, prints the cell center and first ring, and reports the average H3 cell area.

    #Development

    moon check --target all moon build --target all moon test --target all moon check --fmt moon package

    The test suite includes fixed vectors generated with the official H3 implementation.

    #License

    Apache-2.0. See NOTICE for attribution to the upstream H3 project.

    See PROPOSAL.md for the competition proposal draft. See RELEASE.md for the remaining account and publishing steps.

    H3Error

    pub enum H3Error {
    EmptyInput
    TooLong(Int)
    InvalidCharacter(Char)
    InvalidIndex
    InvalidResolution(Int)
    ResolutionMismatch(Int, Int)
    InvalidCoordinate
    InvalidGridDiskRadius(Int)
    InvalidDirection(Int)
    UnavailableNeighbor(Int)
    GridDistanceOutOfRange
    } derive(Eq,
    Debug
    )

    Errors produced while parsing or validating an H3 cell index.

    H3Error::equal

    fn H3Error::equal(H3Error, H3Error) -> Bool

    H3Error::not_equal

    fn H3Error::not_equal(x : H3Error, y : H3Error) -> Bool

    H3Error::to_repr

    #deprecated("Use `@debug.Debug::to_repr` through the trait instead")
    fn H3Error::to_repr(H3Error) ->
    Repr

    H3Index

    pub struct H3Index(UInt64) derive(Eq, Hash)

    A validated H3 cell index.

    The bit layout follows the Uber H3 indexing specification. Values of this type always represent a valid H3 hexagonal or pentagonal cell.

    H3Index::base_cell

    fn H3Index::base_cell(self : H3Index) -> Int

    Returns the base cell number of this cell, from 0 through 121.

    H3Index::center_child

    fn H3Index::center_child(self : H3Index, resolution : Int) -> Result[H3Index, H3Error]

    Returns the center descendant of this cell at resolution.

    Requesting the current resolution returns the same cell.

    H3Index::digit

    fn H3Index::digit(self : H3Index, resolution : Int) -> Int?

    Returns the index digit for resolution, when that resolution is present.

    Resolution numbering starts at 1 and ends at self.resolution().

    H3Index::direction_to

    fn H3Index::direction_to(self : H3Index, other : H3Index) -> Int?

    Returns the direction from this cell to other, when they are neighbors.

    H3Index::equal

    fn H3Index::equal(H3Index, H3Index) -> Bool

    H3Index::from_lat_lng

    fn H3Index::from_lat_lng(latitude : Double, longitude : Double, resolution : Int) -> Result[H3Index, H3Error]

    Encodes decimal latitude and longitude as the containing H3 cell.

    H3Index::from_u64

    fn H3Index::from_u64(value : UInt64) -> Result[H3Index, H3Error]

    Creates an H3 index from its raw 64-bit representation.

    H3Index::great_circle_distance_km

    fn H3Index::great_circle_distance_km(self : H3Index, other : H3Index) -> Double

    Returns the great-circle distance between two cell centers in kilometers.

    H3Index::grid_disk

    fn H3Index::grid_disk(self : H3Index, radius : Int) -> Result[Array[H3Index], H3Error]

    Returns the origin, its direct neighbors, and all cells within radius grid steps.

    The result does not contain duplicates and is ordered by increasing grid distance from the origin.

    H3Index::grid_disk_distances

    fn H3Index::grid_disk_distances(self : H3Index, radius : Int) -> Result[Array[(H3Index, Int)], H3Error]

    Returns each cell within radius together with its grid distance.

    H3Index::grid_distance_to

    fn H3Index::grid_distance_to(self : H3Index, other : H3Index) -> Result[Int, H3Error]

    Returns the exact grid distance to another cell within the supported search radius.

    H3Index::grid_ring

    fn H3Index::grid_ring(self : H3Index, radius : Int) -> Result[Array[H3Index], H3Error]

    Returns only the cells exactly radius grid steps from the origin.

    H3Index::hash

    fn H3Index::hash(self : H3Index) -> Int

    H3Index::hash_combine

    fn H3Index::hash_combine(H3Index, Hasher) -> Unit

    H3Index::is_ancestor_of

    fn H3Index::is_ancestor_of(self : H3Index, other : H3Index) -> Bool

    Returns whether this cell is an ancestor of other.

    A cell is considered an ancestor of itself.

    H3Index::is_descendant_of

    fn H3Index::is_descendant_of(self : H3Index, other : H3Index) -> Bool

    Returns whether this cell is a descendant of other.

    A cell is considered a descendant of itself.

    H3Index::is_neighbor_of

    fn H3Index::is_neighbor_of(self : H3Index, other : H3Index) -> Bool

    Returns whether two cells share an edge.

    H3Index::is_pentagon

    fn H3Index::is_pentagon(self : H3Index) -> Bool

    Returns whether this cell is one of the twelve pentagons at its resolution.

    H3Index::neighbor

    fn H3Index::neighbor(self : H3Index, direction : Int) -> Result[H3Index, H3Error]

    Returns the neighboring cell in an H3 index direction from 1 through 6.

    Pentagons have one unavailable direction. In that case, UnavailableNeighbor is returned.

    H3Index::not_equal

    fn H3Index::not_equal(x : H3Index, y : H3Index) -> Bool

    H3Index::parent

    fn H3Index::parent(self : H3Index, resolution : Int) -> Result[H3Index, H3Error]

    Returns the ancestor of this cell at resolution.

    Requesting the current resolution returns the same cell.

    H3Index::parse

    fn H3Index::parse(text : String) -> Result[H3Index, H3Error]

    Parses an H3 cell index from one to sixteen hexadecimal digits.

    Parsing is case-insensitive and accepts leading zeroes. The resulting value is validated before it is returned.

    H3Index::raw

    fn H3Index::raw(self : H3Index) -> UInt64

    Returns the raw 64-bit H3 representation.

    H3Index::resolution

    fn H3Index::resolution(self : H3Index) -> Int

    Returns the resolution of this cell, from 0 through 15.

    H3Index::to_lat_lng

    fn H3Index::to_lat_lng(self : H3Index) -> LatLng

    Returns the center point of this H3 cell in decimal degrees.

    H3Index::to_string

    fn H3Index::to_string(self : H3Index) -> String

    Returns the canonical lower-case hexadecimal representation.

    LatLng

    pub struct LatLng {
    latitude : Double
    longitude : Double
    } derive(Eq,
    Debug
    )

    A latitude/longitude pair in decimal degrees.

    LatLng::equal

    fn LatLng::equal(LatLng, LatLng) -> Bool

    LatLng::latitude

    fn LatLng::latitude(self : LatLng) -> Double

    LatLng::longitude

    fn LatLng::longitude(self : LatLng) -> Double

    LatLng::not_equal

    fn LatLng::not_equal(x : LatLng, y : LatLng) -> Bool

    LatLng::to_repr

    #deprecated("Use `@debug.Debug::to_repr` through the trait instead")
    fn LatLng::to_repr(LatLng) ->
    Repr

    EARTH_RADIUS_KM

    let EARTH_RADIUS_KM : Double

    Earth radius in kilometers, matching the H3 reference implementation.

    MAX_GRID_DISK_RADIUS

    let MAX_GRID_DISK_RADIUS : Int

    The maximum grid disk radius accepted by this implementation.

    MAX_RESOLUTION

    let MAX_RESOLUTION : Int

    The highest supported H3 resolution.

    NUM_BASE_CELLS

    let NUM_BASE_CELLS : Int

    The number of H3 base cells, including the twelve pentagons.

    average_cell_area_km2

    fn average_cell_area_km2(resolution : Int) -> Result[Double, H3Error]

    Returns the average H3 cell area in square kilometers.

    average_edge_length_km

    fn average_edge_length_km(resolution : Int) -> Result[Double, H3Error]

    Returns the average H3 cell edge length in kilometers.

    is_valid_index

    fn is_valid_index(value : UInt64) -> Bool

    Returns whether value is a valid H3 cell index.

    This validates the top byte, base cell range, active digits, unused digits, and the deleted subsequence rule for pentagonal base cells.

    resolution_cell_count

    fn resolution_cell_count(resolution : Int) -> Result[UInt64, H3Error]

    Returns the total number of H3 cells at a resolution.

    Powered by MoonBit

    Site sourceReport issueModulesSkillsBuild queueStatistics

    © 2026 mooncakes.io