=== versions === python 3.12.0 | h3 4.5.0 (C library 4.5.0) | duckdb 2.0.0 | geopandas 1.2.0 | shapely 2.2.0 === 1. Overture places for Greater London === downloaded from 1 Overture file(s) in 8.8 s Overture release 2026-10-21.0: 756,088 places in the bounding box (52.7 MB on disk) ONS boundary E12000007 London: 1,573.3 km2 inside London: 670,318 | closed: 30,749 | confidence < 0.5: 57,430 | left: 582,139 largest stack: 4,322 places at (51.51357, -0.12430), e.g. Cupella Uk, Salve Herbal, Hubnetix Corporation dropping 41,058 places at 247 coordinates shared by 50+ places (mostly registered-office addresses) | kept: 541,081 top categories: professional_service 29,741, restaurant 29,114, home_service 28,953, personal_or_beauty_service 23,742, financial_service 18,191, fashion_and_apparel_store 17,162 cafes (cafe + coffee_shop): 9,156 === 2. one point, one cell: the h3-py v4 API === latlng_to_cell(51.50809, -0.12804, 9) = 89195da49b7ffff as a 64-bit integer: 617439388698673151 | resolution 9 | base cell 12 | pentagon? False cell centre (51.50784, -0.12571), 164 m from the input point; boundary has 6 vertices cell_to_parent(cell, 7) = 87195da49ffffff | children at res 10: 7 | grid_disk k=1: 7 cells, k=2: 19 area of this cell 94,175 m2 vs global average res-9 hexagon 105,333 m2 === H3 resolutions: average size and the cell at Trafalgar Square === res avg_area_km2 avg_edge_km cells_on_earth london_cell_km2 london/avg 0 4.35745e+06 1,281 122 4.10617e+06 0.942 1 609,788 483.1 842 523,942 0.859 2 86,801.8 182.5 5,882 76,219.8 0.878 3 12,393.4 68.98 41,162 11,131.6 0.898 4 1,770.35 26.07 288,122 1,586.72 0.896 5 252.904 9.854 2,016,842 226.037 0.894 6 36.1291 3.725 14,117,882 32.3094 0.894 7 5.16129 1.406 98,825,162 4.61548 0.894 8 0.737328 0.5314 691,776,122 0.659268 0.894 9 0.105333 0.2008 4,842,432,842 0.0941753 0.894 10 0.0150475 0.07586 33,897,029,882 0.0134539 0.894 11 0.00214964 0.02866 237,279,209,162 0.001922 0.894 12 0.000307092 0.01083 1,660,954,464,122 0.000274571 0.894 13 4.38703e-05 0.004092 11,626,681,248,842 3.92244e-05 0.894 14 6.26718e-06 0.001546 81,386,768,741,882 5.60349e-06 0.894 15 8.95312e-07 0.0005842 569,707,381,193,162 8.00499e-07 0.894 pentagons per resolution: 12; the grid is oriented so that they all fall in the sea === 3. fill the London polygon with cells === geo_to_h3shape -> LatLngMultiPoly with 11 part(s) res 7 contain=center : 342 cells ( 0 duplicates), 1,578.1 km2 (100.3% of the polygon area) in 0.01 s res 7 contain=full : 252 cells ( 0 duplicates), 1,162.7 km2 ( 73.9% of the polygon area) in 0.01 s res 7 contain=overlap: 406 cells (13 duplicates), 1,873.3 km2 (119.1% of the polygon area) in 0.01 s res 8 contain=center : 2,374 cells ( 0 duplicates), 1,564.8 km2 ( 99.5% of the polygon area) in 0.02 s res 8 contain=full : 2,125 cells ( 0 duplicates), 1,400.7 km2 ( 89.0% of the polygon area) in 0.03 s res 8 contain=overlap: 2,579 cells (15 duplicates), 1,699.9 km2 (108.0% of the polygon area) in 0.04 s res 9 contain=center : 16,668 cells ( 0 duplicates), 1,569.5 km2 ( 99.8% of the polygon area) in 0.11 s res 9 contain=full : 15,908 cells ( 0 duplicates), 1,498.0 km2 ( 95.2% of the polygon area) in 0.15 s res 9 contain=overlap: 17,275 cells (20 duplicates), 1,626.7 km2 (103.4% of the polygon area) in 0.22 s geo_to_cells(geometry, 8) gives the same cells as contain='center' compact_cells: 16,668 res-9 cells -> 1,650 mixed-resolution cells (res 6: 20, res 7: 122, res 8: 387, res 9: 1121) res-8 cell areas inside London: 0.6550 to 0.6627 km2 (range 1.18%), mean 0.6592 km2 === 4. index 541,081 points: h3-py loop vs DuckDB h3 extension === h3-py list comprehension: 541,081 cells in 0.42 s (779 ns per point) DuckDB h3_latlng_to_cell: 541,081 cells in 0.41 s (753 ns per point) identical cell IDs from both: True res-8 cells: 2,374 | empty: 38 (1.6%) | points whose cell centre is outside the polygon: 10,181 places per cell: median 116, 90th pct 482, 99th pct 1789, max 7,533 h3 places per_km2 centre top_category 88195da49dfffff 7533 11,425 51.5175, -0.1468 professional_service 88195da499fffff 7508 11,389 51.5154, -0.1346 professional_service 88195da491fffff 6205 9,411 51.5097, -0.1425 financial_service 88194ad325fffff 5579 8,464 51.5133, -0.1224 professional_service 88194ad305fffff 4815 7,308 51.5148, -0.0901 financial_service busiest cell: 7,533 places at 3,992 distinct coordinates; the 5 largest stacks hold 48, 47, 46, 45, 41 places (3% of the cell) DuckDB GROUP BY gives the same counts: True === hierarchy: is the parent of a point's res-9 cell its res-8 cell? === cell_to_parent(res-9 cell, 8) != latlng_to_cell(point, 8) for 38,027 of 541,081 points (7.0%) rolling res-9 counts up to res 8 changes 2,051 of 2,374 cell counts (largest change 291 places) === 5. k-ring smoothing of cafe counts at res 9 === raw : cells > 0 20.6% | max 32.00 at (51.5129, -0.1316) | std 1.722 | lag-1 autocorrelation 0.67 k1 : cells > 0 60.5% | max 22.00 at (51.5131, -0.1270) | std 1.230 | lag-1 autocorrelation 0.97 k2_decay : cells > 0 82.6% | max 19.46 at (51.5129, -0.1316) | std 1.124 | lag-1 autocorrelation 0.99 DuckDB h3_grid_disk scatter-sum: max |difference| from the Python k=1 mean = 0.00e+00 === 6. hexagons vs squares of the same area === square side for equal area with the mean London res-8 hexagon: 811.9 m hexagon: 6 neighbours at 836-911 m from the centre square : 4 edge neighbours at 812 m and 4 corner neighbours at 1148 m compactness 4*pi*A/P^2: hexagon 0.904, square 0.785 farthest point from the centre: hexagon 527 m, square 574 m mean distance from a place to its cell centre: hexagon 309 m, square 313 m square : 2,459 occupied cells, max 7,624 places in a cell square shifted by half a cell : 2,457 occupied cells, max 8,032 places in a cell H3 res 8 : 2,456 occupied cells, max 7,533 places in a cell moving the square grid origin by 406 m changes the count of the cell a place falls in by a median 36% (90th pct 117%) === figures === wrote 01-h3-hierarchy-kring.png, 02-polygon-fill-modes.png, 03-london-places-res8.png, 04-kring-smoothing.png, 05-hex-vs-square.png, 06-resolution-choice.png