Hexagonal H3 routing, drivesheds, and scalable GIS network analysis with OpenStreetMap networks.
Project description
osmh3nx
Hexagonal H3 routing, drivesheds, and scalable GIS network analysis with OpenStreetMap networks.
osmh3nx is a Python package for building reusable H3-based transportation networks from
OpenStreetMap drive graphs, then using those networks for routing, nearest-target assignment,
drivesheds, and (geo)dataframe-oriented batch analysis.
The project is designed for users who want a scalable hexagonal abstraction over OSM routing
rather than using raw street-network nodes as the main analysis surface,
thus greatly enhancing computational efficiency.
Building Blocks
osmh3nx was created at Child Care Aware® of America and is built upon:
h3, originally developed by Uber, provides the hexagonal global grid system that serves as the package's core routing and storage abstraction.osmnxhandles OpenStreetMap graph download, enrichment, and graph-to-GeoDataFrame conversion.networkxpowers the graph structure itself along with shortest-path and connectivity operations.GeoPandas,shapely, andpandasprovide the geometry, tabular, and dataframe-first workflow foundation used throughout the package outputs and batch interfaces.
Inspiration
- Rabinowitz, N. 2023. "H3 Travel Times." https://observablehq.com/@nrabinowitz/h3-travel-times
- Malla, S. R. 2025. A landmark-based addressing framework for urban navigation using geospatial clustering and pathfinding algorithm. Kathmandu University Journal of Science Engineering and Technology, 19(1). https://doi.org/10.70530/kuset.v19i1.593
- Boeing, G. 2025. Modeling and Analyzing Urban Networks and Amenities with OSMnx. Geographical Analysis 57(4), 567-577. https://doi.org/10.1111/gean.70009
Installation
Install from PyPI:
pip install osmh3nx
osmh3nx currently targets Python 3.11 and 3.12.
What the Package Does
At a high level, osmh3nx:
- Downloads or reuses a drivable, directional OpenStreetMap network
- Collapses that network into an H3-based travel graph
- Preserves OSM-derived connectivity while operating on hexagons rather than raw street nodes
- Exposes routing, nearest-target assignment, drivesheds, and dataframe-first batch tools
This package is most useful when you want scalable area-wide travel-time analysis and are willing to work with a hex-based abstraction instead of exact turn-by-turn street routing.
Typical Use Cases
- Build a reusable, directional, and abstracted drive network for a study area
- Find the nearest destination for many source points by travel time
- Generate drivesheds around many origin points
- Reuse one shared network context for clustered batch runs, even across large areas
- Store unique H3 cell geometry once and keep origin-to-cell relationships in a sidecar table
- Explore which origins cross a given H3 cell, or which cells belong to a given origin's driveshed
Core Concepts
H3-first network analysis
osmh3nx uses H3 cells as the main network abstraction. OSM is still the source of the road topology and travel-time evidence, but the downstream analysis surface is the hex grid.
Calibrated travel cost
The package includes a reusable calibration layer so network-building settings do not need to be duplicated across every script. Current defaults are intentionally configurable and remain subject to future tuning.
Dataframe-first outputs
Batch tools are built around pandas and GeoPandas outputs. The package is designed so batch results can be inspected directly in Python and also written cleanly to GIS-friendly formats.
Main Public Functions
The top-level package currently exposes the main entry points you are most likely to use:
build_calibrated_h3_graph_from_osmbuilds a calibrated H3 travel graph directly from an OSM drive graph.build_calibrated_h3_graph_for_pointsbuilds and packages a reusable batch graph context for one point set or group.run_batch_od_routessolves many origin-destination routes and returns tabular plus spatial route outputs.run_batch_nearest_target_assignmentassigns each source point to its nearest target by H3-network travel cost.run_batch_driveshedsbuilds many drivesheds and returns unique H3 cell geometry plus origin-to-cell lookup rows. Grouped batch drivesheds rely on buffered convex hull geometries from the batch input points.build_h3_driveshed_from_pointbuilds a single-origin driveshed from a point and returns detailed route-cell outputs.select_driveshed_cells_from_lookupreconstructs the unique cell geometry for one or more selected origins.select_origins_for_driveshed_cellreturns all origin lookup rows whose drivesheds cross a given H3 cell.dissolve_driveshed_cells_from_lookuprebuilds dissolved driveshed polygons on demand from normalized cell storage.
Quick Start
Single-origin driveshed
from shapely.geometry import Point
from osmh3nx import build_h3_driveshed_from_point
origin = Point(-79.94143, 37.27097)
result = build_h3_driveshed_from_point(
origin,
max_travel_minutes=20.0,
)
print(result.reachable_cells_gdf.head())
print(result.driveshed_gdf.head())
This returns a DriveshedResult object with:
reachable_cells_gdfreachable_edges_gdfdriveshed_gdf- the origin cell ids used in routing
- the underlying H3 graph and optional OSM graph context
Batch drivesheds from a GeoDataFrame
import geopandas as gpd
from osmh3nx import run_batch_drivesheds
origins = gpd.GeoDataFrame(
{"origin_id": ["a", "b"]},
geometry=gpd.points_from_xy(
[-79.94143, -79.94500],
[37.27097, 37.27200],
),
crs="EPSG:4326",
)
result = run_batch_drivesheds(
origins,
origin_id_col="origin_id",
share_graph_for_all_origins=True,
max_travel_minutes=20.0,
)
print(result.driveshed_cells_unique_gdf.head())
print(result.driveshed_cell_lookup_df.head())
run_batch_drivesheds(...) now uses a normalized storage model:
driveshed_cells_unique_gdfstores unique H3 cell geometry oncedriveshed_cell_lookup_dfstores origin-to-cell relationships as a non-spatial table
This is much more scalable than writing duplicated polygon geometry for every origin-cell pair.
Batch OD routing / nearest-target assignment
If your workflow is origin-destination routing rather than drivesheds, use the dataframe-oriented batch helpers:
run_batch_od_routes(...)run_batch_nearest_target_assignment(...)
These functions accept pandas or GeoPandas inputs and return structured batch result objects with routes, route hexes, search polygons, and reusable graph contexts.
Working With Normalized Driveshed Outputs
One of the main downstream patterns in osmh3nx is:
- write unique cell geometry to a GeoPackage
- write the lookup table to a sidecar table
- reconstruct subsets on demand rather than storing massive duplicated geometry layers
Get all cells for one origin
from osmh3nx import select_driveshed_cells_from_lookup
cells_for_origin = select_driveshed_cells_from_lookup(
unique_cells_gdf,
cell_lookup_df,
origin_ids=["1412817"],
)
Get all origins that cross one H3 cell
from osmh3nx import select_origins_for_driveshed_cell
origins_for_cell = select_origins_for_driveshed_cell(
cell_lookup_df,
h3_cell="8a2a8a905aeffff",
)
Rebuild a dissolved polygon on demand
from osmh3nx import dissolve_driveshed_cells_from_lookup
dissolved = dissolve_driveshed_cells_from_lookup(
unique_cells_gdf,
cell_lookup_df,
origin_ids=["1412817"],
)
This allows large batch runs to stay compact while still supporting targeted visualization later.
Output Formats
Current common output pattern:
- spatial layers to GeoPackage
- lookup tables to sidecar files
The lookup sidecar supports:
parquetby default at the module level for scale and performancecsvwhen human readability or quick GIS joins are more important
Caching And Temporary Data
osmh3nx can reuse cached OSM graph downloads where configured,
and downstream callers can pass a custom cache_dir to the relevant network/driveshed/batch functions when they want cache files written somewhere specific.
At the package level, the default cache location comes from the user's platform cache directory via platformdirs rather than from the downstream working directory or this repo.
The package test suite is intentionally offline-first and avoids persistent scratch data by using tiny synthetic fixtures and pytest temporary directories.
GIS Workflow Notes
The package is designed to work well with GIS GUI tools:
- unique H3 cell layers can be rendered directly from GeoPackage
- lookup sidecars can be joined as non-spatial tables
- helper functions are available for reconstructing subsets in Python
- the same lookup logic can be replicated in GIS through normal joins and filters
Command Line Entry Point
The package installs a console script:
osmh3nx-driveshed
This maps to the package driveshed CLI entry point. The repo's scripts/ directory also contains larger workflow scripts used during development, calibration, and batch testing.
Limitations And Expectations
- This package is not a replacement for exact street-node routing when exact turn-level path fidelity is the main objective.
- H3 resolution choice matters and changes both runtime and route behavior.
- Travel-time realism depends on calibration settings and study-area context.
- Large batch runs can still be computationally heavy even with shared-graph reuse.
- Some development scripts in
scripts/are research-oriented and broader than the minimal package API surface.
Development
Run tests:
python -m pytest tests -ra
Check formatting:
black . --check --target-version py311
Install in editable mode:
python -m pip install -e .[development]
License
This project is licensed under the BSD 3-Clause License. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file osmh3nx-0.1.0b1.tar.gz.
File metadata
- Download URL: osmh3nx-0.1.0b1.tar.gz
- Upload date:
- Size: 50.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad5c94123b25464c1a7d11172e9a23b813a682e832bed028ee9549b064441a8a
|
|
| MD5 |
654422d0f0b76607b5ddc9536f987d13
|
|
| BLAKE2b-256 |
68fc8a8fe02c77465249fd9a47fb540d1d5ea67f5374b561849db888d27b785c
|
Provenance
The following attestation bundles were made for osmh3nx-0.1.0b1.tar.gz:
Publisher:
publish.yml on ccaoa/osmh3nx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
osmh3nx-0.1.0b1.tar.gz -
Subject digest:
ad5c94123b25464c1a7d11172e9a23b813a682e832bed028ee9549b064441a8a - Sigstore transparency entry: 1309493673
- Sigstore integration time:
-
Permalink:
ccaoa/osmh3nx@92b0bb8fe9a6a3d01720349ab009077aae113638 -
Branch / Tag:
refs/tags/v0.1.0b1 - Owner: https://github.com/ccaoa
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@92b0bb8fe9a6a3d01720349ab009077aae113638 -
Trigger Event:
push
-
Statement type:
File details
Details for the file osmh3nx-0.1.0b1-py3-none-any.whl.
File metadata
- Download URL: osmh3nx-0.1.0b1-py3-none-any.whl
- Upload date:
- Size: 47.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bac2e4673ba418aec0bb0cbe7bb3d37bd3ffd58402600c7ac0f4628c97c848e0
|
|
| MD5 |
78957e97bc44d38e6a9fc89a14f431c6
|
|
| BLAKE2b-256 |
dca2dfdf33cc7d31ce65fed7401f2f7f232bd0387d3b5d6e093505930e38f03a
|
Provenance
The following attestation bundles were made for osmh3nx-0.1.0b1-py3-none-any.whl:
Publisher:
publish.yml on ccaoa/osmh3nx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
osmh3nx-0.1.0b1-py3-none-any.whl -
Subject digest:
bac2e4673ba418aec0bb0cbe7bb3d37bd3ffd58402600c7ac0f4628c97c848e0 - Sigstore transparency entry: 1309493959
- Sigstore integration time:
-
Permalink:
ccaoa/osmh3nx@92b0bb8fe9a6a3d01720349ab009077aae113638 -
Branch / Tag:
refs/tags/v0.1.0b1 - Owner: https://github.com/ccaoa
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@92b0bb8fe9a6a3d01720349ab009077aae113638 -
Trigger Event:
push
-
Statement type: