在Android中绘制(过滤)100k +指向MapView

时间:2012-07-21 07:01:16

标签: android performance google-maps optimization android-mapview

我正在尝试解决从巨大的(100k +)GeoPoints集到Android上的MapView的路径问题。 首先我想说,我经常搜索StackOverflow并且没有找到答案。我的代码的瓶颈实际上并没有画到画布上,而是Projection.toPixels(GeoPoint, Point)Rect.contains(point.x, point.y)方法。我是跳过点在屏幕上不可见,并且还根据当前缩放级别仅显示每个第n个点。当地图放大时我希望显示尽可能准确的路径,所以我跳过零(或接近零)点,这样当找到可见点时,我需要为集合中的每个点调用投影方法。这真的需要花费很多时间(不是几秒钟,但是地图平移不流畅,我没有在HTC Wildfire上测试:))。我尝试缓存计算点,但由于每次映射平移/缩放后重新计算点数都没有帮助 一点都不。

我考虑过使用某种修剪和搜索算法而不是迭代数组,但我发现输入数据没有排序(我不能扔掉任何堆叠在两个不可见点之间的分支)。我可以在开始时通过简单的排序来解决这个问题,但我仍然不确定即使是getProjection()Rect.contains(point.x, point.y)调用的对数计数而不是线性也会解决性能问题。

贝娄是我目前的代码。如果你知道如何做得更好,请帮助我。非常感谢!

public void drawPath(MapView mv, Canvas canvas) {
    displayed = false;

    tmpPath.reset();

    int zoomLevel = mapView.getZoomLevel();
    int skippedPoints = (int) Math.pow(2, (Math.max((19 - zoomLevel), 0)));
    int mPointsSize = mPoints.size();
    int mPointsLastIndex = mPointsSize - 1;
    int stop = mPointsLastIndex - skippedPoints;

    mapView.getDrawingRect(currentMapBoundsRect);
    Projection projection = mv.getProjection();

    for (int i = 0; i < mPointsSize; i += skippedPoints) {

        if (i > stop) {
            break;
        }
//HERE IS THE PROBLEM I THINK - THIS METHOD AND THE IF CONDITION BELOW
        projection.toPixels(mPoints.get(i), point);

        if (currentMapBoundsRect.contains(point.x, point.y)) {
            if (!displayed) {
                Point tmpPoint = new Point();
                projection.toPixels(mPoints.get(Math.max(i - 1, 0)),
                        tmpPoint);
                tmpPath.moveTo(tmpPoint.x, tmpPoint.y);
                tmpPath.lineTo(point.x, point.y);
                displayed = true;
            } else {

                tmpPath.lineTo(point.x, point.y);

            }

        } else if (displayed) {
            tmpPath.lineTo(point.x, point.y);
            displayed = false;

        }

    }

    canvas.drawPath(tmpPath, this.pathPaint);

}

1 个答案:

答案 0 :(得分:3)

所以我想出了如何让它变得更快! 我会在这里发布,有人可能会发现它在将来有用。 已经发现projection.toPixels()的使用确实会损害应用程序性能。因此,我认为这比采用每一个GeoPoint更好,将其转换为Point,然后检查它是否包含在地图视口中,当我计算地图的实际视口半径时,如下所示: / p>

    mapView.getGlobalVisibleRect(currentMapBoundsRect);
    GeoPoint point1 = projection.fromPixels(currentMapBoundsRect.centerX(), currentMapBoundsRect.centerY());
    GeoPoint point2 = projection.fromPixels(currentMapBoundsRect.left, currentMapBoundsRect.top);
    float[] results2 = new float[3];
    Location.distanceBetween(point1.getLatitudeE6()/1E6, point1.getLongitudeE6()/1E6, point2.getLatitudeE6()/1E6, point2.getLongitudeE6()/1E6, results2);

半径在results2 [0] ..

然后我可以拍摄每张GeoPoint并计算它与地图中心mapView.getMapCenter()之间的距离。然后我可以将半径与计算出的距离进行比较,并决定是否不显示该点。

就是这样,希望它会有所帮助。