Uber H3 Index

Abstract

  • given a latitude/longitude point, find the index of the containing H3 cell at a particular resolution
  • given an H3 index, find the latitude/longitude cell center
  • given an H3 index, determine the cell boundary in latitude/longitude coordinates

Overview

The H3 grid is constructed on the icosahedron by recursively creating increasingly higher precision hexagon grids until the desired resolution is achieved. Note that it is impossible to tile the sphere/icosahedron completely with hexagons; each resolution of an icosahedral hexagon grid must contain exactly 12 pentagons at every resolution, with one pentagon centered on each of the icosahedron vertices.

Base Cells

The first H3 resolution (resolution 0) consists of 122 cells (110 hexagons and 12 icosahedron vertex-centered pentagons), referred to as the base cells.

Resolution

Each subsequent resolution beyond resolution 0 is created using an aperture 7 resolution spacing (aperture refers to the number of cells in the next finer resolution grid for each cell); as resolution increases the unit length is scaled by \sqrt{7}7 and each hexagon has 1/7th the area of a hexagon at the next coarser resolution (as measured on the icosahedron).

H3 provides 15 finer grid resolutions in addition to the resolution 0 base cells. The finest resolution, resolution 15, has cells with an area of less than 1 m^2.

H3 Index

IJK Coordinate

Discrete hexagon planar grid systems naturally have 3 coordinate axes spaced 120° apart. We refer to such a system as an ijk coordinate system, for the three coordinate axes i, j, and k. A single ijk coordinate triplet is represented in the H3 Core Library using the structure type CoordIJK

img

1.0 unit distance in the Hex2d system is the distance between adjacent cell centers in the ijk coordinate system.

Index Representation

The H3Index is the integer representation of an H3 index, which can be placed into multiple modes to indicate the kind of concept being indexed. Mode 1 is an H3 Cell (Hexagon) Index, mode 2 is an H3 Unidirectional Edge (Hexagon A -> Hexagon B) Index, mode 3 is planned to be a bidirectional edge (Hexagon A <-> Hexagon B). Mode 0 is reserved and indicates an invalid H3 index.

However, only mode 1 will be used in RCS Demo.

The components of the H3 cell index (mode 1) are packed into a 64-bit integer in order, highest bit first, as follows:

  • 1 bit reserved and set to 0,
  • 4 bits to indicate the index mode,
  • 3 bits reserved and set to 0,
  • 4 bits to indicate the cell resolution 0-15,
  • 7 bits to indicate the base cell 0-121, and
  • 3 bits to indicate each subsequent digit 0-6 from resolution 1 up to the resolution of the cell (45 bits total are reserved for resolutions 1-15)

Bit layout of H3Index

The layout of an H3Index is shown below in table form. The interpretation of the “Reserved/edge” field differs depending on the mode of the index.

  0x0F 0x0E 0x0D 0x0C 0x0B 0x0A 0x09 0x08 0x07 0x06 0x05 0x04 0x03 0x02 0x01 0x00
0x30 Reserved Mode Reserved/edge Resolution Base cell                      
0x20 Base cell     Digit 1     Digit 2     Digit 3     Digit 4     Digit 5
0x10     Digit 6     Digit 7     Digit 8     Digit 9     Digit 10  
0x00   Digit 11     Digit 12     Digit 13     Digit 14     Digit 15    

Experiment

I have picked 2 points in Nanjing City: [37.7076131999975672,-122.5123436999983966] and [37.813318999983238,-122.4089866999972145] and then checked the index of them form resolution 0 to resolution 15.

it is easy to see the bit layout in H3 Index.

no. bit meaning
0 reserved bit and default to 0
1-4 mode 1
5-7 since we only use mode 1, it was reserved and set to 0
8-11 resolution level
12-18 the base cell
19-63 ijk coordinator from resolution 1 - 15, thus the total is 3*15

Redis Key Design

According to the H3 concept and the experiment that we have, we can find once we get 15th resolution we can get all parents’ ijk coordinate information. Thus, we can keep the 15th resolution index to construct the Redis key which is in binary format.

[7 bits base cell info(resolution 0)] + [15 ijk coordinate info(resolution 1 - 15)]

For the points in the experiments, once we call h3 api geoToH3() we can get the index as follow:

point 1: 0 0001 000 1111 0010100 000110000100000001101110010110000000110011010

point 2: 0 0001 000 1111 0010100 000110000100101000000011001110101001101000000

==> find the keys:

key 1: 0010100000110000100000001101110010110000000110011010

key 2: 0010100000110000100101000000011001110101001101000000

Conclusion:

  • key length is 52 bits,
  • unique key for each point,
  • compact the original index,
  • easy to query aggregation and union

Method Design

In RCS Backend Cloud project, the Hexagon.class provides a method to generate compact index.

    public static String getCompactHexagonKey(double lat, double lng) {
        
        String binaryIndex = String.format("%64s", new BigInteger(getMaxHexagonKey(lat, lng), 16).toString(2))
                .replace(" ", "0").substring(12);
        int face = Integer.parseInt(binaryIndex.substring(0, 7), 2);
        StringBuilder sb = new StringBuilder(String.valueOf(face));

        for(int i = 7; i < binaryIndex.length(); i+=3) {
            sb.append(String.valueOf(Integer.parseInt(binaryIndex.substring(i, i+3),2)));
        }
        return sb.toString();
    }

Categories:

H3   Java