Skip to main content

H3 Bound Cells

https://pypi.org/project/h3_bound_cells/

Convert geographic polygons into multi-resolution H3 cell coverings, with fast point-in-region lookups.

Rust core is built on h3o and exposed to Python via PyO3 / Maturin.

Generation uses h3-compactfill which is an extension to H3 which implements a short-circuited polygonToCells + compact Algorithm.

Overview

BoundCells holds a Compacted Polyfill of a target Polygon, keyed by H3 Resolution.

Generation - Fairly standard polyfill+compact step which converts a Polygon into contained H3 Cells. Start Resolution - This is the finest (highest) Resolution of the Cells, this is needed at cell edges to get a closer match to the polygon. Containment - Walks a datasets H3 Cells (checking each from fine->coarse) against the BoundCells for containment predicate. Prefilter allows for Parquet Predicate Pushdown which can Prune Row Groups by checking against Cell Index Ranges.

Install

The package is built locally with maturin: uv run maturin develop --release

Usage

import h3
from h3_bound_cells import polygon_to_bound_cells, cell_in_bound_cells, BoundCells

# Rectangle around central London. (lat, lng) pairs; the ring need not be closed.
exterior = [
    (51.50, -0.13),
    (51.52, -0.13),
    (51.52, -0.08),
    (51.50, -0.08),
]

bc = polygon_to_bound_cells(exterior, start_res=9)

print(bc)
# BoundCells(cells={8: 9, 9: 5, ...})

for res, cells in bc.cells.items():
    print(f"res {res}: {len(cells)} cells")

# Point-in-region check: Trafalgar Square at H3 resolution 11.
cell = h3.latlng_to_cell(51.5074, -0.1278, 11)
assert cell_in_bound_cells(cell, bc)

# JSON-friendly round trip
restored = BoundCells.from_dict(bc.to_dict())

API

  • polygon_to_bound_cells(exterior, holes=None, start_res=None, containment_mode=None, tolerance=None) -> BoundCells
    • exterior, holes — lists of (lat, lng) tuples. Note: this is (latitude, longitude), matching the H3 convention (e.g. h3.latlng_to_cell) — the reverse of GeoJSON/shapely/WKT, which use (longitude, latitude). Swap the order when feeding in GeoJSON coordinates.
    • start_res — H3 resolution to tile at. When omitted, it is auto-picked from the polygon's planar area.
    • containment_mode — a BCContainmentMode selecting which cells the fill keeps (default BCContainmentMode.ContainsCentroid). See BCContainmentMode below.
    • tolerance — Douglas–Peucker simplification distance in degrees, applied to the polygon before tiling. Tiling cost is linear in vertex count, so simplifying high-fidelity boundaries (e.g. OS/OSM data with metre-scale vertices) is a large speed-up. Defaults to 0 — no simplification, an exact covering identical to the raw geometry. Pass a small positive value (e.g. 1e-5, ≈1 m, for a ~5× speed-up on detailed boundaries) to opt in. Note that any non-zero tolerance is effectively-lossless rather than provably identical: a cell whose centroid lies within ~tolerance of the boundary can flip. Larger values are faster but shift more such edge cells.
  • cells_to_bound_cells(cells) -> BoundCells
    • Build a covering directly from an existing set of H3 cells, skipping polygon tiling. cells is an iterable of H3 cells as hex strings or u64 ints.
    • Input must be at a single resolution (mixed resolutions raise ValueError); duplicates are de-duplicated. An empty input yields an empty covering.
  • cell_in_bound_cells(cell: str, bound_cells: BoundCells) -> bool — membership test by H3 cell id.
  • BCContainmentMode — enum choosing which cells a polygon fill keeps (mirrors h3o's ContainmentMode):
    • ContainsCentroid (default) — cell kept when its centroid is inside. Fast, approximate interior.
    • ContainsBoundary — cell kept only when fully inside. Strict interior — no false positives, but omits edge cells only partly inside.
    • IntersectsBoundary — cell kept when it touches the polygon. Produces a superset covering that extends past the edge.
    • Covers — like IntersectsBoundary, also handling polygons smaller than a cell. Also a superset.
    • ⚠️ The overlap modes (IntersectsBoundary, Covers) make the covering a conservative superset, so cell_in_bound_cells then means "overlaps the region" and can report cells lying outside the polygon as inside. Use them when you want a covering, not exact point-in-region.
  • BoundCells — frozen class:
    • .cells — dict[str, list[str]] keyed by resolution.
    • .to_dict() / BoundCells.from_dict(d) — JSON-friendly round trip.
    • BoundCells.merge([bc1, bc2, ...]) — union of multiple results.
    • .cells_at_resolution(res) — flatten/expand the covering to a single H3 resolution (parents map up, coarser cells expand to their children).

Polars integration (optional)

Filter a Polars DataFrame/LazyFrame down to the rows whose H3 cell falls inside a covering.

Install the optional polars extra:

pip install h3_bound_cells[polars]

Importing h3_bound_cells registers a bound_cells namespace on Polars expressions (only registered when polars is installed):

import polars as pl
import h3_bound_cells  # registers the bound_cells namespace

bc = h3_bound_cells.polygon_to_bound_cells(exterior, start_res=9)

df = pl.DataFrame({"cell": [...]})  # H3 cells as hex strings or u64 ints

# Filter to rows inside the covering:
df.filter(pl.col("cell").bound_cells.is_in(bc))

# Or use the boolean result as a column:
df.with_columns(inside=pl.col("cell").bound_cells.is_in(bc))
  • pl.col(cell_column).bound_cells.is_in(bound_cells) — a boolean expression, true where the cell lies inside bound_cells.
  • Use it anywhere an expression is accepted (filter, select, with_columns, boolean combinations, …).
  • Works with both eager and lazy frames. Cells may be hex strings or u64 ints; a null cell maps to false (dropped by filter).

Predicate Pushdown (Parquet)

is_in is a native plugin, so the query optimiser can't see through it to prune a scan on its own. To fix that, is_in ANDs a pure H3-index range predicate in front of the exact check (prefilter=True, on by default). Because an H3 index sorts identically as a u64 and as its 15-char hex string, Polars can push that range test into a Parquet SCAN and skip whole row groups via their min/max statistics — often a large speed-up on big scans, with an identical result. The exact plugin check still runs, so correctness is unchanged.

This is ONLY recommended in Lazy Execution as it provides purely IO-bound wins, with a collected DataFrame there is no scan to prune so this then just becomes and additional filter to run.

lf = pl.scan_parquet("atlas.parquet")  # sorted by the H3 column

# UInt64 cell column (default dtype):
lf.filter(pl.col("h3").bound_cells.is_in(bc))

# Canonical 15-char hex-string cell column:
lf.filter(pl.col("h3point").bound_cells.is_in(bc, dtype=pl.Utf8))

For the prefilter to be correct and effective:

  • Resolution — by default the range predicate covers every resolution, so it is correct whatever resolution the column is at. If you know it, pass child_res=<res> (e.g. child_res=15) for the leanest predicate; the extra ranges of the default sit in empty u64 regions for a uniform-resolution column, so they don't weaken pruning either way.
  • Matching dtype — dtype must match the column: pl.UInt64 (default) for an integer column, or pl.Utf8 for a canonical 15-char lowercase-hex string column.
  • Sorted column — row-group skipping is dramatic only when the column is sorted (tight per-group min/max). On unsorted data the prefilter still trims per-row plugin cost but skips no row groups.

Pass prefilter=False for the exact-only behaviour.

Release files for h3_bound_cells 0.5.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for h3_bound_cells 0.5.1
File Size Uploaded
h3_bound_cells-0.5.1.tar.gz 69.5 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for h3_bound_cells 0.5.1
File
h3_bound_cells-0.5.1-cp39-abi3-win_arm64.whl CPython 3.9 abi3 Windows ARM64 Details
h3_bound_cells-0.5.1-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details
h3_bound_cells-0.5.1-cp39-abi3-win32.whl CPython 3.9 abi3 Windows x86-32 Details
h3_bound_cells-0.5.1-cp39-abi3-musllinux_1_2_x86_64.whl CPython 3.9 abi3 Linux musl 1.2+ x86-64 Details
h3_bound_cells-0.5.1-cp39-abi3-musllinux_1_2_i686.whl CPython 3.9 abi3 Linux musl 1.2+ x86-32 Details
h3_bound_cells-0.5.1-cp39-abi3-musllinux_1_2_aarch64.whl CPython 3.9 abi3 Linux musl 1.2+ ARM64 Details
h3_bound_cells-0.5.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.9 abi3 Linux glibc 2.17+ x86-64 Details
h3_bound_cells-0.5.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.9 abi3 Linux glibc 2.17+ ARM64 Details
h3_bound_cells-0.5.1-cp39-abi3-manylinux_2_12_i686.manylinux2010_i686.whl CPython 3.9 abi3 Linux glibc 2.12+ x86-32 Details
h3_bound_cells-0.5.1-cp39-abi3-macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64 Details

Total release size: 47.1 MB

Release files / h3_bound_cells-0.5.1.tar.gz

Download URL h3_bound_cells-0.5.1.tar.gz
Size 69.5 kB
Tags Source
SHA-256 checksum
How to use checksums
171ccf4eecceefecd962f5703d7b727dd204edd6cea7493640615476c79113af
BLAKE2b-256 checksum
How to use checksums
27a61b9c265f0c7b41fbcad72a529f4b4544bebb7a01b6af51052382ebdbbdcc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / h3_bound_cells-0.5.1-cp39-abi3-win_arm64.whl

Download URL h3_bound_cells-0.5.1-cp39-abi3-win_arm64.whl
Size 4.2 MB
Tags CPython 3.9 Windows ARM64 abi3
SHA-256 checksum
How to use checksums
4f8ee0f27476ea11b0d8bee3d4df155641781bff4b52565b271b55c0ef70baca
BLAKE2b-256 checksum
How to use checksums
548f5896e6c278e42393c6ad9f258e5284e81e3d9bae04ced6cc6afd54a9640d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / h3_bound_cells-0.5.1-cp39-abi3-win_amd64.whl

Download URL h3_bound_cells-0.5.1-cp39-abi3-win_amd64.whl
Size 4.7 MB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
32dcc142557ed5a52406d6b80d107e3e2ea3cbfe9bb352f3f7a3cf8eeea29c4b
BLAKE2b-256 checksum
How to use checksums
73d8abd542e93255f0f05ae61f834a2a2173d32ff562ae49c2cbfe62c2ec2800
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / h3_bound_cells-0.5.1-cp39-abi3-win32.whl

Download URL h3_bound_cells-0.5.1-cp39-abi3-win32.whl
Size 4.2 MB
Tags CPython 3.9 Windows x86-32 abi3
SHA-256 checksum
How to use checksums
3d4581b43e550d8e31e2b82c5f904847d5b0ba04c00f652980ece57c54df069a
BLAKE2b-256 checksum
How to use checksums
3776c43edd63d51929fc6d77ff4aa7439fcc33b0d0ba101d9553409cb991a08c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / h3_bound_cells-0.5.1-cp39-abi3-musllinux_1_2_x86_64.whl

Download URL h3_bound_cells-0.5.1-cp39-abi3-musllinux_1_2_x86_64.whl
Size 5.0 MB
Tags CPython 3.9 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
93074f528f9f89f0412e6f7b3bb61077d0d3a6c50d63a514964c46cd1127f16a
BLAKE2b-256 checksum
How to use checksums
9266806bd3cbd6ee3f989f4060d07a10bc5989633560dea5e4a7b6d04a67ef42
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / h3_bound_cells-0.5.1-cp39-abi3-musllinux_1_2_i686.whl

Download URL h3_bound_cells-0.5.1-cp39-abi3-musllinux_1_2_i686.whl
Size 5.3 MB
Tags CPython 3.9 Linux musl 1.2+ x86-32 abi3
SHA-256 checksum
How to use checksums
03afda7125aa584a4869aa49bd95db56910c87161ca797862c5aac291c490c95
BLAKE2b-256 checksum
How to use checksums
1d3999cd903c04ed353261fe2668eb0265fead300236f0c5444e375b78f20376
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / h3_bound_cells-0.5.1-cp39-abi3-musllinux_1_2_aarch64.whl

Download URL h3_bound_cells-0.5.1-cp39-abi3-musllinux_1_2_aarch64.whl
Size 4.7 MB
Tags CPython 3.9 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
62ef5de3d8790e0dc95e069a05a88b419607e0d77d77427512e71cfc606d0a88
BLAKE2b-256 checksum
How to use checksums
03b025bb578e34cc7505be39814c60821881caf2ca7021a3f396fc59f6226ed3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / h3_bound_cells-0.5.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL h3_bound_cells-0.5.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 4.8 MB
Tags CPython 3.9 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
56d74a6729f349a0e377d097a61dba8b13a39bebc2692ab3a748a7f8bf348b9c
BLAKE2b-256 checksum
How to use checksums
51b1d21a392407402cdaeadac4c7204323e053f38b398f75fa0d06d32542e359
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / h3_bound_cells-0.5.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL h3_bound_cells-0.5.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 4.5 MB
Tags CPython 3.9 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
31185748693f6cf0ca1673347a33bbd0f65f4552ee0c87c0716c9ba6d68f6758
BLAKE2b-256 checksum
How to use checksums
b8ec4f8cd20d2b9873434efcaf08cd7b3dff60a6cbb88437b74c98508ca31096
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / h3_bound_cells-0.5.1-cp39-abi3-manylinux_2_12_i686.manylinux2010_i686.whl

Download URL h3_bound_cells-0.5.1-cp39-abi3-manylinux_2_12_i686.manylinux2010_i686.whl
Size 5.2 MB
Tags CPython 3.9 Linux glibc 2.12+ x86-32 abi3
SHA-256 checksum
How to use checksums
7aaafa46da7a55adee5fdd26529deb9de1de54e8b5858a4749c535baac9ea22e
BLAKE2b-256 checksum
How to use checksums
cfdf78a239676cf90d071dffe00384cfdfaf07127ff7910ffebd8485f6f69d58
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / h3_bound_cells-0.5.1-cp39-abi3-macosx_11_0_arm64.whl

Download URL h3_bound_cells-0.5.1-cp39-abi3-macosx_11_0_arm64.whl
Size 4.3 MB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
a2cfe9583c9afaa41a3bf0ecb2955d72ba8839c3e62333131e1cf0e9866295a9
BLAKE2b-256 checksum
How to use checksums
9d1556f1364b06778cfb56718fcf5a007566778de1268554a383d79bb8220dcc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.5.3

11 release files

0.5.2

11 release files

This release

0.5.1 This release

11 release files

0.5.0

11 release files

0.4.1

11 release files

0.3.1

11 release files

0.3.0

11 release files

0.2.2

11 release files

0.2.1

11 release files

0.2.0

11 release files

0.1.5

92 release files

0.1.4

92 release files

0.1.3

92 release files

0.1.2

92 release files

0.1.0

92 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page