# Uber H3 Hexagonal Modeling ### Uber H3 Functions ### Overview 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 single-scale tessellation of California into Uber h3 hexagons](https://files.buildwithfern.com/heavyai.docs.buildwithfern.com/heavyai/cb9dd1d8be018abfaab81c8c757f775c5870dcef6f8ab5df5f71ae445625db58/docs/assets/image-1.png) ![A multi-scale tesselation of California into Uber h3 hexagons](https://files.buildwithfern.com/heavyai.docs.buildwithfern.com/heavyai/77daaa9217d4816052c0612d30449f7e165e20df1a75de5d66c617bcec550173/docs/assets/image-2.png) ### Advantages 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. ![Pixel neighbors vary in distance](https://files.buildwithfern.com/heavyai.docs.buildwithfern.com/heavyai/b6596a095d8b2b3641cf51f705c0a228b0e9faf848fcda211744a714eb41982a/docs/assets/image-27.png) ![Hexagon neighbors are equidistant](https://files.buildwithfern.com/heavyai.docs.buildwithfern.com/heavyai/fafd6b86fb3b6b81b9d74aba3b92c660ed730a1975af38e26bacf6358aea7230/docs/assets/image.png) 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. ### Disadvantages 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: ![Hexagons at varying scales do not nest cleanly](https://files.buildwithfern.com/heavyai.docs.buildwithfern.com/heavyai/9cdba3b4e37213e536ede460db01cf2e06de84f756541f0003e3064927b61aa1/docs/assets/image-33.png) 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. ### Supported Methods #### Coordinates to H3 Indices `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 Indices to Coordinates `H3_CellToLon(BIGINT cell) -> DOUBLE` `H3_CellToLat(BIGINT cell) -> DOUBLE` `H3_CellToPoint(BIGINT cell) -> POINT` These functions take an H3 Index value as `BIGINT` and convert it back to a world-space coordinate (in WGS84/SRID4326) returning, respectively, the longitude value, latitude value, or both as a `POINT` of the center point of the cell represented by the input index. #### Conversions to and from Hex String Representation `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. #### Getting the Index Parent `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). #### Checking Index Validity `H3_IsValidCell(BIGINT cell) -> BOOL` This function checks an H3 Index value for validity. Invalid input values result in a `FALSE` result. #### Converting Index to Geometry `H3_CellToBoundary_WKT(BIGINT cell) -> TEXT ENCODING DICT` `H3_CellToBoundary_POLYGON(BIGINT cell) -> POLYGON` The first 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. The second function takes the same argument as the first but returns the cell boundary as a geo `POLYGON` . Note that, in either case, the polygon may be a hexagon or a pentagon, depending on the cell location. See the [H3 documentation](https://h3geo.org/) for more details. ### Query Execution As the implementation of these functions is provided by the open-source H3 SDK, query stages containing them will run on CPU only. ### H3 Usage Notes 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 [H3 documentation](https://h3geo.org/) for more details. 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.