【问题标题】:Detect if the OSM Mapview is still loading or not in android检测 OSM Mapview 是否仍在 android 中加载
【发布时间】:2013-06-09 09:12:19
【问题描述】:

我在我的 Android 应用程序中包含了 Open Street Maps。在地图视图中,用户应该能够在地图完全加载后捕获屏幕。但是目前即使地图视图仍在加载,用户也可以捕获图像。谁能告诉我如何检测地图视图何时完全加载?

下面是我加载地图视图的代码:

public class MainActivity extends Activity  {
    MapView mapView;
    MyLocationOverlay myLocationOverlay = null;
    ArrayList<OverlayItem> anotherOverlayItemArray;
    protected ItemizedOverlayWithBubble<ExtendedOverlayItem> itineraryMarkers;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mapView = (MapView) findViewById(R.id.mapview);

        final ArrayList<ExtendedOverlayItem> waypointsItems = new ArrayList<ExtendedOverlayItem>();
        itineraryMarkers = new ItemizedOverlayWithBubble<ExtendedOverlayItem>(this, waypointsItems, mapView, new ViaPointInfoWindow(R.layout.itinerary_bubble, mapView));
        mapView.getOverlays().add(itineraryMarkers);

        mapView.setTileSource(TileSourceFactory.MAPNIK);
        mapView.setBuiltInZoomControls(true);
        MapController mapController = mapView.getController();
        mapController.setZoom(1);
        GeoPoint point2 = new GeoPoint(51496994, -134733);
        mapController.setCenter(point2);

        Drawable marker=getResources().getDrawable(android.R.drawable.star_big_on);
        GeoPoint myPoint1 = new GeoPoint(0*1000000, 0*1000000);
        ExtendedOverlayItem overlayItem = new ExtendedOverlayItem("Title Test Loc", "Desc", myPoint1, this);
        overlayItem.setMarkerHotspot(OverlayItem.HotspotPlace.BOTTOM_CENTER);
        overlayItem.setMarker(marker);
        overlayItem.setRelatedObject(0);
        itineraryMarkers.addItem(overlayItem);
        mapView.invalidate();



        myLocationOverlay = new MyLocationOverlay(this, mapView);
        mapView.getOverlays().add(myLocationOverlay);
        myLocationOverlay.enableMyLocation();

        myLocationOverlay.runOnFirstFix(new Runnable() {
            public void run() {
             mapView.getController().animateTo(myLocationOverlay.getMyLocation());
               } 
           });


    }

    @Override
     protected void onResume() {
      // TODO Auto-generated method stub
      super.onResume();
      myLocationOverlay.enableMyLocation();
      myLocationOverlay.enableCompass();
      myLocationOverlay.enableFollowLocation();
     } 

     @Override
     protected void onPause() {
      // TODO Auto-generated method stub
      super.onPause();
      myLocationOverlay.disableMyLocation();
      myLocationOverlay.disableCompass();
      myLocationOverlay.disableFollowLocation();
     }

【问题讨论】:

    标签: android map osmdroid openstreetmap


    【解决方案1】:

    看看TilesOverlayTileLooper 的实现。这就是我们用来加载然后在屏幕上绘制每个图块的方法。在handleTile(...) 中,我们尝试从磁贴提供者mTileProvider.getMapTile(pTile) 获取磁贴。如果返回Drawable,则加载磁贴,否则将返回null

    一个简单的方法是扩展TilesOverlay,覆盖drawTiles(...)并在调用super.drawTiles(...)之前调用你自己的TileLooper,这将检查是否所有传递给handleTile(...)的图块都没有空值。要使用 TilesOverlay,请致电 mMapView.getOverlayManager().setTilesOverlay(myTilesOverlay)

    【讨论】:

    • 非常感谢,能否提供一些示例代码?
    • 我能想出一组这样的代码: public class Tiles extends TilesOverlay{ public Tiles(MapTileProviderBase aTileProvider, Context aContext) { super(aTileProvider, aContext); // TODO 自动生成的构造函数存根 } @Override public void drawTiles(Canvas c, int zoomLevel, int tileSizePx, Rect viewPort) { // TODO 自动生成的方法存根 TileLooper tileloop; tileloop.handleTile(arg0, arg1, arg2, arg3, arg4) super.drawTiles(c, zoomLevel, tileSizePx, viewPort); } } 请让我知道如何进行。谢谢!
    【解决方案2】:

    从osmdroid API 6.1.0开始,就很简单了:

    // check completeness of map tiles
    TileStates tileStates = mapView.getOverlayManager().getTilesOverlay().getTileStates();
    
    // evaluate the tile states
    if (tileStates.getTotal() == tileStates.getUpToDate())
    {
        // map is loaded completely
    
    }
    else
    {
        // loading is still in progress
    
    }
    
    /* meaning of TileStates
        .getUpToDate()   not expired yet
        .getExpired()    expired
        .getScaled()     computed during zoom
        .getNotFound()   default grey tile
        ---------------------------------------
        .getTotal()      sum of all above
    */
    

    【讨论】:

      【解决方案3】:

      我通过扩展 TilesOverlay 创建了一个名为“MyTileOverlay”的类,它延续了这个类:

      https://code.google.com/p/osmdroid/source/browse/trunk/osmdroid-android/src/main/java/org/osmdroid/views/overlay/TilesOverlay.java?r=1086

      然后在设置地图视图时,我这样做:

      this.mTilesOverlay = new MyTileOverlay(mProvider, this.getBaseContext());
      

      按照 kurtzmarc 的指示,我使用了 handleTile() 来检查是否正在加载所有图块:

      @Override
              public void handleTile(final Canvas pCanvas, final int pTileSizePx,
                      final MapTile pTile, final int pX, final int pY) {
                  Drawable currentMapTile = mTileProvider.getMapTile(pTile);
                  if (currentMapTile == null) {
                      currentMapTile = getLoadingTile();
                      Log.d("Tile Null", "Null");
                  } else {
      
                      Log.d("Tile Not Null", "Not Null");
                  }
      
                  if (currentMapTile != null) {
                      mTileRect.set(pX * pTileSizePx, pY * pTileSizePx, pX
                              * pTileSizePx + pTileSizePx, pY * pTileSizePx
                              + pTileSizePx);
                      onTileReadyToDraw(pCanvas, currentMapTile, mTileRect);
                  }
      
                  if (DEBUGMODE) {
                      mTileRect.set(pX * pTileSizePx, pY * pTileSizePx, pX
                              * pTileSizePx + pTileSizePx, pY * pTileSizePx
                              + pTileSizePx);
                      mTileRect.offset(-mWorldSize_2, -mWorldSize_2);
                      pCanvas.drawText(pTile.toString(), mTileRect.left + 1,
                              mTileRect.top + mDebugPaint.getTextSize(),
                              mDebugPaint);
                      pCanvas.drawLine(mTileRect.left, mTileRect.top,
                              mTileRect.right, mTileRect.top, mDebugPaint);
                      pCanvas.drawLine(mTileRect.left, mTileRect.top,
                              mTileRect.left, mTileRect.bottom, mDebugPaint);
                  }
              }
      

      此方法确保加载过程是否完成:

      @Override
                  public void finaliseLoop() {
                      Log.d("Loop Finalized", "Finalized");
                  }
      

      我也可以用这个方法来判断是否所有的瓦片都已经加载完毕:

      public int getLoadingBackgroundColor() {
                  return mLoadingBackgroundColor;
              }
      

      希望这对某人有所帮助!

      【讨论】:

        猜你喜欢
        • 2012-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多