javascript - 在 map 上创建非重叠 POI 图标的算法

标签 javascript algorithm gis data-visualization

我想在代表兴趣点 (POI) 的 map 上创建各种大小的图标。当有足够的空间时,应使用较大的图标。在更拥挤的区域,使用较小的图标。

例如: enter image description here

这是来自 Sygic Travel .密度保持在各种缩放级别。我假设对突出的 POI 进行了某种加权,以使它们在各种缩放级别下显得更大。

到目前为止我探索的内容包括:

  • 按网格位置分箱。该方法将 map 划分为网格正方形,并统计每个正方形上出现了多少个 POI。如果一个方 block 上只有一个 POI,它可以显示为最大的图标。如果出现两个或更多,它们应该更小。此方法使用 POI 的中心,因此当两个 POI 出现在相邻的 Angular 上时,它们仍然重叠。
  • 将图标分开。当 POI 之间的距离小于某个阈值时,此方法只是将它们相互推开。问题是它们可能会被插入其他重叠的 POI。它也不太准确,因为 map 上的 POI 位置没有保留。

现在我正在考虑探索某种类似于物理引擎中的碰撞检测。它可以防止重叠,但我不确定它如何实现各种大小图标的要求。另一种技术可能是检测网格空间重叠的多 channel 合并。

这里有我缺少的算法吗?或者是否有任何现有的解决方案可以引用?

最佳答案

算法很简单:

map 区域由通常使用纬度和经度的一些边界定义(例如 south:51.482238, west: -0.18462181, north: 51.529571733, east: -0.058450698)还有你想要的点绘制有一些纬度和经度坐标,在边界内。

您可以将 map 视为像素 Canvas ,例如 1200x800 像素(尺寸通常由浏览器中 map 的尺寸​​定义)

选择 map 的一个 Angular 作为起始坐标[0,0](例如[南,西])并将点的纬度、经度坐标转换为 Canvas 像素坐标。

然后我们只需按优先级对点进行排序,然后将它们一个接一个地放在 map 上。我们知道要绘制的标记的大小以及已经绘制的标记,因此在像素 Canvas 上很容易检测到可能的碰撞。检测到的碰撞方式比地点由具有更高优先级的点占据。如果该点不适合作为巨大标记在 map 上,我们会尝试将其放置为较小的标记,依此类推...

关于javascript - 在 map 上创建非重叠 POI 图标的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43106922/

相关文章:

javascript - 如何在 jquery mobile 中单击按钮时关闭应用程序

javascript - Jquery 中的关联数组

algorithm - 有什么方法可以使用单个循环比较数组中的每个元素吗?

postgresql - 绕其局部轴旋转几何体

javascript - 我的 .done() Mocha 测试出了什么问题?

javascript - 数据表: brake with url

c++ - 传递一个对象及其方法之一作为参数

c++ - 合并来自 std::set 的相邻条目

r-将sf::st_within的输出转换为矢量

R sf - 如何平移多边形?