Android的图形页面:合并重叠的标记到一个新的标志标记、图形、标志、页面

2023-09-10 23:26:26 作者:公主身,女仆命

所以我有很多标记,其中大部分都集中在英里宽集群的图形页面。当放大的标记重叠,似乎仅是一个。我想实现的是在一定的缩放级别取代重叠的标记有一组标记,将显示标记的密度和的onClick将放大到里面显示所有标志。我知道我能做到这一点用蛮力距离测量,但必须有一个更有效的方式。任何人对我如何能做到这一点的任何解决方案或智能算法?

So I have a MapView with a lot of markers, most of which are concentrated in mile wide clusters. When zoomed the markers overlap and appear to only be one. What I want to achieve is at a certain zoom level replace the overlapping markers with a group marker that will display the density of markers and onClick will zoom to display all markers inside. I know I can do this with brute force distance measurements but there must be a more efficient way. Anyone have any solution or smart algorithms on how I can achieve this?

推荐答案

嗯......假设标记不分组,分层或任何东西:为什么 - 显示它们之前 - 你不创造一定密度的网格,只是斌标记到网格的单元格?

Um... assuming the markers are not grouped, layered or anything: why - before showing them - don't you create a grid of certain density and simply bin the markers into the cells of your grid?

如果你再算上那几个标记属于同一箱(单元格) - 你可以将它们。如果你需要稍微聪明的分组,你也可以检查相邻小区。

If you then count that several markers fall into the same bin (grid cell) - you can group them. If you need slightly more clever grouping, you might also check the neighbouring cells.

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

Maybe it sounds a bit primitive but:

在无N ^ 2算法 有关输入的顺序没有假设 要额外地显示无需处理标记,其不打算

在code网格:

请注意 - 我从C ++世界(来到这里,通过[算法]标签),所以我会坚持到伪C ++。我不知道的MapView的API。不过,我会感到惊讶,如果这不能被有效地翻译成任何语言/库,你正在使用。

Note - I come from the C++ world (got here through [algorithm] tag) so I'll stick to the pseudo-C++. I do not know the API of the mapview. But I would be surprised if this couldn't be efficiently translated into whatever language/library you are using.

输入: - 标记列表 - 观察窗的世界坐标(世界上,我们正在寻找的部分)的矩形

Input: - list of markers - the rectangle viewing window in world coordinates (section of world we are currently looking at)

在最简单的形式,它看起来是这样的:

In the simplest form, it would look something like this:

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

}

可能出现的问题是,不希望的网格分割,可能会出现一些内群集基,形成两个GroupMarkers。为了应对这一点,你可能要考虑的不只是一个网格单元,也是其邻国的\图一节中,以及 - 如果分组 - 马克相邻小区的走访

The problem that might appear is that an unwanted grid split may appear within some clustered group, forming two GroupMarkers. To counter that, you may want to consider not just one grid cell, but also its neighbors in the "\drawing" section, and - if grouped - mark neighboring cells as visited.