h3o Documentation

repository·master·Indexed 19 days ago

https://github.com/hydroniumlabs/h3o

A 100% Rust implementation of the H3 geospatial indexing system, version 0.11.0. Designed for performance and WASM compatibility without C dependencies, it provides tools for H3 cell indexing via CellIndex, coordinate conversions with LatLng, and grid traversal. Optional geometry features enable conversions between H3 objects and geometric shapes using ToGeo and ToCells traits, as well as path plotting with Plotter and polygon dissolution with Solvent.

Tokens
11.3K
Snippets
41
Records
53
Agent score
68%

What's inside h3o

  1. Understand error handling in h3o

    master
    The library uses a granular error handling strategy. Instead of a single crate-wide catch-all error type, h3o leans toward providing specific error types for individual functions. This allows consumers to use pattern matching to handle specific error cases more effectively when calling API methods.
  2. How the H3 API is structured

    master

    The h3o API is primarily centered around the CellIndex type, which serves as the main entry point for most H3 operations. While the library contains various internal modules for grid traversal and coordinate systems, most functionality is exposed directly through CellIndex to provide a streamlined consumer experience.

    Key architectural components include:

    • Index Types (src/index): Contains the core H3 index types, with CellIndex being the most prominent.
    • Coordinate Systems (src/coord): Acts as a bridge between public types. For example, converting a CellIndex to a LatLng involves the IJK coordinate system internally.
    • Grid API (src/grid): Handles grid traversal algorithms (finding neighbors, traversing from one cell to another). This module is internal; its capabilities are exposed via the CellIndex API.
  3. Map H3 API functions to h3o

    master

    If you are migrating from the original H3 library, use this mapping to find the equivalent functionality in h3o:

    Indexing

    H3h3o
    latLngToCellLatLng::to_cell
    cellToLatLngLatLng::from
    cellToBoundaryCellIndex::boundary

    Index Inspection

    H3h3o
    constructCellCellIndex::from_raw_parts
    getResolutionCellIndex::resolution
    getBaseCellNumberCellIndex::base_cell
    getIndexDigitCellIndex::direction_at
    stringToH3str::parse
    h3ToStringToString::to_string
    isValidCellCellIndex::try_from
    isValidIndexis_valid_index
    isResClassIIIResolution::is_class3
    isPentagonCellIndex::is_pentagon
    getIcosahedronFacesCellIndex::icosahedron_faces
    maxFaceCountCellIndex::max_face_count

    Grid Traversal

    H3h3o
    gridDiskCellIndex::grid_disk
    maxGridDiskSizemax_grid_disk_size
    maxGridRingSizemax_grid_ring_size
    gridDiskDistancesCellIndex::grid_disk_distances
    gridDiskUnsafeCellIndex::grid_disk_fast
    gridDiskDistancesUnsafeCellIndex::grid_disk_distances_fast
    gridDiskDistancesSafeCellIndex::grid_disk_distances_safe
    gridDisksUnsafeCellIndex::grid_disks_fast
    gridRingUnsafeCellIndex::grid_ring_fast
    gridRingCellIndex::grid_ring
    gridPathCellsCellIndex::grid_path_cells
    gridPathCellsSizeCellIndex::grid_path_cells_size
    gridDistanceCellIndex::grid_distance
    cellToLocalIjCellIndex::to_local_ij
    localIjToCellCellIndex::try_from

    Hierarchical Grid

    H3h3o
    cellToParentCellIndex::parent
    cellToChildrenCellIndex::children
    cellToChildrenSizeCellIndex::children_count
    cellToCenterChildCellIndex::center_child
    cellToChildPosCellIndex::child_position
    childPosToCellCellIndex::child_at
    compactCellsCellIndex::compact
    uncompactCellsCellIndex::uncompact
    uncompactCellsSizeCellIndex::uncompact_size

    Region & Edges

    H3h3o
    polygonToCellsgeom::Tiler::into_coverage
    maxPolygonToCellsSizegeom::Tiler::coverage_size_hint
    h3SetToLinkedGeogeom::Solvent::dissolve
    areNeighborCellsCellIndex::is_neighbor_with
    cellsToDirectedEdgeCellIndex::edge
    isValidDirectedEdgeDirectedEdgeIndex::try_from
    getDirectedEdgeOriginDirectedEdgeIndex::origin
    getDirectedEdgeDestinationDirectedEdgeIndex::destination
    directedEdgeToCellsDirectedEdgeIndex::cells
    originToDirectedEdgesCellIndex::edges
    directedEdgeToBoundaryDirectedEdgeIndex::boundary

    Vertex & Misc

    H3h3o
    cellToVertexCellIndex::vertex
    cellToVertexesCellIndex::vertexes
    vertexToLatLngLatLng::from
    isValidVertexVertexIndex::try_from
    degsToRadsf64::to_radians
    radsToDegsf64::to_degrees
    getHexagonAreaAvgKm2Resolution::area_km2
    getHexagonAreaAvgM2Resolution::area_m2
    cellAreaKm2CellIndex::area_km2
    cellAreaM2CellIndex::area_m2
    cellAreaRads2CellIndex::area_rads2
    getHexagonEdgeLengthAvgKmResolution::edge_length_km
    getHexagonEdgeLengthAvgMResolution::edge_length_m
    edgeLengthKmDirectedEdgeIndex::length_km
    edgeLengthMDirectedEdgeIndex::length_m
    edgeLengthRadsDirectedEdgeIndex::length_rads
    getNumCellsResolution::cell_count
    getRes0CellsCellIndex::base_cells
    res0CellCountBaseCell::count
    getPentagonsResolution::pentagons
    pentagonCountResolution::pentagon_count
    greatCircleDistanceKmLatLng::distance_km
    greatCircleDistanceMLatLng::distance_m
    greatCircleDistanceRadsLatLng::distance_rads
  4. Understand icosahedron face adjacency with NEIGHBORS

    master

    The NEIGHBORS table defines the adjacency relationship between icosahedron faces. For any given face, the table provides 4 FaceOrientIJK entries representing its neighbors in different quadrants:

    • IJ (index 1): The ij quadrant neighbor.
    • KI (index 2): The ki quadrant neighbor.
    • JK (index 3): The jk quadrant neighbor.

    Note: The first entry (index 0) in the array for each face is the face itself (the 'central face').

    Each FaceOrientIJK contains:

    • face: The neighbor's Face.
    • translate: A CoordIJK representing the resolution 0 translation relative to the primary face.
    • ccw_rot60: The number of 60-degree counter-clockwise rotations relative to the primary face.
    // Example of accessing neighbors
    let current_face_idx = 0;
    let neighbors = h3o::NEIGHBORS[current_face_idx];
    
    // Access the 'ij' quadrant neighbor
    let ij_neighbor = neighbors[h3o::IJ];
    println!("Neighbor face: {:?}, translation: {:?}", ij_neighbor.face, ij_neighbor.translate);
  5. Represent a topological vertex with VertexIndex

    master

    A VertexIndex represents a single topological vertex in the H3 grid system, which is shared by three cells. Unlike a CellIndex, a VertexIndex identifies a specific point in space by encoding both an "owner" cell and a specific vertex number on that cell.

    Bit Layout

    The 64-bit index is laid out as follows:

    • U (bit 63): Unused, always 0.
    • M (bits 59-62): Index mode (set to 4 for Vertex mode).
    • V (bits 56-58): Vertex number on the owner cell [0, 5].
    • O (bits 0-55): Owner cell index.

    Common Operations

    • Get the vertex number: Use .vertex() to retrieve the Vertex on the owner cell.
    • Get the owner cell: Use .owner() to retrieve the CellIndex that owns this vertex.
    • Get coordinates: Convert a VertexIndex into a LatLng to get its geographic coordinates.
    • Parsing: You can create a VertexIndex from a hex string using FromStr or from a u64 using TryFrom.
    // Create from a hex u64
    let index = h3o::VertexIndex::try_from(0x2222597fffffffff)?;
    
    // Access the owner cell
    let owner = index.owner();
    
    // Access the specific vertex number
    let vertex = index.vertex();
    
    // Get geographic coordinates
    let coords: h3o::LatLng = index.into();
  6. Configure Tiler containment modes

    master

    The ContainmentMode determines the logic used to decide if an H3 cell is considered part of the input geometry. This affects both the completeness of the coverage and whether cells overlap between adjacent polygons.

    ModeBehavior
    ContainsCentroidFastest. Selects cells whose centroids are inside the polygon. May overshoot boundaries or leave small gaps. Ensures no overlapping cells between adjacent polygons.
    ContainsBoundarySelects cells whose entire boundaries are within the polygon. Avoids overshooting but may leave more uncovered area than ContainsCentroid.
    IntersectsBoundarySelects cells that partially or fully intersect the polygon boundary. Guarantees complete coverage but may result in overlapping cells between adjacent polygons.
    CoversSimilar to IntersectsBoundary, but also includes cells that completely cover the geometry without the boundary intersecting.
  7. Convert geometries to H3 cell coverage using Tiler

    master

    The Tiler struct allows you to convert geographic shapes (Polygons) into a set of H3 cells. You can configure the tiler using a TilerBuilder to specify the H3 Resolution and the ContainmentMode (how a cell is determined to be 'inside' a shape).

    To use it:

    1. Create a TilerBuilder with a specific Resolution.
    2. Set a ContainmentMode.
    3. Build the Tiler.
    4. Add one or more Polygon objects using .add() or .add_batch().
    5. Use .into_coverage() to get an iterator of CellIndex or .into_annotated_coverage() to get AnnotatedCell objects which include containment metadata.
    use geo::{LineString, Polygon};
    use h3o::{geom::{ContainmentMode, TilerBuilder}, Resolution};
    
    let polygon = Polygon::new(
        LineString::from(vec![(0., 0.), (1., 1.), (1., 0.), (0., 0.)]),
        vec![],
    );
    
    let mut tiler = TilerBuilder::new(Resolution::Six)
        .containment_mode(ContainmentMode::Covers)
        .build();
    
    tiler.add(polygon)?;
    
    // Get just the cell indices
    let cells = tiler.into_coverage().collect::<Vec<_>>();
    
    // Or get cells with containment info
    let annotated_cells = tiler.into_annotated_coverage().collect::<Vec<_>>();
  8. Basic usage of h3o in Rust

    master

    To use h3o in your Rust project, import the necessary types like LatLng and Resolution. You can create a coordinate and convert it into an H3 cell at a specific resolution.

    Note that LatLng::new returns a Result, so you must handle potential errors (e.g., invalid latitude/longitude values) using .expect() or proper error handling.

    use h3o::{LatLng, Resolution};
    
    let coord = LatLng::new(37.769377, -122.388903).expect("valid coord");
    let cell = coord.to_cell(Resolution::Nine);
  9. Calculate maximum grid disk and ring sizes

    master

    Use max_grid_disk_size(k) and max_grid_ring_size(k) to determine the upper bounds of cells produced by grid traversal algorithms for a given radius k.

    • max_grid_disk_size(k): Returns the maximum number of indices produced by the grid disk algorithm. For very large k (>= 13,780,510), it returns the total cell count for resolution 15.
    • max_grid_ring_size(k): Returns the maximum number of cells that result from the gridRing algorithm.
    let count = h3o::max_grid_disk_size(3);
    let ring_count = h3o::max_grid_ring_size(3);
  10. Use the Geometry API for H3-Geometry conversions

    master

    If you enable the geom feature, you can use the Geometry API to convert between H3 objects and geometric shapes. This is achieved through two primary traits:

    • ToGeo: Converts H3 objects into geometries (e.g., converting a set of CellIndex values into a multi-polygon).
    • ToCells: Converts geometries into H3 objects (e.g., finding the set of CellIndex values that cover a specific polygon).

    The API also provides wrapper types around RustGeo types to ensure H3-specific constraints are met and includes From/Into implementations for seamless GeoJSON interoperability.