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

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.0
File Size Uploaded
h3_bound_cells-0.5.0.tar.gz 69.5 kB Details

Built distributions (wheels)

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

Download URL h3_bound_cells-0.5.0.tar.gz
Size 69.5 kB
Tags Source
SHA-256 checksum
How to use checksums
a3393a7c60f8f99f02b6d3c7d28f6be9881358a4c6223ede8e8d47334c505a41
BLAKE2b-256 checksum
How to use checksums
98e8b0af5916aa4ee8ad97a16050eee42f79420f861d3dcad7f14e9eee9dd6c7
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.0-cp39-abi3-win_arm64.whl

Download URL h3_bound_cells-0.5.0-cp39-abi3-win_arm64.whl
Size 4.2 MB
Tags CPython 3.9 Windows ARM64 abi3
SHA-256 checksum
How to use checksums
eca0fa081ea988b91eb1b01c5308c12d62ece86c38864ccdb7c865a2b43a748f
BLAKE2b-256 checksum
How to use checksums
798a8a9c83ea5f684cf4f7930aff7ef77ebaba073f6e1a7346f0c49a72d8f3ae
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.0-cp39-abi3-win_amd64.whl

Download URL h3_bound_cells-0.5.0-cp39-abi3-win_amd64.whl
Size 4.7 MB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
c036eaa40ea68c235b59e3b395f38b7fc9e8e9deb60d2c88470ad22c253b6fcd
BLAKE2b-256 checksum
How to use checksums
758c52a0a38c9f76439c9861b5fddcf95ef04e8db83cc7f7ddddca6d2125ad31
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.0-cp39-abi3-win32.whl

Download URL h3_bound_cells-0.5.0-cp39-abi3-win32.whl
Size 4.2 MB
Tags CPython 3.9 Windows x86-32 abi3
SHA-256 checksum
How to use checksums
ad357b4111e83d00f3006c7ef5140201ec8ebc359951aad398d2823ae5bb3120
BLAKE2b-256 checksum
How to use checksums
85cdc4f9feceadf88b65b33a124a2fce0b34760f949e8d57f24db35c13f8189e
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.0-cp39-abi3-musllinux_1_2_x86_64.whl

Download URL h3_bound_cells-0.5.0-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
75355f5a8a172e996391f340cc4ce15c614effcc274ece95101cfa2ee9cf1cfb
BLAKE2b-256 checksum
How to use checksums
13d137ff95aa005a24266c55c616364db8e171abc555958f309c888534b26043
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.0-cp39-abi3-musllinux_1_2_i686.whl

Download URL h3_bound_cells-0.5.0-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
175490bc70a7b4b4c823410b317c35c1c4aad3fbb745af1a8bddef2ce0ac0ede
BLAKE2b-256 checksum
How to use checksums
63173a1a22ed705df7a17a5dc7aef6725698c43681cb470d66750960f14729ca
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.0-cp39-abi3-musllinux_1_2_aarch64.whl

Download URL h3_bound_cells-0.5.0-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
49c6221b8a8587daf2bb6c756012e2431ea347c525a9a4fc9dea49f038bbd329
BLAKE2b-256 checksum
How to use checksums
9c282e674474e7097d81924c27e3620eb7c85ec670dde0d763609cd1089601c3
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.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL h3_bound_cells-0.5.0-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
1ce8e47173aebe2aa8bdd950701946fa1ede637fd60d5d32443ffb33bd1c047d
BLAKE2b-256 checksum
How to use checksums
47ee5950c38d07b8131c48ce7c85b3a2aa0acdf28e9613f0330a5f220a468937
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.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL h3_bound_cells-0.5.0-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
aefdd60f83a4982b87184d6f9f39912bbec9cfb0b705d57e136cf326f519b18d
BLAKE2b-256 checksum
How to use checksums
57f4518d20151cbe45383970d8f5c76de9ff2b4cbdcec4bdeeec47362568dbb9
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.0-cp39-abi3-manylinux_2_12_i686.manylinux2010_i686.whl

Download URL h3_bound_cells-0.5.0-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
92c5272bbc1801ab40ba80f157470c76554384ca561f123d42d2e9e2f6caadf2
BLAKE2b-256 checksum
How to use checksums
b4fba174c7ca1e4557e9fe85f076f687abb9c9de96f97c5dd0b34ca2d5dda98b
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.0-cp39-abi3-macosx_11_0_arm64.whl

Download URL h3_bound_cells-0.5.0-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
053ca58bc54121a0ead23eb51d1738f5811e125f3ab3b1025b193b6c7afbaf38
BLAKE2b-256 checksum
How to use checksums
87c79b85d43887918a8c17539f140b4446c8fe0534e2c299f967c78013bb3179
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

0.5.1

11 release files

This release

0.5.0 This release

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