Android 如何使路线绘制更有效?
这是我用来画路线的代码。当我有1000个点时,路由严重减慢ui。也许有人可以提供一个代码片段或链接来解释如何更有效地绘制路线?我知道解决这个问题的一种方法是缓存位图的路径,但我不知道怎么做Android 如何使路线绘制更有效?,android,path,bitmap,routes,Android,Path,Bitmap,Routes,这是我用来画路线的代码。当我有1000个点时,路由严重减慢ui。也许有人可以提供一个代码片段或链接来解释如何更有效地绘制路线?我知道解决这个问题的一种方法是缓存位图的路径,但我不知道怎么做 public class PathOverlay extends Overlay{ private GeoPoint startPoint; private GeoPoint finishPoint; private ArrayList<GeoPoint> pathPoints; private
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;
}
}
}
公共类PathVerlay扩展覆盖{
私人地质点起始点;
私人地质点修整点;
私有ArrayList路径点;
私人油漆;
专用路径;
专用点路径起始点;
专用点路径端点;
私人浮动dx;
私家车;
公共路径显示(地质点起点、地质点终点、阵列列表路径点、int颜色){
this.startPoint=startPoint;
this.finishPoint=finishPoint;
this.pathPoints=路径点;
this.paint=新油漆();
this.paint.setAntiAlias(true);
这个.paint.setDither(true);
此.paint.setColor(颜色);
这个.paint.setAlpha(150);
此。油漆。设置行程宽度(4);
this.paint.setStyle(paint.Style.STROKE);
}
@凌驾
公共空心绘制(画布覆盖Canvas、MapView MapView、布尔阴影){
if(路径==null){
path=getPath(地图视图);
}否则{
路径=转换路径(mapView);
}
覆盖Canvas.drawPath(路径,绘制);
super.draw(叠加Canvas、地图视图、阴影);
}
专用路径getPath(MapView MapView){
Projection=mapView.getProjection();
if(路径==null){
路径=新路径();
path.setFillType(FillType.WINDING);
}否则{
倒带();
}
点=新点();
pathStartPoint=新点();
pathEndPoint=新点();
投影。顶像素(起点、点);
投影.toPixels(起始点、路径起始点);
路径移动到(点x,点y);
添加圆(点x,点y,(浮点)2.0,方向.CCW);
如果(路径点!=null){
对于(int i=0;i提高绘图速度的最佳方法是减少路径包含的点的数量。它们可能不是必需的-它们中的很多只是位于上一个和下一个之间,因此您可以通过以下方式对它们进行过滤:
与上一点的最小距离(简易方式)
最小方位变化(稍微困难一点,尽管类及其方法bearingTo()
应该会有所帮助。您可以绘制透明位图
对象的路径(无论您认为合适的大小-越大,路径的细节越好,内存消耗也越高)
确保使用Bitmap.config.ARGB_8888
创建它以提高透明度
完成此操作后,您将使用两个矩形在覆盖图上显示路径
:
- 用于确定路径哪一部分可见的源矩形
- 一个目标矩形,用于确定要在
覆盖
的画布上显示此路径片段的位置
您将使用
应该不会太难,您已经完成了transformPath
方法中的大部分重要计算
添加:
实际上,您可以同时按住绘制到位图的路径和重画实际路径点。当用户在地图周围移动或放大/缩小时,使用上述技术,然后在用户放开屏幕时重画路径
你应该知道draw()方法绘制一个绘制周期大约50次。我不知道为什么,但你可以测试它。这会降低性能。如果你必须绘制1000个对象,draw()每个对象绘制30-50次…这会变得非常笨拙。。
为了避免这种情况,您应该创建一个缓存覆盖。此缓存将只绘制一次所有对象,并将拒绝其他绘制
要加快进程,请以低优先级绘制后台线程
在多个点之间绘制直线的最快方法是使用Canvas.drawLines方法(float[]pts、int offset、int count、Paint-Paint)。
我已经测试了所有的方法,这是android提供的最快的方法
我希望使用您的方法,但我发现了两个问题。如果我创建固定大小的位图并绘制更大的路径,则并非所有路径部分都将绘制到位图,因此,如果移动贴图,某些路径部分将不可见。如果创建路径大小的位图,我可能会遇到创建位图需要大量内存的问题对象,因此应用程序会被杀死。有什么解决方法吗?你可以缩小路径的大小。使用dst矩形将其放大。这将很好地执行,但根据位图的大小,在更高的缩放级别上可能缺少细节。如果路径不经常更改,则此解决方案效果很好,否则最好删除路径points.1.能否指定创建缓存覆盖将如何防止绘图运行超出需要?2.如何在后台线程中绘图?我知道可以使用SurfaceView在单独的线程中绘图,还是有其他方法?1.绘制位图。检查地图是否有任何更改(更改了地图中心、更改了缩放级别等)。如果有任何更改-重新绘制位图。如果没有,请在屏幕上绘制位图。2.我试图在SurfaceView中绘制,但未发生任何更改。您可以创建线程类,并在UI线程和后台线程之间创建通信模块位。请参阅HandlerThread类。可能的重复