如何使路线绘图更有效率?

时间:2011-07-12 15:25:14

标签: android path bitmap routes

这是我用来绘制路线的代码。当我有1000点时,路线严重减慢了ui。也许有人可以提供代码片段或链接来解释如何更有效地进行路线绘制?我知道解决这个问题的一种方法是缓存位图的路径,但不知道如何做到这一点。

public class PathOverlay extends Overlay{

private GeoPoint startPoint;
private GeoPoint finishPoint;
private ArrayList<GeoPoint> pathPoints;
private Paint paint;
private Path path;
private Point pathStartPoint;
private Point pathEndPoint;

private float dx;
private float dy;


public PathOverlay(GeoPoint startPoint, GeoPoint finishPoint, ArrayList<GeoPoint> pathPoints, int color){
    this.startPoint = startPoint;
    this.finishPoint = finishPoint;
    this.pathPoints = pathPoints;
    this.paint = new Paint();
    this.paint.setAntiAlias(true);
    this.paint.setDither(true);
    this.paint.setColor(color);
    this.paint.setAlpha(150);
    this.paint.setStrokeWidth(4);
    this.paint.setStyle(Paint.Style.STROKE);
}

@Override
public void draw(Canvas overlayCanvas, MapView mapView, boolean shadow) {
    if(path == null) {
        path = getPath(mapView);
    } else {
        path = transformPath(mapView);
    }
    overlayCanvas.drawPath(path, paint);
    super.draw(overlayCanvas, mapView, shadow);
}

private Path getPath(MapView mapView) {
    Projection projection = mapView.getProjection();
    if(path == null) {
        path = new Path();
        path.setFillType(FillType.WINDING);
    } else {
        path.rewind();
    }
    Point point = new Point();
    pathStartPoint = new Point();
    pathEndPoint = new Point();

    projection.toPixels(startPoint, point);
    projection.toPixels(startPoint, pathStartPoint);
    path.moveTo(point.x, point.y);
    path.addCircle(point.x, point.y, (float) 2.0, Direction.CCW);
    if (pathPoints != null) {
        for(int i=0;i<pathPoints.size();i++) {
            projection.toPixels(pathPoints.get(i), point);
            path.lineTo(point.x, point.y);
        }
    }
    projection.toPixels(finishPoint, point);
    projection.toPixels(finishPoint, pathEndPoint);
    path.lineTo(point.x-5, point.y);
    path.addCircle(point.x-5, point.y, (float) 2.0, Direction.CCW);


    return path;
}

private Path transformPath(MapView mapView) {
    Projection projection = mapView.getProjection();

    Point sPoint = new Point();
    Point ePoint = new Point();
    projection.toPixels(startPoint, sPoint);
    projection.toPixels(finishPoint, ePoint);

    float sx = ((float)ePoint.x - (float)sPoint.x)/((float)pathEndPoint.x - (float)pathStartPoint.x);
    float sy = ((float)ePoint.y - (float)sPoint.y)/((float)pathEndPoint.y - (float)pathStartPoint.y);

    if(sx != 1.0 && sy != 1.0) {
        Log.i("PathOverlay", "resized");
        return getPath(mapView);
    } else {
        Log.i("PathOverlay", "moved");
        Matrix matrix = new Matrix();

        dx = (float)sPoint.x - (float)pathStartPoint.x;
        dy = (float)sPoint.y - (float)pathStartPoint.y;

        matrix.postTranslate(dx, dy);
        pathStartPoint = sPoint;
        pathEndPoint = ePoint;
        path.transform(matrix);

        return path;
    }
}

}

3 个答案:

答案 0 :(得分:2)

您可以绘制透明Bitmap对象的路径(无论您认为合适的大小 - 它越大,路径细节越好但内存消耗越高)。

请确保使用Bitmap.config.ARGB_8888创建透明度。

完成此操作后,您将使用两个矩形在Overlay上显示路径:

  • 确定路径的哪一部分可见的源矩形
  • 目标矩形,用于确定在Overlay画布上显示此路径的位置。

您将使用Canvas.drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint)

不应该太困难,你已经在transformPath方法中完成了大部分重要计算。

<强>加了:

实际上,您可以同时执行两者的组合,保持绘制到位图的路径并重新绘制实际路径点。当用户在地图上移动或放大/缩小时,使用上述技术,然后在用户离开屏幕时重绘路径。

答案 1 :(得分:0)

提高绘图速度的最佳方法是减少路径所包含的点数。可能它们不是必需的 - 它们很多只是在前一个和下一个之间放置,所以你可以通过以下方式过滤它们:

距离上一点(简单方法)的最小距离

最小的轴承变化(虽然Location类及其方法bearingTo()应该有所帮助,但有点困难。

答案 2 :(得分:0)

  1. 您应该知道draw()方法绘制一个绘制周期约50次。我不知道为什么,但你可以测试一下。这会降低性能。如果你必须绘制1000个对象并且draw()每个绘制30-50个...它变得非常笨拙.. 为了避免这种情况,你应该创建一个缓存覆盖。这个缓存只会绘制一次所有对象,并拒绝其他绘制。

  2. 要加快处理速度,请使用优先级较低的后台线程进行绘制。

  3. 在多个点之间绘制直线的最快方法是使用方法Canvas.drawLines(float [] pts,int offset,int count,Paint paint)。 我测试了所有方法,这是android提供的最快方法。