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.3

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.3
File Size Uploaded
h3_bound_cells-0.5.3.tar.gz 72.8 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for h3_bound_cells 0.5.3
File
h3_bound_cells-0.5.3-cp39-abi3-win_arm64.whl CPython 3.9 abi3 Windows ARM64 Details
h3_bound_cells-0.5.3-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details
h3_bound_cells-0.5.3-cp39-abi3-win32.whl CPython 3.9 abi3 Windows x86-32 Details
h3_bound_cells-0.5.3-cp39-abi3-musllinux_1_2_x86_64.whl CPython 3.9 abi3 Linux musl 1.2+ x86-64 Details
h3_bound_cells-0.5.3-cp39-abi3-musllinux_1_2_i686.whl CPython 3.9 abi3 Linux musl 1.2+ x86-32 Details
h3_bound_cells-0.5.3-cp39-abi3-musllinux_1_2_aarch64.whl CPython 3.9 abi3 Linux musl 1.2+ ARM64 Details
h3_bound_cells-0.5.3-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.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.9 abi3 Linux glibc 2.17+ ARM64 Details
h3_bound_cells-0.5.3-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.3-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.3.tar.gz

Download URL h3_bound_cells-0.5.3.tar.gz
Size 72.8 kB
Tags Source
SHA-256 checksum
How to use checksums
ff7a3ff0ab1e9475b300747cab06c968665084e4606323d3293fedd458687390
BLAKE2b-256 checksum
How to use checksums
f5702df8512b94696b3acbb8fc7dd97fc46dac6e6e9f5414e79468a99e8b2617
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.3-cp39-abi3-win_arm64.whl

Download URL h3_bound_cells-0.5.3-cp39-abi3-win_arm64.whl
Size 4.2 MB
Tags CPython 3.9 Windows ARM64 abi3
SHA-256 checksum
How to use checksums
63631eea8c30f69ccf304529e8038a3b7de70b8ec36677fff78ca8c378263fc6
BLAKE2b-256 checksum
How to use checksums
06232e3d35b49f75e428203ca69c4824a12ee24be26b080247c8e2aeef40ac4b
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.3-cp39-abi3-win_amd64.whl

Download URL h3_bound_cells-0.5.3-cp39-abi3-win_amd64.whl
Size 4.7 MB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
efb0df8bbb1d5fd98a4c08ebd2f050abe7de5a001e1ae9850dc6b6da9c7a7d4b
BLAKE2b-256 checksum
How to use checksums
17b960657dc2fb5fe57ea071efa5ecbc4c8cb1d7874b76ab7ed0f34a9e24be24
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.3-cp39-abi3-win32.whl

Download URL h3_bound_cells-0.5.3-cp39-abi3-win32.whl
Size 4.2 MB
Tags CPython 3.9 Windows x86-32 abi3
SHA-256 checksum
How to use checksums
ce069f412f6c92201cbd8fd36f13b8bfc0d527723291a459b38c4676622faaef
BLAKE2b-256 checksum
How to use checksums
3ecc7c88f75817b6b2d42632ff96cad6b953d69ca5606a644bfe94b30d4e9ba3
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.3-cp39-abi3-musllinux_1_2_x86_64.whl

Download URL h3_bound_cells-0.5.3-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
d29db23e68018a1c88890d24fc83401c3ffd15b656bc1c2c8f540b79947f11ec
BLAKE2b-256 checksum
How to use checksums
5a068e544265a35b71098462333a0b555ecedacd439b9c384a6e6c868bccb091
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.3-cp39-abi3-musllinux_1_2_i686.whl

Download URL h3_bound_cells-0.5.3-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
7baef31933b7721403f19ff55c988e8ea70eb0cedcbf939b39a77fd17df4e6e9
BLAKE2b-256 checksum
How to use checksums
f77fbd03b560f59b9ffb54c5afd3b548547cf6609cadfac9bde72a1bc639b491
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.3-cp39-abi3-musllinux_1_2_aarch64.whl

Download URL h3_bound_cells-0.5.3-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
76364067620e2db20a6d371753982edf8d70cc816ca38c8b4febf6bb0a9637b9
BLAKE2b-256 checksum
How to use checksums
37531d4fa0321908698fbcc7422e7388461c3b3f6159f9f86dd0af0fce8c2fd3
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.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL h3_bound_cells-0.5.3-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
5a6365180c7ade5677406c4957b30c9c91883294f5733b20b566980dee754461
BLAKE2b-256 checksum
How to use checksums
0d0b7e9080ba4ef5dae0f506a78572542c45c16a10dc49daaa772430b7acc354
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.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL h3_bound_cells-0.5.3-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
8db55d265c78a4eb3c7cc30749dac1b6911736ec4a2e4c934bbb03e93d6e5856
BLAKE2b-256 checksum
How to use checksums
f48dc52d3767029882850c19468562bef2b7bdd89ce04b58c9a2b3541b45c2f2
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.3-cp39-abi3-manylinux_2_12_i686.manylinux2010_i686.whl

Download URL h3_bound_cells-0.5.3-cp39-abi3-manylinux_2_12_i686.manylinux2010_i686.whl
Size 5.3 MB
Tags CPython 3.9 Linux glibc 2.12+ x86-32 abi3
SHA-256 checksum
How to use checksums
983fc8682e4c7c8d5dab4283409e0cf0d86faffaa0547805f7a04ff407dffb31
BLAKE2b-256 checksum
How to use checksums
75f87fc13985e704e4b33cf99305edf857027a8b6e62ccdb8b952610e181c4ca
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.3-cp39-abi3-macosx_11_0_arm64.whl

Download URL h3_bound_cells-0.5.3-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
65779436c0a79e9139f21cb92b6670b9c239d764b5457eb660dd91a95ac949cb
BLAKE2b-256 checksum
How to use checksums
7844cc40b28cb998c143b145c77f609e53a1dbac9c79ee12a9ffdff5a20437d4
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

This release

0.5.3 This release

11 release files

0.5.2

11 release files

0.5.1

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