【问题标题】:Android google maps drawing roads performanse issue with 10.000+ overlayAndroid 谷歌地图绘制道路性能问题与 10.000+ 覆盖
【发布时间】:2012-04-01 13:32:38
【问题描述】:

我正在开展一个项目,该项目正在启动绘制道路并显示有关道路的一些信息。问题是我使用了这么多地理点(5.000-10.000 +)并绘制线点到点并显示不同颜色的道路,所以地图太慢了。我做了一些关于我的配置应用程序,但仍然太慢。 您对解决我的问题并提高性能有任何想法吗?

这是我的代码。

for (int t = 0; t < roads.size(); t++) {

            for (int i = 0; i < roads.get(t).size() - 1; i++) {
                                //bounds up-bottom-right-left to draw roads
                if (boundBox[0] >= roads.get(t).get(i)
                        .getLatitudeE6()
                        && boundBox[1] >= roads.get(t).get(i)
                                .getLongitudeE6()
                        && boundBox[2] <= roads.get(t).get(i)
                                .getLatitudeE6()
                        && boundBox[3] <= roads.get(t).get(i)
                                .getLongitudeE6()) {


                    MyOverlay mOverlay = new MyOverlay();
                    mOverlay.setColor(Color.GREEN);

                    mOverlay.setWidth(4);
                    mOverlay.setPair(roads.get(t).get(i),
                            roads.get(t).get(i + 1));
                    mapOverlays.add(mOverlay);
                }
            }
        }

 class MyOverlay extends Overlay {

            GeoPoint gp1 = new GeoPoint(0, 0);
            GeoPoint gp2 = new GeoPoint(0, 0);
            int colr=0,width=0;



            public MyOverlay() {

            }

            public void draw(Canvas canvas, MapView mapv, boolean shadow) {
                super.draw(canvas, mapv, false);

                Paint mPaint = new Paint();
                mPaint.setDither(true);
                mPaint.setColor(colr);
                mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
                mPaint.setStrokeJoin(Paint.Join.ROUND);
                mPaint.setStrokeCap(Paint.Cap.ROUND);
                mPaint.setStrokeWidth(width);

                Point p1 = new Point();
                Point p2 = new Point();

                Path path = new Path();

                Projection projection = mapv.getProjection();
                projection.toPixels(gp1, p1);
                projection.toPixels(gp2, p2);

                path.moveTo((float) p2.x, (float) p2.y);
                path.lineTo((float) p1.x, (float) p1.y);


                // canvas.drawBitmap(markerBitmap, point.x, point.y, null);

                canvas.drawPath(path, mPaint);
                //canvas.drawBitmap(bitmap, src, dst, paint);

            }

            public void setPair(GeoPoint gpone, GeoPoint gptwo) {

                gp1 = gpone;
                gp2 = gptwo;

            }

            public void setColor(int clr)
            {
                colr=clr;
            }

            public void setWidth(int w)
            {
                width=w;
            }


        }

有人可以解决我的问题吗?

【问题讨论】:

  • 一些关于如何实现这些 5000-10000+ 的编码会很有用,因为您可能没有以有效的方式实现它
  • 我也有同样的疑问,有人可以帮助我们吗?

标签: android performance google-maps map


【解决方案1】:

您可以采取一些措施来提高效率。

您的第一个代码块可能会更高效:

for (int t = 0, size = roads.size(); t < size; t++) { //Avoid calling '.size()' over and over
    for (int i = 0; i < roads.get(t).size() - 1; i++) {//Avoid calling '.size()' over and over
        final GeoPoint road = roads.get(t).get(i); //Reduce the number of get() calls.
        if (boundBox[0] >= road.getLatitudeE6()
            && boundBox[1] >= road.getLongitudeE6()
            && boundBox[2] <= road.getLatitudeE6()
            && boundBox[3] <= road.getLongitudeE6()) {
                MyOverlay mOverlay = new MyOverlay();
                mOverlay.setColor(Color.GREEN);
                mOverlay.setWidth(4);
                mOverlay.setPair(road, roads.get(t).get(i + 1));
                mapOverlays.add(mOverlay);
        }
    }
}

但最重要的是,我在您的代码中看到的最大性能消耗是每次调用 draw() 时您都在分配一个新的渲染对象(Paint、Path、Point)。这可以重构,以便您重用相同的 Paint 实例:

class MyOverlay extends Overlay {
    GeoPoint gp1 = new GeoPoint(0, 0);
    GeoPoint gp2 = new GeoPoint(0, 0);
    Point p1 = new Point();
    Point p2 = new Point();
    Path path = new Path();
    int colr=0,width=0;

    public MyOverlay() {
          Paint mPaint = new Paint();
          mPaint.setDither(true);
          mPaint.setColor(colr);
          mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
          mPaint.setStrokeJoin(Paint.Join.ROUND);
          mPaint.setStrokeCap(Paint.Cap.ROUND);
          mPaint.setStrokeWidth(width);
    }

      public void draw(Canvas canvas, MapView mapv, boolean shadow) {
          super.draw(canvas, mapv, false);

          path.reset();

          Projection projection = mapv.getProjection();
          projection.toPixels(gp1, p1);
          projection.toPixels(gp2, p2);

          path.moveTo((float) p2.x, (float) p2.y);
          path.lineTo((float) p1.x, (float) p1.y);
          canvas.drawPath(path, mPaint);
      }
  }

有关详细信息,请参阅此处文章的“注意事项”部分:http://android-developers.blogspot.com.au/2011/03/android-30-hardware-acceleration.html

文章中的相关观点是:“不要在draw方法中创建渲染对象:一个常见的错误是每次调用渲染方法时都创建一个新的Paint,或者一个新的Path。这是不仅浪费,迫使系统更频繁地运行 GC,还绕过了硬件管道中的缓存和优化。”

【讨论】:

  • 谢谢兄弟。做得好。我减少了 size() 和 get() 方法。我现在不使用它们。它比旧的更快。现在,我正在尝试您的建议。再次感谢。
猜你喜欢
  • 2012-06-01
  • 1970-01-01
  • 2012-11-21
  • 1970-01-01
  • 1970-01-01
  • 2011-05-28
  • 1970-01-01
  • 1970-01-01
  • 2011-06-07
相关资源
最近更新 更多