【问题标题】:Memory efficient google map drawing on AndroidAndroid上的内存高效谷歌地图绘制
【发布时间】:2013-10-15 21:56:35
【问题描述】:

我正在尝试在带有支持库的 Android 上使用 APIv2 在 GoogleMap 上绘制几个点。 我有几个 SPOT 对象数组,包含所述点的纬度和经度。 每次想在地图上画点,我都会调用下面的方法:

public void drawSpotsFromArray(ArrayList<Spot> pSpots, int pZIndex) {

    for (int i=0; i<pSpots.size(); i++) {
        Spot lSpot = pSpots.get(i);

        double lDiameter = 10;

        CircleOptions lCircleOptions = new CircleOptions();
        lCircleOptions.center(new LatLng(lSpot.mLatitude, lSpot.mLongitude));
        lCircleOptions.radius(lDiameter);
        lCircleOptions.strokeColor(Color.BLACK);
        lCircleOptions.strokeWidth(5);
        lCircleOptions.fillColor(Color.WHITE);
        lCircleOptions.zIndex(pZIndex);

        mGoogleMap.addCircle(lCircleOptions);
    }
}

它只绘制数组中包含的每个点。
现在,我的问题是这些数组非常大,导致内存过载。我画了大约 500 个圆圈(5 个 100 个圆圈的数组),所以应用程序变得非常慢。

有没有办法,而不是将每个圆圈绘制为单个叠加层,而是将每个点表绘制为单个叠加层?例如,将一个数组的 100 个圆绘制为一个叠加层,结果是 5 个叠加层(5 个数组)而不是 500 个叠加层(数组的圆)。

如果是这样,它会更节省内存吗?
如果不是,在不消耗所有设备内存的情况下绘制这些圆圈的最佳做法是什么?

每次调用此方法时,我都会给出更高的 zIndex。我不知道这是否会以任何方式影响内存。 感谢您的帮助。

编辑:

好的,下面答案中的算法帮助我解决了我的问题,以及这个线程来绘制带有可绘制对象的地面覆盖: Ground Overlay

感谢您的帮助!

【问题讨论】:

    标签: android performance google-maps memory overlay


    【解决方案1】:

    您可以尝试稍微不同的方法。仅当地图的该部分可见时才在地图上绘制点。每次相机位置移动时,您都需要再次调用它。

    试试这样的:

        public void drawSpotsFromArray(ArrayList<Spot> pSpots, int pZIndex) {
    
        LatLngBounds bounds = mGoogleMap.getProjection().getVisibleRegion().latLngBounds;
    
        for (int i = 0; i < pSpots.size(); i++) {
            Spot lSpot = pSpots.get(i);
    
            if (bounds.contains(new LatLng(lSpot.Latitude, lSpot.Longitude))) {
                double lDiameter = 10;
    
                CircleOptions lCircleOptions = new CircleOptions();
                lCircleOptions.center(new LatLng(lSpot.mLatitude,
                        lSpot.mLongitude));
                lCircleOptions.radius(lDiameter);
                lCircleOptions.strokeColor(Color.BLACK);
                lCircleOptions.strokeWidth(5);
                lCircleOptions.fillColor(Color.WHITE);
                lCircleOptions.zIndex(pZIndex);
    
                mGoogleMap.addCircle(lCircleOptions);
    
            }
        }
    }
    

    【讨论】:

    • 这似乎很好。我只是看到两个问题:第一,如果我画一个圆,把它移出屏幕再回来,我怎么知道它已经画好了? (我不能为每个地方都保留一个布尔值)。其次,如果地图一次显示所有可见点,我的意思是,全部 500 个,问题将是相同的。这可能发生在某些配置中。那你有什么建议?如果地图被放大,我现在将采用这种方法来提高响应能力。
    • 我会在重新绘制之前清除所有地点的地图。 mGoogleMap.clear()
    • 好的,我想我可以做到。最后一点,如果我要一次显示所有这些,你会怎么做?当用户想要显示所有内容并打开应用程序时,会发生这种情况,相机会缩小显示每个位置。
    • 使用drawable而不是为每个帖子创建一个圆圈会更快。我假设您有理由手动创建那么多圈子。可绘制对象会导致更少的问题。如果你打算这样做,那么也许看看聚类,这样当地图缩小时你就不会显示那么多圆圈。
    • 嗯,我使用圆圈的原因是我阅读了有关如何绘制圆圈的 Google 文档。如果内存效率更高,我将使用可绘制对象。缩放时是否会以相同的方式缩放或固定可绘制对象?我的意思是,我认为可绘制对象将用作标记,而不能用作叠加层。您如何用可绘制对象替换圆形选项代码(顺便说一下,绘制对象的大小应该与任何屏幕上的 10 米直径相匹配?)。
    【解决方案2】:

    您看到延迟的原因是您试图在 UI 线程的地图上绘制 500 个元素,这肯定会减慢速度。

    执行您想要的 IMO 操作的正确方法是获取地图投影并仅绘制当前可见的圆圈,并保留布尔值或其他东西以指示圆圈已被绘制。这样做会降低应用程序的速度,因为它不会绘制所有内容,最终会导致所有项目都绘制在地图上(假设所有圆圈都是可见的),因此您最终不必再绘制任何内容。

    【讨论】:

      猜你喜欢
      • 2011-06-07
      • 1970-01-01
      • 2015-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-18
      • 2011-12-03
      相关资源
      最近更新 更多