小编典典

Android Mapview:将重叠的标记合并为新标记

algorithm

因此,我有一个包含许多标记的MapView,其中大多数标记集中在几英里宽的簇中。缩放时,标记重叠,并且看起来只有一个。我要实现的是在某个缩放级别上,将重叠的标记替换为一个组标记,该组标记将显示标记的密度,而onClick将缩放以显示内部的所有标记。我知道我可以用蛮力距离测量来做到这一点,但是必须有一种更有效的方法。任何人都对我如何实现此目标有任何解决方案或智能算法?


阅读 238

收藏
2020-07-28

共1个答案

小编典典

嗯…假设标记未分组,不分层或没有其他内容:为什么-在显示标记之前-您不创建特定密度的网格并将标记简单地装到网格的单元格中?

如果您随后算出几个标记落入同一容器(网格单元)中,则可以将它们分组。如果您需要更巧妙的分组,还可以检查相邻的单元格。

也许听起来有点原始,但:

  • 没有n ^ 2个算法
  • 没有关于输入顺序的假设
  • 无需额外处理不会显示的标记

网格的代码:

注意-我来自C 世界(通过[algorithm]标记在此处获得),因此我将坚持使用伪C
。我不知道mapview的API。但是,如果无法将其有效地翻译为您使用的任何语言/库,我会感到惊讶。

输入:-标记列表-世界坐标中的矩形查看窗口(当前正在查看的世界部分)

最简单的形式如下所示:

void draw(MarkerList mlist, View v) {

    //binning:

    list<Marker> grid[densityX][densityY]; //2D array with some configurable, fixed density
    foreach(Marker m in mlist) {
        if (m.within(v)) {
            int2 binIdx;
            binIdx.x=floor(densityX*(m.coord.x-v.x1)/(v.x2-v.x1));
            binIdx.y=floor(densityY*(m.coord.y-v.y1)/(v.y2-v.y1));
            grid[binIdx.x][binIdx.y].push(m); //just push the reference
        }

    //drawing:

    for (int i=0; i<densityX; ++i)
    for (int j=0; j<densityY; ++j) {
        if (grid[i][j].size()>N) {
            GroupMarker g;
            g.add(grid[i][j]); //process the list of markers belonging to this cell
            g.draw();
        } else {
            foreach (Marker m in grid[i][j])
                m.draw()
        }
    }

}

可能出现的问题是在某些群集组中可能会出现不必要的网格拆分,从而形成两个GroupMarker。为了解决这个问题,您可能不仅要考虑一个网格单元,而且还要考虑“
\绘图”部分中的相邻网格,并且-如果进行分组,则将相邻单元标记为已访问。

2020-07-28