地图上大量标记的问题

发布于 2024-10-12 11:33:54 字数 2905 浏览 3 评论 0原文

我正在开发一款 iPhone 上已经存在的 Android 应用程序。

在应用程序中,有一个 Map 活动,它有(我数过)大约 800 个标记,分为四组,并用四种不同颜色的可绘制标记进行标记。每个组都可以打开或关闭。有关我在列表中的标记的信息。我为每个组创建一个 mapOverlay,然后将该叠加层附加到地图上。我坚信我的编码部分做得正确。但无论如何我都会附上我的代码...

问题是,我的 Nexus One 无法处理带有所有这些标记的地图。仅绘制 500 个标记就需要大约 15 秒。然后当全部绘制完毕后,地图不太平滑。缩放和导航有点困难。可以做到,但是经验很差,我想看看是否可以在那里做点什么。我知道如果我避免 String >双重转换,我可以节省一些时间,但我怀疑这是否重要。

iPhone 显示所有这些标记似乎没有问题。显示所有内容大约需要 1-2 秒,并且缩放和平移也不错。减慢是明显的,但仍然可以接受。我个人认为绘制所有这些标记是没有好处的,但应用程序是由其他人设计的,我不应该进行任何重大更改。

我不知道在这里做什么。看来我必须想出不同的功能,也许使用 GPS 位置(如果已知),并仅在某个半径内绘制标记,或者,如果位置未知,则使用屏幕(地图)中心并在其周围绘制标记。如果我做出这些改变,我必须向我的老板做出合理的解释。

如果有人有任何 idas,我将不胜感激。

和代码:

    List<Overlay> mapOverlays = mapView.getOverlays();
    Drawable drawable = this.getResources().getDrawable(R.drawable.pin_blue);
    drawable = this.getResources().getDrawable(R.drawable.pin_blue);
    ArrList = appState.GetSleepArrList();
    ItemizedOverlay itemizedoverlay = new ItemizedOverlay(drawable, this); 
    ...
    ...
       for (int m = 0; m < ArrList.size(); m++) {
            tName = ArrList.get(m).get("name").toString();
            tId = ArrList.get(m).get("id").toString();
            tLat = ArrList.get(m).get("lat").toString();;
            tLng = ArrList.get(m).get("lng").toString();;
            try {
                lat = Double.parseDouble(tLat);
                lng = Double.parseDouble(tLng);
                p1 = new GeoPoint(
                        (int) (lat * 1E6), 
                        (int) (lng * 1E6));
                OverlayItem overlayitem = new OverlayItem(p1, tName, tId);
                itemizedoverlay.addOverlay(overlayitem);
            } catch (NumberFormatException e) {
                Log.d(TAG, "NumberFormatException" + e);    
            }
        }
        mapOverlays.add(itemizedoverlay);
        mapView.postInvalidate();

................................

public class ItemizedOverlay extends ItemizedOverlay<OverlayItem>
{
    private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
    private Context mContext;
    public HelloItemizedOverlay(Drawable defaultMarker, Context context)
    {
        super(boundCenterBottom(defaultMarker));
        mContext = context;
    }

    public void addOverlay(OverlayItem overlay)
    {
        mOverlays.add(overlay);
        populate();
    }
    @Override
    protected OverlayItem createItem(int i)
    {
        return mOverlays.get(i);
    }
    @Override
    public int size()
    {
        return mOverlays.size();
    }
    @Override
    protected boolean onTap(int index)
    {
        final OverlayItem item = mOverlays.get(index);
                    ... EACH MARKER WILL HAVE ONCLICK EVENT THAT WILL PRODUCE CLICABLE 
                    ... BALOON WITH MARKER'S NAME.          
        return true;
    }       
}    

I am working on an Android app that already exists on iPhone.

In the app, there is a Map activity that has (I counted) around 800 markers in four groups marked by drawable in four different colors. Each group can be turned on or off. Information about markers I have inside List. I create a mapOverlay for each group, then I attach that overlay to the map. I strongly believe that coding part I did properly. But I will attach my code anyway...

The thing is, my Nexus One can't handle map with all those markers. It takes around 15 seconds just to draw 500 markers. Then when all drawn, map is not quite smooth. It is sort of hard to zoom and navigate around. It can be done, but experience is bad and I would like to see if something can be done there. I know if I avoid String > Double conversion, I could save some time, but I doubt that would be significant.

iPhone seems doesn't have problems showing all these markers. It takes roughly about 1-2 seconds to show all of them and zooming and panning is not that bad. Slow down is noticeable but still acceptable. I personally think it is no good to draw all those markers, but app is designed by somebody else and I am not supposed to make any drastic changes.

I am not sure what to do here. It seems I will have to come up with different functionality, maybe use GPS location, if known, and draw only markers within some radius, or, if location not known, use center of the screen(map) and draw markers around that. I will have to have reasonable explanation for my bosses in case I make these changes.

I appreciate if anybody has any idas.

And the code:

    List<Overlay> mapOverlays = mapView.getOverlays();
    Drawable drawable = this.getResources().getDrawable(R.drawable.pin_blue);
    drawable = this.getResources().getDrawable(R.drawable.pin_blue);
    ArrList = appState.GetSleepArrList();
    ItemizedOverlay itemizedoverlay = new ItemizedOverlay(drawable, this); 
    ...
    ...
       for (int m = 0; m < ArrList.size(); m++) {
            tName = ArrList.get(m).get("name").toString();
            tId = ArrList.get(m).get("id").toString();
            tLat = ArrList.get(m).get("lat").toString();;
            tLng = ArrList.get(m).get("lng").toString();;
            try {
                lat = Double.parseDouble(tLat);
                lng = Double.parseDouble(tLng);
                p1 = new GeoPoint(
                        (int) (lat * 1E6), 
                        (int) (lng * 1E6));
                OverlayItem overlayitem = new OverlayItem(p1, tName, tId);
                itemizedoverlay.addOverlay(overlayitem);
            } catch (NumberFormatException e) {
                Log.d(TAG, "NumberFormatException" + e);    
            }
        }
        mapOverlays.add(itemizedoverlay);
        mapView.postInvalidate();

................................

public class ItemizedOverlay extends ItemizedOverlay<OverlayItem>
{
    private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
    private Context mContext;
    public HelloItemizedOverlay(Drawable defaultMarker, Context context)
    {
        super(boundCenterBottom(defaultMarker));
        mContext = context;
    }

    public void addOverlay(OverlayItem overlay)
    {
        mOverlays.add(overlay);
        populate();
    }
    @Override
    protected OverlayItem createItem(int i)
    {
        return mOverlays.get(i);
    }
    @Override
    public int size()
    {
        return mOverlays.size();
    }
    @Override
    protected boolean onTap(int index)
    {
        final OverlayItem item = mOverlays.get(index);
                    ... EACH MARKER WILL HAVE ONCLICK EVENT THAT WILL PRODUCE CLICABLE 
                    ... BALOON WITH MARKER'S NAME.          
        return true;
    }       
}    

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一世旳自豪 2024-10-19 11:33:54

出色地。事实证明,我每次添加标记后都会调用 populate() 。我从 addOverlay() 方法中取出了 populate() ,并在循环完成后调用它。所有标记现在几乎立即显示。现在唯一的问题是地图在较低缩放时反应非常迟钝(一次显示很多标记)。我没有看到这个问题的解决方案,除非我弄清楚如何在地图缩小时减少地图上的标记数量...考虑以某种方式对它们进行分组...目前正在研究这个...

Well. It turned out I call populate() every time after adding an marker. I took populate() out of addOverlay() method and I am calling it after loop finishes. All markers now show almost instantaneously. The only problem now is that the map is very unresponsive when at lower zoom (showing a lot of markers at once). I don't see solution for this unless I figure out how to decrease number of markers on the map when map is zoomed out... thinking to group them somehow.... currently working on this...

深爱不及久伴 2024-10-19 11:33:54

您可以通过两种方法来简化路线。

1)如果你得到了所有点的标题。您可以保留航向容差,假设点 A 和 B 之间的航向差异为 0.5 只需从 A 到 B 画一条线并忽略之间的点即可。

2)如果你没有标题。制作一个三角形,如图所示。如果 h 位于您的限制之间,请跳过中间的点并从 A 到 B 画一条线
在此处输入图像描述

您还可以使用其他一些路线简化算法


另请参阅:

路线简化 - Douglas Puecker 算法

There are two ways you can do this route simplification.

1) If you got the heading of all the points. You can keep a heading tolerance , say if the heading diffference between point A and B is 0.5 Just draw a line from A to B and ignore the points between.

2) If you dont have a heading. Make a triangle as shown in the fig. If h lies in between your limits, skip the points in between and draw a line from A to B
enter image description here

You can also use some other route simplification algorithms.


See also :

Route simplification - Douglas Puecker Algorithm

‖放下 2024-10-19 11:33:54

我在地图上加载多个标记时遇到了同样的问题,但我在加载标记和显示地图方面设置了一些延迟。首先显示地图,经过一些延迟后将加载所有标记。在某种程度上,这会加载得更快。

I am having same problem in multiple marker loading on map but I have put some delay in loading marker and display map.first display map and after some delay will load all marker. that will load faster up to some extent.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文