Android Mapview平移和缩放太慢

时间:2010-01-04 09:13:46

标签: android android-mapview

我开发了一个GPS应用,我在其中记录用户根并显示它 在地图上.......但是 在查看我的路线时,在地图上平移是非常缓慢的, 地图响应手指需要至少4或5秒钟 划动......

我已经覆盖了onDraw()方法并绘制线条以显示 路线......有没有更好的方法来做到这一点,以便平移成为 更快,如"MyTracks" ...........

谢谢大家...... Pratap S.

4 个答案:

答案 0 :(得分:2)

我必须做something similar。我的尝试目前在onDraw中执行以下操作(为了便于阅读而简化了错误处理等错误处理):

if ((bmap == null) || (lastZoom != mapv.getLatitudeSpan()))
{
    // bitmap is null - so we haven't previously drawn the path, OR
    //  the map has been zoomed in/out, so we're gonna re-draw it anyway
    //    (alternatively, I could have tried scaling the bitmap... might
    //     be worth investigating if that is more efficient)

    Projection proj = mapv.getProjection();

    // store zoom level for comparing in the next onDraw
    lastZoom = mapv.getLatitudeSpan();

    // draw a path of all of the points in my route
    GeoPoint start = routePoints.get(0);
    Point startPt = new Point();            
    proj.toPixels(start, startPt);

    Path path = new Path();
    path.moveTo(startPt.x, startPt.y);

    Point nxtPt;

    for (GeoPoint nextPoint : routePoints) 
    {
        nxtPt = new Point();
        proj.toPixels(nextPoint, nxtPt);
        path.lineTo(nxtPt.x, nxtPt.y);
    }

    // create a new bitmap, the size of the map view
    bmap = Bitmap.createBitmap(mapv.getWidth(), mapv.getHeight(), Bitmap.Config.ARGB_8888);

    // create an off-screen canvas to prepare new bitmap, and draw path on to it
    Canvas offscreencanvas = new Canvas(bmap);
    offscreencanvas.drawPath(path, mPaint);

    // draw the bitmap of the path onto my map view's canvas
    canvas.drawBitmap(bmap, 0, 0, null);

    // make a note of where we put the bitmap, so we know how much we 
    //  we need to move it by if the user pans the map
    mapStartPosition = proj.fromPixels(0, 0);
}
else
{
    // as we're in onDraw, we think the user has panned/moved the map
    //  if we're in here, the zoom level hasn't changed, and
    //   we've already got a bitmap with a drawing of the route path

    Projection proj = mapv.getProjection();

    // where has the mapview been panned to?
    Point offsetPt = new Point();
    proj.toPixels(mapStartPosition, offsetPt);

    // draw the bitmap in the new correct location
    canvas.drawBitmap(bmap, offsetPt.x, offsetPt.y, null);
}

它还不完美....例如,路径在缩放后立即在错误的位置结束 - 一旦用户开始平移就移动到正确的位置。

但这是一个开始 - 并且比在每次onDraw调用上重绘路径更有效率

希望这有帮助!

答案 1 :(得分:2)

从5月7日开始评论dalelane的回答: 我使用你的解决方案来减少绘图的负荷,但稍微修改了一下:

  • 如果地图中心,缩放级别已被cjanged或没有旧位图,则会创建新的位图。

缩放后,路线被放置在正确的位置。当检测到更改的缩放级别时,似乎缩放尚未完全完成。

我使用了一个计时器,它在缩放级别改变后延迟600毫秒后将地图中心修改了10。 通过更改地图中心,将调用draw方法并创建新的位图。然后正确放置路线。  这是一个丑陋的工作。有没有人有更好的解决方案?

private void panAfterZoom(MapView mv, long delay){
    timer = new java.util.Timer("drawtimer", true);
    mapView=mv;
    task = new java.util.TimerTask() {
       public void run() {
           GeoPoint center=mapView.getMapCenter();
           GeoPoint point=new GeoPoint(center.getLatitudeE6()+10, center.getLongitudeE6());
           MapController contr=mapView.getController();
           contr.setCenter(point);
           timer.cancel();
       }
       };
    timer.schedule(task, delay);
}

这在draw方法中被调用为:pabAfterZoom(mapView,600);

博斯特

答案 2 :(得分:1)

感谢dalelane ,上面的建议帮助我改进了路线覆盖。 我想分享一个改进,解决了缩放变化后路径在错误位置结束的问题。

问题根本原因: mapview.getLatitudeSpan()以及mapview.getZoomLevel()方法返回的值不考虑缩放值之间的渐进地图比例变化(动画)。

<强>解决方案: 方法mapview.getProjection()。fromPixels(x,y)将此渐进变化考虑在内,因此您可以从中构建getLatitudeSpan()或getLongitudeSpan(),并且路径将始终正确显示。

以下是dalelane建议的代码,其中包含所做的更改:

**int lonSpanNew = mapv.getProjection().fromPixels(0,mapv.getHeight()/2).getLongitudeE6() - mapv.getProjection().fromPixels(mapv.getWidth(),mapview.getHeight()/2).getLongitudeE6();**
if ((bmap == null) || (lastZoom != **lonSpanNew** )) 
{ 
    // bitmap is null - so we haven't previously drawn the path, OR 
    //  the map has been zoomed in/out, so we're gonna re-draw it anyway 
    //    (alternatively, I could have tried scaling the bitmap... might 
    //     be worth investigating if that is more efficient) 

    Projection proj = mapv.getProjection(); 

    // store zoom level for comparing in the next onDraw 
    lastZoom = **lonSpanNew**;  

    // draw a path of all of the points in my route 
    GeoPoint start = routePoints.get(0); 
    Point startPt = new Point();             
    proj.toPixels(start, startPt); 

    Path path = new Path(); 
    path.moveTo(startPt.x, startPt.y); 

    Point nxtPt; 

    for (GeoPoint nextPoint : routePoints)  
    { 
        nxtPt = new Point(); 
        proj.toPixels(nextPoint, nxtPt); 
        path.lineTo(nxtPt.x, nxtPt.y); 
    } 

    // create a new bitmap, the size of the map view 
    bmap = Bitmap.createBitmap(mapv.getWidth(), mapv.getHeight(), Bitmap.Config.ARGB_8888); 

    // create an off-screen canvas to prepare new bitmap, and draw path on to it 
    Canvas offscreencanvas = new Canvas(bmap); 
    offscreencanvas.drawPath(path, mPaint); 

    // draw the bitmap of the path onto my map view's canvas 
    canvas.drawBitmap(bmap, 0, 0, null); 

    // make a note of where we put the bitmap, so we know how much we  
    //  we need to move it by if the user pans the map 
    mapStartPosition = proj.fromPixels(0, 0); 
} 
else 
{ 
    // as we're in onDraw, we think the user has panned/moved the map 
    //  if we're in here, the zoom level hasn't changed, and 
    //   we've already got a bitmap with a drawing of the route path 

    Projection proj = mapv.getProjection(); 

    // where has the mapview been panned to? 
    Point offsetPt = new Point(); 
    proj.toPixels(mapStartPosition, offsetPt); 

    // draw the bitmap in the new correct location 
    canvas.drawBitmap(bmap, offsetPt.x, offsetPt.y, null); 
}

希望这有帮助。 问候, 路易斯

答案 3 :(得分:0)

覆盖onDraw是唯一的方法。你是如何绘制曲目的,也许可以提高效率?