Uber H3 Hexagonal Modeling
Last updated
Last updated
Uber H3 is an open-source geospatial system created by Uber Technologies. H3 provides a hierarchical grid system that divides the Earth's surface into hexagons of varying sizes, allowing for easy location-based indexing, search, and analysis.
Hexagons can be created at a single scale, for instance to fill an arbitrary polygon at one resolution (see below). They can also be used to generate a much-smaller number of hexagons at multiple scales. In general, operating on H3 hexagons is much faster than on raw arbitrary geometries, at a cost of some precision. Because each hexagon is exactly the same size, this is particularly advantageous for GPU-accelerated workflows.
A principal advantage of the system is that for a given scale, hexagons are approximately-equal area. This stands in contrast to other subdivision schemes based on longitudes and latitudes or web Mercator map projections.
A second advantage is that with hexagons, neighbors in all directions are equidistant. This is not true for rectangular subdivisions like pixels, whose 8 neighbors are at different distances.
The exact amount of precision lost can be tightly bounded, with the smallest sized hexagons supported being about 1m2. That’s more accurate than most current available data sources, short of survey data.
There are some disadvantages to be aware of. The first is that the world can not actually be divided up completely cleanly into hexagons. It turns out that a few pentagons are needed, and this introduces discontinuities. However the system has cleverly placed those pentagons far away from any land masses, so this is only practically a concern for specific maritime operations.
The second issue is that hexagons at adjacent scales do not nest exactly:
This doesn’t much affect practical operations at any single given scale. But if you look carefully at the California multiscale plot above you will discover tiny discontinuities in the form of gaps or overlaps. These don’t amount to a large percentage of the total area, but nonetheless mean this method is not appropriate when exact counts are required.
H3_PointToCell(POINT p, INTEGER resolution) -> BIGINT
H3_LonLatToCell(DOUBLE lon, DOUBLE lat, INTEGER resolution) -> BIGINT
These functions take a world-space coordinate (in WGS84/SRID4326) as either POINT
or DOUBLE
, and a resolution value as INTEGER
(which must be in the range 0 to 15) and return an H3Index
as a BIGINT
corresponding to the cell at that resolution with a center point nearest to the given point. The index value may be projected, stored in a table, used as a Join Key, or as the input to one of the other functions.
Note: H3 indices in this form are intended to be immutable values and not human-readable. Any manipulation of the value may destroy its content.
Note: The H3_PointToCell
function only accepts POINT
projections from columns. It does not accept temporary values or literals.
H3_CellToLon(BIGINT cell) -> DOUBLE
H3_CellToLat(BIGINT cell) -> DOUBLE
These functions take an H3 Index value as BIGINT
and convert it back to a world-space coordinate (in WGS84/SRID4326) returning the longitude or the latitude value respectively of the center point of the cell represented by the input index.
H3_CellToString_TEXT(BIGINT cell) -> TEXT ENCODING DICT
H3_CellToString_TEXT_NONE(BIGINT cell) -> TEXT ENCODING NONE
These functions take an H3 Index value as BIGINT
and convert it to the corresponding H3 Hex String representation. There are two variants of the function depending on whether the output needs to be a Dictionary-Encoded or None-Encoded TEXT
value. The latter is fine for projection for display. The former should be used if required as a Join Key. Note that heavy use of the Dictionary-Encoded version to generate many unique values may result in very large string dictionaries in the database.
H3_StringToCell([TEXT ENCODING DICT|TEXT ENCODING NONE]) -> BIGINT
This function performs the reverse, taking a H3 Hex String as either a Dictionary-Encoded or None-Encoding TEXT
value, and returning the corresponding numeric representation as BIGINT
. This must be used to convert H3 Indices stored as TEXT
columns into numeric values for passing to the other functions.
H3_CellToParent(BIGINT cell, INTEGER resolution) -> BIGINT
This function takes an H3 Index value as BIGINT
and returns the H3 Index value of the parent cell containing the input cell, at the specified resolution (larger).
H3_IsValidCell(BIGINT cell) -> BOOL
This function checks an H3 Index value for validity. Invalid input values result in a FALSE
result.
H3_CellToBoundary_WKT(BIGINT cell) -> TEXT ENCODING DICT
As the implementation of these functions is provided by the open-source H3 SDK, query stages containing them will run on CPU only.
H3 codes can be used in regular joins, including joins in Immerse. They can also be used as aggregators, such as in Immerse custom dimensions. For points which are exactly aligned, such as imports from raster data bands of the same source, aggregating on H3 codes is faster than the exact geographic overlaps function ST_EQUALS.
This function takes an H3 Index as BIGINT
and returns a WKT (Well-Known Text) representation of the geo POLYGON
of the cell boundary as a Dictionary-Encoded TEXT
value. Note that the polygon may be a hexagon or a pentagon, depending on the cell location. See the for more details.
Uber's H3 python library provides a wider range of functions than those available above (although at significantly slower performance). The library defaults to generating H3 codes as hexadecimal strings, but can be configured to support BIGINT codes. PSee the for more details.