【问题标题】:Android Mapview panning and zooming too slowAndroid Mapview 平移和缩放太慢
【发布时间】:2012-07-02 09:53:11
【问题描述】:

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

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

谢谢大家..... 普拉塔普。

【问题讨论】:

    标签: android android-mapview


    【解决方案1】:

    我不得不做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 调用时重绘路径效率高得多

    希望这会有所帮助!

    【讨论】:

    • 有没有人想出缩放的东西?我断断续续地和这个怪物搏斗了 10 个月。
    【解决方案2】:

    从 5 月 7 日评论 dalelane 的回答: 我使用了你的解决方案来减少绘图的负担,但做了一些修改:

    • 如果地图中心、缩放级别已更改或不存在旧位图,则会创建新位图。

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

    我使用了一个计时器,它在缩放级别更改后延迟 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);

    博斯特

    【讨论】:

      【解决方案3】:

      感谢 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); 
      }
      

      希望对您有所帮助。 问候, 路易斯

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 2023-03-07
          • 1970-01-01
          • 2012-08-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-08
          相关资源
          最近更新 更多