executing-plans
executing-plans
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available
polygon-geospatialUse H3Shape, LatLngPoly, LatLngMultiPoly, and the GeoJSON-like interface to rasterize polygons, holes, and multipolygons to H3 cells or turn cells back into interoperable geometry.
Independent GitHub snapshot · Automated classification · Original documentation governs
Use this route for LatLngPoly, LatLngMultiPoly, GeoJSON-like dictionaries,
__geo_interface__ objects, polygon_to_cells, h3shape_to_cells,
geo_to_cells, cells_to_h3shape, and cells_to_geo. It covers holes,
multipolygons, ring normalization, CRS mistakes, and dateline-sensitive
workflows. It does not cover cell/grid/edge algorithms; use
core-indexing for those. Use
api-variants for integer, NumPy, memoryview, or
representation selection, and the root h3-py route for
installation and package-wide routing.
(lat, lng) pairs, in degrees: latitude first,
longitude second.__geo_interface__ coordinates use (lng, lat) positions.
Swap exactly once at the boundary; never pass GeoJSON positions directly to
LatLngPoly.to_crs, rather than relabeling
its CRS. H3 does not interpret feet, meters, Web Mercator, or local grid
coordinates as latitude/longitude.LatLngPoly points must be 2D. GeoJSON conversion accepts positions
with extra ordinates but discards the third and later values; elevation is
not preserved by an H3 shape round trip.geometry before geo_to_h3shape; that function accepts Polygon or
MultiPolygon geometry dictionaries, not Feature/FeatureCollection wrappers.__geo_interface__ is the GeoJSON-like (lng, lat) form. Validate ring closure, dimensions, finite numeric coordinates,
and multipolygon nesting before converting.LatLngPoly(outer, *holes) for one polygon. Construct each
component as a LatLngPoly, then call LatLngMultiPoly(poly1, poly2, ...).
Do not pass raw nested multipolygon coordinates to the latter.h3shape_to_cells(shape, res) or its alias
polygon_to_cells(shape, res). This is centroid/center containment and
output order is not guaranteed. Use geo_to_cells(geo, res) when the input
is already a Polygon/MultiPolygon geometry or implements
__geo_interface__.cells_to_h3shape(cells, tight=True) when a single
LatLngPoly is preferable, or tight=False when a LatLngMultiPoly
container is required. Use cells_to_geo for a direct GeoJSON-like dict.
Normalize unordered cell results as sets for comparisons.h3shape_to_geo(shape, container=...)
and pass only its geometry member to consumers that expect a geometry.
The default auto emits the simplest Polygon or MultiPolygon.The stable shape-to-cells operation includes cells whose center is inside the
shape; it is not a guarantee of full polygon coverage or any overlap measure.
The experimental h3shape_to_cells_experimental / polygon_to_cells_experimental
functions add center, full, overlap, and bbox_overlap modes, but have no
API stability guarantee. Record the selected mode and package version when
using them.
H3 rasterization accepts outer and hole loops in either winding direction and
does not reorder user-supplied loops. GeoJSON consumers may expect the
right-hand rule (outer counterclockwise, holes clockwise), so normalize winding
with a geospatial library if exporting or plotting external geometry. Shapes
returned by cells_to_h3shape follow the right-hand rule. Keep holes inside
their own outer ring and use separate LatLngPoly objects for disjoint parts.
Treat rings crossing ±180° or enclosing a pole as difficult spherical cases. Use a valid longitude convention, test a small dateline fixture, and consider splitting a dateline-crossing GeoJSON geometry into parts before interoperability conversion. Cell-to-shape output for global, prime-meridian, or antimeridian cell bands may not round-trip through center containment; compare the recovered set explicitly rather than assuming a lossless boundary representation.
import h3
outer = [(37.804, -122.412), (37.778, -122.507), (37.733, -122.501)]
hole = [(37.782, -122.449), (37.779, -122.465), (37.788, -122.454)]
shape = h3.LatLngPoly(outer, hole)
cells = h3.h3shape_to_cells(shape, res=9)
geojson_geometry = h3.h3shape_to_geo(shape)
roundtrip_shape = h3.geo_to_h3shape(geojson_geometry)
assert roundtrip_shape.__geo_interface__ == geojson_geometry
For a deterministic structural check, run:
python scripts/validate_geojson.py --help
python scripts/validate_geojson.py --self-test
Read api-reference.md for exact constructors, containers, signatures, and return types; read workflows.md for copyable recipes; and read troubleshooting.md before retrying malformed or dateline-sensitive input.
(lat, lng) is used for H3 shapes and (lng, lat) for GeoJSON.Polygon, MultiPolygon, Feature, or collection) is
intentional and suitable for the downstream consumer.