如何在世界地图上可靠地生成六边形网格
How to reliably generate hexagonal grid over a world map
目标
我正在尝试构建一个应用程序,将整个世界地图分成大量的六边形。这些六边形一旦生成,将始终覆盖地图上的相同区域。然后,给定某些地理坐标,如果这些坐标位于其边界内,则会在地图上呈现一个六边形。这些六边形需要非常小,每边大约。 50m - 这是主要问题。
第一次尝试
我的第一个想法是预先生成六边形网格,其中每个六边形都是不可见的,在确定坐标是否在边界内后,只需更改六边形的样式即可。如果六边形边长真的很大(数百公里),这会起作用。然而,在我的例子中,当试图绘制非常小的六边形时,应用程序将 运行 内存不足,即使是地图的一小部分。
// Attempting to cover the whole map in small hexagons
turf.hexGrid([-179.99, -89.99, 179.99, 89.99], 0.2);
第一次尝试,但有点曲折
我的第二个想法是使用 hexGrid()
的 mask
选项,这样我仍然会生成六边形坐标不变的六边形网格,但只会尝试在小地图中渲染六边形区域(例如地图上可见的区域)。这似乎也不可能,因为即使生成这样的网格(而不是在地图上渲染它)也证明会消耗太多资源。
// Attempting to cover the whole map in small hexagons only within a given area (mask)
turf.hexGrid([-179.99, -89.90, 178.99, 88.90], 30, {
mask: polygon([[[20, 60], [21, 60], [22, 62], [22, 63], [20, 60]]]),
});
然而,这会产生非常倾斜的六边形,这让我相信尝试为整个世界生成六边形网格通常是一个坏主意。
乐观计算
我最后一次尝试是在地图的左上角生成一个六边形,并使用它的坐标来计算第一个六边形和任何给定坐标之间可以容纳多少个六边形。
这些计算几乎有效,但由于四舍五入或者我计算距离的方式(手动)的错误,定位偏离的数字越远坐标来自第一个六边形。
现实生活中的例子
最接近我想要实现的例子是名为 "Run an Empire" 的 运行ning 游戏。那里的六边形网格似乎是按需加载的,并且只围绕着一个所在的区域。从外观上看,该网格没有任何间隙会阻止六边形完美连接。
作为一个额外的兴趣点,在世界地图上绘制六边形会使我们向北倾斜。这在上面提到的游戏中似乎没有发生(下面的屏幕截图)。这是否意味着六边形大小是硬编码的,也许它们是在不同的地图投影上绘制的,其中不会发生倾斜?
主要问题
给定地理坐标,如 GPS 定位,如何可靠地生成一个六边形网格,以便在根据另一组坐标生成另一个六边形网格时,这两个网格可以完美重叠?我愿意使用任何工具来解决这个问题,不一定是 Turf 或 Mapbox。
我建议生成一个包含所有六边形的矢量图层,并使用地理数据库动态加载它们执行地理查询。
放置pin的点的交点,会return其下的六边形,如果使用缓冲区,还可以在其周围添加更多的六边形。
WGS84 的边界是 -180.0000、-90.0000、180.0000、90.0000(我知道这很明显)
来源:https://spatialreference.org/ref/epsg/wgs-84/
这意味着您需要从那里开始,估算您 need/want 要创建的六边形的数量。
根据https://planetcalc.com/7721/,以米为单位的炉床半径为6378137。
假设你想要一个由 6 个等边三角形组成的六边形,这意味着为了得到一个边长大约 50 米的六边形,它的宽度将是 100 米(假设平面的边是水平的)。
现在我们可以说我们在赤道需要大约 63781 个六边形,让我们简化为 63800,360/63800 = 0.00564...所以我建议从赤道点偏移 0.0055 度开始。
需要强调的一件事是,WGS84 是大地水准面而不是球形(就像我们的星球),因此最终表示可能会被拉伸一点。
更新:要自动生成网格,看起来您也可以使用 Quantum GIS,感谢 Grass
编辑:
https://github.com/rldhont/Quantum-GIS/blob/master/python/plugins/processing/algs/grass7/description/v.mkgrid.txt
https://grass.osgeo.org/grass76/manuals/v.mkgrid.html
对于更高版本:
https://github.com/OSGeo/grass/blob/releasebranch_8_0/vector/v.mkgrid/v.mkgrid.html
目标
我正在尝试构建一个应用程序,将整个世界地图分成大量的六边形。这些六边形一旦生成,将始终覆盖地图上的相同区域。然后,给定某些地理坐标,如果这些坐标位于其边界内,则会在地图上呈现一个六边形。这些六边形需要非常小,每边大约。 50m - 这是主要问题。
第一次尝试
我的第一个想法是预先生成六边形网格,其中每个六边形都是不可见的,在确定坐标是否在边界内后,只需更改六边形的样式即可。如果六边形边长真的很大(数百公里),这会起作用。然而,在我的例子中,当试图绘制非常小的六边形时,应用程序将 运行 内存不足,即使是地图的一小部分。
// Attempting to cover the whole map in small hexagons
turf.hexGrid([-179.99, -89.99, 179.99, 89.99], 0.2);
第一次尝试,但有点曲折
我的第二个想法是使用 hexGrid()
的 mask
选项,这样我仍然会生成六边形坐标不变的六边形网格,但只会尝试在小地图中渲染六边形区域(例如地图上可见的区域)。这似乎也不可能,因为即使生成这样的网格(而不是在地图上渲染它)也证明会消耗太多资源。
// Attempting to cover the whole map in small hexagons only within a given area (mask)
turf.hexGrid([-179.99, -89.90, 178.99, 88.90], 30, {
mask: polygon([[[20, 60], [21, 60], [22, 62], [22, 63], [20, 60]]]),
});
然而,这会产生非常倾斜的六边形,这让我相信尝试为整个世界生成六边形网格通常是一个坏主意。
乐观计算
我最后一次尝试是在地图的左上角生成一个六边形,并使用它的坐标来计算第一个六边形和任何给定坐标之间可以容纳多少个六边形。
这些计算几乎有效,但由于四舍五入或者我计算距离的方式(手动)的错误,定位偏离的数字越远坐标来自第一个六边形。
现实生活中的例子 最接近我想要实现的例子是名为 "Run an Empire" 的 运行ning 游戏。那里的六边形网格似乎是按需加载的,并且只围绕着一个所在的区域。从外观上看,该网格没有任何间隙会阻止六边形完美连接。
作为一个额外的兴趣点,在世界地图上绘制六边形会使我们向北倾斜。这在上面提到的游戏中似乎没有发生(下面的屏幕截图)。这是否意味着六边形大小是硬编码的,也许它们是在不同的地图投影上绘制的,其中不会发生倾斜?
主要问题
给定地理坐标,如 GPS 定位,如何可靠地生成一个六边形网格,以便在根据另一组坐标生成另一个六边形网格时,这两个网格可以完美重叠?我愿意使用任何工具来解决这个问题,不一定是 Turf 或 Mapbox。
我建议生成一个包含所有六边形的矢量图层,并使用地理数据库动态加载它们执行地理查询。 放置pin的点的交点,会return其下的六边形,如果使用缓冲区,还可以在其周围添加更多的六边形。
WGS84 的边界是 -180.0000、-90.0000、180.0000、90.0000(我知道这很明显) 来源:https://spatialreference.org/ref/epsg/wgs-84/ 这意味着您需要从那里开始,估算您 need/want 要创建的六边形的数量。 根据https://planetcalc.com/7721/,以米为单位的炉床半径为6378137。 假设你想要一个由 6 个等边三角形组成的六边形,这意味着为了得到一个边长大约 50 米的六边形,它的宽度将是 100 米(假设平面的边是水平的)。
现在我们可以说我们在赤道需要大约 63781 个六边形,让我们简化为 63800,360/63800 = 0.00564...所以我建议从赤道点偏移 0.0055 度开始。
需要强调的一件事是,WGS84 是大地水准面而不是球形(就像我们的星球),因此最终表示可能会被拉伸一点。
更新:要自动生成网格,看起来您也可以使用 Quantum GIS,感谢 Grass
编辑:
https://github.com/rldhont/Quantum-GIS/blob/master/python/plugins/processing/algs/grass7/description/v.mkgrid.txt
https://grass.osgeo.org/grass76/manuals/v.mkgrid.html
对于更高版本: https://github.com/OSGeo/grass/blob/releasebranch_8_0/vector/v.mkgrid/v.mkgrid.html