h3Line 函数抛出 LineUndefinedException

h3Line function throws LineUndefinedException

我想计算 (-39.08, -57.01) 和 (-38.05, -58.16) 之间的 h3 单元格的索引,但它抛出 LineUndefinedException。

文档中说

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.

我认为它抛出异常是因为后一种情况。是否有计算这些单元格索引的解决方法?

代码:

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();
  }
}

异常:

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

您遇到了 H3 尚未处理的边缘情况之一,五边形相对两侧的点:

上图显示了 H3 网格所基于的二十面体的边缘。五边形位于二十面体的顶点,您的点以某种方式穿过这些边,这使得计算网格路径变得更加困难。

我们最终打算在库中实现的正确解决方法是找到连接两点的大圆弧与二十面体边之间的交点。为此,您需要二十面体几何图形,它在 H3 库中可用,但稍微难以提取。有一个版本 here 在每条边上都有一堆不必要的中间点(以促进在 web 地图上正确渲染大弧线),但它应该可以工作。基本算法是:

  • 沿着 A 点和 B 点之间的大圆弧找到所有交点。
  • 对于每个点,找到 H3 索引。
  • 找到每个段之间的 h3Line,例如h3Line(cellA, cellIntersection1)h3Line(cellIntersection1, cellIntersection2),依此类推。
  • 合并行,删除重复的索引。

这里可能有一个更简单的选择,即做同样的事情,但不是计算索引,而是沿着大弧线采样。在这种特殊情况下,看起来您可能只需取大弧的中心并计算 h3Line 两次,但在某些情况下您需要更多样本。