Uber h3 可以用六边形网格覆盖整个地球吗?

问题描述

Uber 发布了 h3,这是一个有效处理地理空间文件中大数据的框架。使用h3,我尝试获取如图所示的六边形网格位置。 (https://eng.uber.com/h3/)

我从下面的代码中得到了六边形网格的位置。然后我将它绘制在二维地图上,看它是否覆盖了整个地球。但是,我在边界(-90°、90°、-180°、180°)上没有得到有效的六边形。它似乎并没有覆盖整个地球。 (hexagonal grid)

    from h3 import h3
    import folium
    
    # polyfill a Geo Json with hexagons
    geoJson1 = {'type': 'polygon','coordinates': [[[90,-180],[90,0],[-90,-180]]]}
    geoJson2 = {'type': 'polygon',180],0]]]}
    hexagons = list(h3.polyfill(geoJson1,1)) + list(h3.polyfill(geoJson2,1))
    # Plot hexagons
    polylines = []
    for hex in hexagons:
        polygons = h3.h3_set_to_multi_polygon([hex],geo_json=False)
        outlines = [loop for polygon in polygons for loop in polygon]
        polyline = [outline + [outline[0]] for outline in outlines][0]
        polylines.append(polyline)
    base = folium.Map([0,zoom_start=2,tiles='cartodbpositron')
    for polyline in polylines:
        m = folium.polyLine(locations=polyline,weight=1,color='black')
        base.add_child(m)
    m.save('test.html')

我想要覆盖整个地球的六边形位置。在这种情况下,我使用h3接近,但我不在乎只要我能得到位置。

解决方法

是的,H3 覆盖了整个地球。您在该图像中看到的是渲染伪影 - 根据您在平面投影中渲染全局网格的方式,您可能会在极点或反子午线处获得类似的伪影。见例如this map 用于在反子午线正确渲染的 H3 投影,尽管它在极点周围仍然存在一些问题。

,

当你填满整个地球时,你会得到跨越反子午线的 H3 多边形。这些将在东半球(经度 > 0)和西半球(经度 找到这样的多边形

for line in polylines:
  if any(p[1] > 0 for p in line) and any(p[1] < 0 for p in line):
    print(line)

考虑例如此列表的一个优势:

(-65.7243888731199,-176.62192487031285),(-66.42506103952591,175.12130159942038)

它跨度从经度 -176 到 173。H3 假设顶点与测地线(最短)路径相连,即在这种情况下,一条穿过反子午线的短路径。因此,多边形应该同时出现在地图的最左侧和最右侧。但是当你把它交给像 Folium 这样的平面地图绘制工具时,它对测地线边缘或反子午线一无所知,而是在整个地球上绘制一条长直线(地图上的最短线,而不是地球上最短的线),穿过初级子午线。这是这里所有长长的近水平线的来源。

有几种解决方案,具体取决于您想要什么。常见的选择是固定每个穿过反子午线的多边形,在左侧或右侧绘制它。假设您将所有这些多边形向右移动 - 然后向所有负经度添加 360,将 -176 替换为 184。您将得到一个小多边形,Folium 应该能够“正确”绘制它,尽管它会伸出 180 的右侧子午线(虽然我没有使用 Folium 的经验,但这是典型的行为)。