Skip to main content
  1. Blog/

Exploring H3: Uber’s Hexagonal Global Grid System for Geospatial Indexing

·792 words·4 mins

When working with geospatial data at scale, one of the biggest challenges is efficiently aggregating and comparing geographic datasets. Traditional methods often involve complex spatial joins and shapefile operations that don’t scale well. That’s where H3 an open-source Discrete Global Grid System (DGGS) developed at Uber shines. It converts geographic coordinates into hexagonal grid indexes, enabling powerful spatial operations and simplifying geospatial data engineering. Uber originally built H3 to support dynamic ride pricing and urban mobility analytics, but it’s now widely used for environmental science, telecom, logistics, and city planning.

If I have a favorite shape, it would be a hexagon. I have spent years looking at hexagonal shaped cells in biology, hexagon computational models in at least three different domains and even built hexagonal shaped shielding of electro-magnetic radiation many moons ago. Here I will demonstrate how it works.

What Is H3?
#

At its core, H3 divides the world into a hierarchy of hexagonal cells. Imagine the world but as a hex map H3 like in the Civilization games (V and above).

Civilization V screen capture
Source

Each cell is uniquely identified by an H3 index (a 64-bit integer). These cells nest neatly into each other, smaller hexagons at higher resolutions fit within larger ones, providing a multi-resolution, global grid.

This system enables you to:

  • Index coordinates into cells that represent specific geographic areas.
  • Join datasets spatially without geometric intersection logic.
  • Aggregate data (e.g., population, trips, or incidents) at multiple resolutions.
  • Run neighborhood or proximity algorithms (e.g., nearest neighbors, flow networks).
  • Enable visual consistency in map based analytics.

Why Hexagons?
#

Why not squares or triangles?
Hexagons have several mathematical and geometric advantages:

  • They provide uniform distance between the center and all neighboring cells.
  • They minimize distortion across the globe better than squares.
  • They make spatial aggregation smoother, ideal for heatmaps and flow visualization.

In other words, hex grids are a sweet spot between accuracy and computational simplicity.

Working With H3 in Python
#

The official H3 Python bindings make it simple to start working with hexagonal grids.

Install it with:

poetry add h3

Example: Indexing Coordinates
#

Lets take a location, in Den Haag, there is this small no name island opposite the Binnenhof. It is the most famous unhabituated island in the whole of Netherlands. [eiland-in-de-hofvijver]](https://www.binnenhofrenovatie.nl/historie-archeologie/een-kleine-geschiedenis-van-het-eiland-in-de-hofvijver) . I am taking this position as an example for this demonstration.

Het eiland in de Hofvijver

import h3

#Het_eiland_in_de_Hofvijver.jpg
lat, lng = 52.080300610066836, 4.312371766726521

cell_0 = h3.latlng_to_cell(lat, lng, 0)
cell_15 = h3.latlng_to_cell(lat, lng, 15)

print(f"Hexagon id at Resolution 0 = {cell_0}")
print(f"Hexagon id at Resolution 15 = {cell_15}")
Hexagon id at Resolution 0 = 801ffffffffffff
Hexagon id at Resolution 15 = 8f196b84ec9a7b1

Each resolution corresponds to a different cell size, from huge (res 0) down to just to less than 1 m² (res 15).

ResAverage Hexagon Area (m²)
04,357,449,416,078.392
1609,788,441,794.134
286,801,780,398.997
312,393,434,655.088
41,770,347,654.491
5252,903,858.182
636,129,062.164
75,161,293.360
8737,327.598
9105,332.513
1015,047.502
112,149.643
12307.092
1343.870
146.267
150.895

You can check the resolution table on H3’s RESTable .

Here is the example at Resolution 15 (id: 8f196b84ec9a7b1):

H3 Resolution 15 Hexagon

Here is the example at Resolution 0 (id: 801ffffffffffff): It is huge.

H3 Resolution 0 Hexagon

Example: Polygon to Cells
#

A common task is to find all H3 cells that fall within a polygon, for example, a city boundary or service area.

here again I am taking Den Haag as an example

Den Haag bounding box

from h3 import polygon_to_cells, LatLngPoly

polygon_coords = [
    [51.9984, 4.1885],
    [51.9984, 4.4289],
    [52.1301, 4.4289],
    [52.1301, 4.1885],
    [51.9984, 4.1885]
]

shape = LatLngPoly(polygon_coords)
res = 8
cells = polygon_to_cells(shape, res=res)
print(f"Number of H3 cells at res {res}: {len(cells)}")
Number of H3 cells at res 8: 389

Den Haag bounding box with hexagons

Containment is determined by cell centroids, which ensures that polygon partitions translate neatly into cell partitions, perfect for aggregating city scale data.

Example: Checking Neighbor Cells
#

H3 can also determine adjacency relationships between cells using directed edges:

h3.are_neighbor_cells('8928308280fffff', '8928308280bffff')

This is particularly useful for routing, clustering, or diffusion models.

Real World Applications
#

H3 is a very powerful concept, think of it like a python dictionary but for geospatial coordinates. Here are a few ways H3 can be used in production workflows:

  • Urban analytics, aggregating millions of GPS points into hexagonal cells for visualization and analysis.
  • Mobility & logistics, computing trip density and demand heatmaps at multiple resolutions.
  • Telecom planning, aggregating signal strength or coverage into uniform grid cells.
  • Environmental monitoring, mapping deforestation or air quality data consistently across regions.

Check out Uber’s H3 urban analytics notebook for a deeper dive.

Conclusion
#

H3 elegantly bridges the gap between geospatial theory and practical data engineering. Whether you’re building dashboards, analyzing city patterns, or optimizing routes, H3 provides a consistent, scalable framework for geospatial indexing. If your work involves location data, H3 is absolutely worth exploring.