Introducing H3 Version 4.0.0
By: Isaac Brodsky (Foursquare), David Ellis (IaSQL), AJ Friend (Uber), Nick Rabinowitz (Foursquare)
Today marks the release of version 4.0.0 of the H3 hexagonal grid system. With this new version comes numerous API improvements as well as updates to the Java, Javascript, and Python bindings.
To provide more detail, H3 follows semantic versioning to help developers better understand how the library is changing. This release includes breaking API changes that will improve function naming, robustness to errors, and extensibility of the API.
However, the H3 grid system itself is unchanged; how points are assigned to cells and the identifiers of those cells are stable across major versions of the library. Cell identifiers generated from the previous version of the library will work in version 4 and vice versa.
Function name changes
The biggest change developers will see with version 4 is changes to function names in H3. These were updated to be more consistently named and to more precisely describe what they do.
While changing function names can add friction for developers who want to upgrade, this update addresses a significant user pain point. Many H3 functions were named organically as the library was developed. Functions like kRing, hexRing, and hexRange were vague and confusing to users, and it was difficult to tell which one to use in a given situation, even though they produce very different outputs. Lack of clarity around issues like lat/long order and the tradeoffs between unsafe-but-fast and safe-but-slow functions led to spurious bug reports and confusion for developers using the H3 library.
These functions have been replaced with consistently named functions. kRing has been renamed to gridDisk, as disk better describes the concept of a filled-in disk. hexRange has been renamed to gridDiskUnsafe, with the “unsafe” suffix indicating this function can fail on some inputs. hexRing has been renamed to gridRingUnsafe, as “ring” better describes the concept of a hollow ring of cells.
We acknowledge that name changes can be disruptive for developers, but for many applications, migration should be a straightforward mechanical change. When possible, we’ve added legacy APIs to the bindings to make the transition easier. Our hope is that combining the changes into a single major-version upgrade will make migration simpler. We feel the benefits of clear, consistent names will outweigh the costs, and we do not expect to make large naming changes again in the future.
Concept name changes
More generally, a few concepts have been renamed throughout the library. In fact, we now have a glossary of these terms.
One of the more consequential changes is renaming a hex to a cell. Since the H3 library is mostly used to refer to hexagonal grid cells, we casually refer to these as hexes. As the H3 grid system includes twelve pentagons at every resolution in order to be a fully global system, this presents an issue in the API when functions work on both hexagon and pentagon cells. (Note: We are referring to topological hexagons or pentagons, not the number of geographic vertexes.) Other functions referred to h3 in their name without indicating whether it was a cell index or another indexing mode, such as a directed edge or vertex.
Cell has been adopted as the better term for a unit polygon in the H3 grid system, such as the common latLngToCell (previously geoToH3), cellToLatLng (previously h3ToGeo), and cellToBoundary (previously h3ToGeoBoundary). We have also established consistent naming for other entities in the system, including DirectedEdge and Vertex.
Error codes
Error return codes are new in H3 version 4. Previously, many core library functions would either need to use special return values like zero to indicate that a call failed, or simply would not have a way to indicate to the caller that some prerequisite was not met. The new H3Error return code is returned consistently throughout the library, excluding a few functions that are simple enough to never need to return errors. This makes it possible for applications to appropriately handle invalid states.
The new error code is propagated to the application by bindings when errors occur. The values returned for errors have been designed to never be confused with H3 indexes. The error values can be readily extended from 32 to 64 bits and stored alongside H3 indexes, for example when an application would like to ignore errors or handle them later.
Extensibility
H3 version 4 provides an API basis for further development on the H3 core library to proceed.
Particularly, the polygonToCells (previously polyfill) function now accepts an options parameter which can be used for alternative containment criteria than the current centroid-containment one.
The local IJ series of functions (cellToLocalIj and localIjToCell, previously experimentalH3ToLocalIJ and experimentalLocalIJToH3) also now accept an options parameter for similar extensibility reasons. In light of these functions’ continued inclusion in the library for years, they are no longer marked as “experimental.”
Vertex mode
Vertex mode is a new indexing mode in H3 which enables developers to refer to specific topological vertexes in the H3 grid system. While the cellToBoundary function provides geographical vertexes for a given cell, these are subject to floating point error and are not guaranteed to be exactly equal between neighboring cells. This can make it difficult to match vertexes across cells, in turn making certain geospatial operations difficult or even impossible.
Vertex indexes provide a new mode in the H3 indexing system that offers a canonical 64-bit index for every vertex in the grid, which is the same for each of the three cells that share it. This solves several problems internal to the library with regard to calculating the geometry for edges and groups of cells, and provides a new primitive for external users with advanced use cases.
Robustness
In addition to API changes, version 4 of H3 improves overall robustness. A full suite of fuzzers has been added to the core library and bugs have been fixed based on their findings. For context, H3 is regularly fuzzed by Google’s OSS-Fuzz project. Fuzzing joins H3’s robustness strategy alongside unit testing, exhaustive and large-sample test suites, and high code coverage.
We would like to thank the community contributors to H3 for their continued support on making H3 one of the most widely used discrete global grid systems today. The H3 steering committee is made up of Isaac Brodsky (Foursquare), David Ellis (IaSQL), AJ Friend (Uber), and Nick Rabinowitz (Foursquare).