H3_POLYFILL

Return the H3 cells at a given resolution whose centers fall inside a WKT polygon.

Category: h3Returns: ARRAY<BIGINT>Dialect: Standard

Syntax

H3_POLYFILL(polygon_wkt, resolution)

Description

## Overview Returns the H3 cells at the requested resolution whose centers lie inside the given polygon. The polygon is provided as a WKT POLYGON string in (longitude latitude) coordinate order. This is the canonical way to rasterize a geographic region into an H3 cover: pass a polygon, get back a sorted set of cell IDs that you can then join against an H3-indexed table. Use it whenever you need to intersect a region with an H3-bucketed dataset without running a point-in-polygon test per row. The typical pattern is `polyfill -> explode -> join on h3_cell`, which pushes the spatial test to an equi-join on a BIGINT column and runs orders of magnitude faster than a geometric filter. ## Behavior - Returns an ARRAY<BIGINT> of H3 cell IDs at the requested resolution. - Coverage is center-based: a cell is included iff its geometric center falls strictly inside the polygon. Cells that overlap the boundary but whose center lies outside are not included. - Returns NULL if the polygon WKT is malformed, has fewer than 3 distinct vertices, or cannot be parsed. - Returns NULL if the resolution is outside [0, 15]. - Returns NULL if either argument is NULL. - The polygon is interpreted on the ellipsoid; very long edges are not re-projected, so at continental scale the fill may miss or include edge cells near cell-size-fraction boundaries. - Results are capped at approximately 10,000,000 cells; fills exceeding this return NULL to protect memory. - Coordinate order in WKT is (lng lat), opposite of the (lat lng) order used by H3_LATLNG_TO_CELL. ## Polyfill mode This implementation uses the center-containment mode: a cell is included if and only if its center point falls inside the polygon. Other modes that exist in the H3 specification: - **contain-all**: include a cell only if the entire cell is inside the polygon (smallest output). - **contain-centroid** (the mode used here): include a cell if its center is inside the polygon. - **cover-any**: include a cell if any part of it intersects the polygon (largest output). For exact boundary coverage, combine this function with a boundary ring from the coarser polygon and a set union. ## H3 resolution reference | Res | Average edge length | Cells per km^2 (hexagon) | | --- | --- | --- | | 7 | 1.22 km | ~0.19 | | 8 | 461 m | ~1.36 | | 9 | 174 m | ~9.5 | | 10 | 65.9 m | ~67 | | 12 | 9.4 m | ~3,260 | ## Compatibility - Follows the standard H3 hierarchical hex grid specification for polygon fill. The coverage semantics match the centroid-containment mode.

Parameters

NameTypeDescription
polygon_wktSpecifies the polygon to fill, as a WKT POLYGON string with (longitude latitude) coordinate order. The ring must be closed (first vertex equals last vertex) and must have at least three distinct vertices. Holes are not supported.
resolutionSpecifies the H3 resolution of the fill cells, as an integer from 0 through 15. Finer resolutions produce more cells; expect cell count to grow as roughly 7 per resolution level.

Examples

-- Returns every resolution 8 cell whose center falls inside the polygon.
SELECT H3_POLYFILL(
  'POLYGON((-0.15 51.50, -0.15 51.52, -0.10 51.52, -0.10 51.50, -0.15 51.50))',
  8
) AS cells;
-- Cell count grows with area and with resolution. Use this to estimate workload.
SELECT SIZE(H3_POLYFILL(
  'POLYGON((-73.95 40.70, -73.95 40.80, -73.93 40.80, -73.93 40.70, -73.95 40.70))',
  9
)) AS cell_count;
-- Intersect a polygon region with an H3-bucketed events table by exploding the polyfill.
WITH region_cells AS (
  SELECT EXPLODE(H3_POLYFILL(
    'POLYGON((2.29 48.86, 2.29 48.88, 2.34 48.88, 2.34 48.86, 2.29 48.86))',
    9
  )) AS h3_cell
)
SELECT SUM(events) AS region_events
FROM region_cells r
JOIN analytics.curated.h3_events_res9 e
  ON e.h3_cell = r.h3_cell;
SELECT
  SIZE(H3_POLYFILL('POLYGON((139.60 35.65, 139.60 35.70, 139.75 35.70, 139.75 35.65, 139.60 35.65))', 8)) AS res8_cells,
  SIZE(H3_POLYFILL('POLYGON((139.60 35.65, 139.60 35.70, 139.75 35.70, 139.75 35.65, 139.60 35.65))', 9)) AS res9_cells;
-- An unclosed ring or fewer than 3 vertices returns NULL.
SELECT H3_POLYFILL('POLYGON((0 0, 1 0))', 8) AS cells;

Pitfalls

See Also

Open in interactive docs →   DeltaForge home →