uber-apih3

h3Line function throws LineUndefinedException


I want to calculate index of the h3 cells between (-39.08, -57.01) and (-38.05, -58.16) but it throws LineUndefinedException.

In the documentation it says

This function may fail to find the line between two indexes, for example if they are very far apart. It may also fail when finding distances for indexes on opposite sides of a pentagon.

I think that it throws the exception because of the latter case. Is there workaround to calculate those cell indexes?

Code:

public static void main(String[] args) {
  try {
    H3Core h3Core = H3Core.newInstance();
    long p1 = h3Core.geoToH3(-39.08, -57.01, 8);
    long p2 = h3Core.geoToH3(-38.05, -58.16, 8);
    List<Long> line = h3Core.h3Line(p1, p2);
  } catch (Exception e) {
    e.printStackTrace();
  }
}

Exception:

com.uber.h3core.exceptions.LineUndefinedException: Could not compute line size between cells
at com.uber.h3core.H3Core.h3Line(H3Core.java:630)

Solution

  • You have hit one of the edge cases H3 does not handle (yet), points on opposite sides of a pentagon:

    points and icosahedron edges

    The image above shows the edges of the icosahedron the H3 grid is based on. Pentagons are located at the vertexes of the icosahedron, and your points cross these edges in a way that makes it harder to compute the grid path.

    The correct workaround here, which we eventually intend to implement in the library, is to find the intersection points between the great arc linking the two points and the icosahedron edges. To do this, you'd need the icosahedron geometry, which is available in the H3 lib but slightly hard to extract. There's a version here which has a bunch of unnecessary intermediate points in each edge (to facilitate rendering great arcs correctly on web maps), but which should work. The basic algorithm is:

    There is likely an easier option here, which is to do the same thing but instead of calculating indexes just sample along the great arc. In this particular case, it looks like you probably could just take the center of the great arc and calculate h3Line twice, but in some cases you'd need more samples.