
H3: A Hexagonal Hierarchical Geospatial Indexing System - omot
https://github.com/uber/h3
======
macmccann
For anyone else wondering, like I did, why you would use a hexagonal indexing
system instead of a (roughly square) latitude longitude system, from
[https://eng.uber.com/elk/](https://eng.uber.com/elk/):

"Data size matters in Elasticsearch; a large index means too much data,
caching churn, and poor response time. When query volumes are large, ELK nodes
become overloaded, causing long garbage collection pauses or even system
outages.

To address this, we switched to hexagonal queries, dividing our maps into
hexagonal cells. Each hexagonal cell has a string ID determined by the hexagon
resolution level. A geodistance query can be roughly translated to a ring of
hexagon IDs; although a hexagonal ring is not a circular surface, it is close
enough for our use case. Due to this adjustment, our system’s query capacity
more than tripled."

~~~
scdoshi
S2, linked from the README[1], does the same hierarchical subdivisions in
squares, with each square having a string ID.

Squares divide into sub-squares exactly, but hexagon's don't sub-divide into
hexagon's neatly.[2]

Can someone explain the advantages of hexagons over squares in this use case?

[1][https://code.google.com/archive/p/s2-geometry-
library/](https://code.google.com/archive/p/s2-geometry-library/)
[2][https://www.illustrativemathematics.org/content-
standards/ta...](https://www.illustrativemathematics.org/content-
standards/tasks/1123)

~~~
dvanduzer
See sibling post for links, but the short answer: you can use 12 pentagons,
strategically interspersed. Like a (soccer) football.

edit: Oops, that only explains the tiling. For explanations of how the
hierarchy descends, Dr. Sahr produced some GIFs that give a little bit of an
overview of how the resolutions overlay:
[http://webpages.sou.edu/~sahrk/dgg/images/topogif/topogif.ht...](http://webpages.sou.edu/~sahrk/dgg/images/topogif/topogif.html)

~~~
scdoshi
Thanks for that link.

Also found this which goes into some more detailed comparison with rectangular
grids:

[https://github.com/uber/h3/blob/master/docs/doxyfiles/usecas...](https://github.com/uber/h3/blob/master/docs/doxyfiles/usecases.md)

------
snake_plissken
What's with the output of the hexagon's vertices? There technically isn't a
285th degree line of meridian, or are they saying, 285 degrees east from 0? In
which case, why don't they just subtract 360 from all values greater than 180
(since the input is in decimal degrees)?

~~~
snake_plissken
Looks like it's just a rough edge per this very insightful comment:
[https://news.ycombinator.com/item?id=16136912](https://news.ycombinator.com/item?id=16136912)

------
ISV_Damocles
I used to work at Uber and worked on H3. They're working on a blog post to
explain some more, but if you clone the repo and build the doxygen docs,
you'll get more explanation.

The big difference between this and S2 is that hexagons have only one kind of
neighbor, neighbors that border on an edge, instead of the two kinds of
"checkerboard" neighbors that squares have. This lets you do some interesting
analysis on data gathered with hexagons.

Movement between neighbors could be modelled as a current flow, with the edge
being a cross-sectional area between them, and since the edges are all equal
(unlike squares) you can consider it a constant factor on that analysis, and
then drop it and simply use the directional flow counts (the H3 UniEdge index)
directly.

H3 takes better care than S2 to keep both hexagon area and shape distortion to
a minimum together (area distortion is about the same as S2, but shape
distortion is much better than S2), so the hexagons look almost the same
almost anywhere on the planet, and so data gathered in one city on the planet
is directly comparable to data gathered in another city, which can let you do
interesting things like classify "types" of hexagons (urban, suburban, etc)
and then make predictions about cities you haven't even set up shop in, yet,
based on similar cities.

Hexagons are also the most efficient way to pack spheres, and can best
approximate a circular radius with a discrete grid, so they're also useful for
doing fast approximations of field-effect calculations (like electromagnetic
fields from discrete particles). You could count drivers as a negative charge
and riders as a positive charge, for instance, and use EM equations to
determine the biggest imbalances in supply and demand distribution, and this
will let you do it very quickly with little error.

The hexagons themselves can get down to a granularity below GPS resolution
error, so you could, without any effective losses, pack 3 doubles (lat, lng,
error) into a single 64-bit integer (H3 index of an appropriate size based on
the error) and reduce bandwidth usage on location data.

The H3 index for any particular resolution is ordered in something similar to
a Gosper curve[1] so if you really need just a rough approximation of data to
query from an area, you actually only need to store the two indexes at the
beginning and end of the gosper-like curve you're interested in.

This C library wasn't meant to be used directly by most developers and that's
why it has a few rough edges (like not centering the output around the
meridian (-180, 180) instead of the current (0, 360) output). I can't wait
until the bindings come out, too, probably with the blog post. :)

[1]:
[https://en.wikipedia.org/wiki/Gosper_curve](https://en.wikipedia.org/wiki/Gosper_curve)

~~~
amckenna
This was a very helpful explanation, thank you! Does using hexagons represent
the start of a paradigm shift for mapping applications or is it something that
has been used for a while? This is the first I have heard of it, but based on
your explanation it makes a lot of sense.

~~~
ISV_Damocles
There have been many uses of hex grids and maps for a while, such as
Civilization V, and this awesome hex grid resource from a gaming company:
[https://www.redblobgames.com/grids/hexagons/](https://www.redblobgames.com/grids/hexagons/)

Others have pointed out various indexing systems that NASA uses that support
hexagons, as well. H3's advantages over the others is, in my opinion, that we
tried to marry as much of the awesome S2 library into a hexagonal grid (short
64-bit addresses for all hexagons at all resolutions, a parent-child tree with
no shared parents, minimized area distortion, and a pretty simple API with
some built-in utilities, like geofence polyfill, hexagon compaction, GeoJSON
output, etc), where the hexagonal properties give you the other advantages I
outlined over S2.

To be perfectly fair, there are some things that S2 will still do better than
H3, most notably that the area coverage of a parent perfectly matches all of
its children, where that's not the case with H3, though we minimized it as
well as I think is possible.

Kevin Sahr (whom others have cited in here) worked with us on this library and
came up with the parent-child orientation and scaling, and implemented the
original version of the code.

------
Guidii
OGC has a spec for Discrete Global Grids at
[http://docs.opengeospatial.org/as/15-104r5/15-104r5.html](http://docs.opengeospatial.org/as/15-104r5/15-104r5.html)

It has a good overview of the implementation details, and pictures!

------
adrianratnapala
Is every face a hexagon?

I thought to cover a sphere you had to throw in at least a few things that
weren't hexagons. Euler and all that.

~~~
rockinghigh
There are pentagons:

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

From:
[https://github.com/uber/h3/blob/9df3940473e2f0446cf38e22443c...](https://github.com/uber/h3/blob/9df3940473e2f0446cf38e22443c77c6b3935382/docs/doxyfiles/overview.md)

------
tejtm
See Buckminster Fuller's Dymaxion map also
[0]([https://en.wikipedia.org/wiki/Dymaxion_map](https://en.wikipedia.org/wiki/Dymaxion_map))

------
awshepard
Can anyone compare/contrast this with geohex.org? I've used geohex in a past
life, just curious what, if anything, H3 might offer over it.

~~~
dvanduzer
I have never heard of this library before, which is surprising, because I've
been looking hard for such a hexagonal privacy-fencing system for a long time!

I can't find anything that explains how the partitioning in geohex works, but
the Uber system makes it clear that they are using Dr. Sahr's partitioning
scheme:
[https://github.com/uber/h3/blob/master/docs/doxyfiles/h3inde...](https://github.com/uber/h3/blob/master/docs/doxyfiles/h3indexing.md)

------
espeed
Also see NASA JPL's HEALPix v3...

"A multi-resolution HEALPix data structure for spherically mapped point data"
(2017)
[http://www.heliyon.com/article/e00332](http://www.heliyon.com/article/e00332)

------
cmaggard
So MGRS[0] with hexagons? Pretty interesting.

[0]
[https://en.wikipedia.org/wiki/Military_Grid_Reference_System](https://en.wikipedia.org/wiki/Military_Grid_Reference_System)

~~~
acemarke
Seems more like Hierarchical Triangular Meshing with hexagons. I had to use
that for a project a few years back.

[http://www.skyserver.org/htm/](http://www.skyserver.org/htm/)

[https://arxiv.org/ftp/cs/papers/0701/0701164.pdf](https://arxiv.org/ftp/cs/papers/0701/0701164.pdf)

------
copperx
Hexagonal? Is this inspired in any way by Borges's Library of Babel?

