1

我正在尝试在我的应用程序中使用 osmdroid 进行离线地图使用,但我找不到的是如何从/assets文件夹中设置图块源。所以我已经放置了瓷砖(来自Mobile Atlas Creator/assets/maps.zip ), 我正在尝试这样的事情:

final ITileSource tileSource = 
   new XYTileSource("maps", null, 15, 17, 256, "png", "/assets");
mapview.setBuiltInZoomControls(true);
mapview.setTileSource(tileSource);
mapview.getController().setZoom(15);
mapview.setUseDataConnection(false); 

..这在某种程度上似乎是错误的。那么有人可以指出我该怎么做吗?

4

3 回答 3

2

好的,这个问题几年前就被问过了,
但仍然没有关于如何使用资产文件夹中的离线地图的明确信息。
所以这是我的解决方案。

  1. 使用 Mobile Atlas Creator 创建地图。
    我使用 Atlas 格式 = osmdroid zip 和地图源 = OpenStreetMap 4UMaps.eu
  2. 解压缩地图并放入您的资产文件夹:
    assets/map/14,其中 14 - 例如具有相应缩放级别的文件夹(您可能会有多个文件夹)
  3. 添加我在互联网上某处找到的类:

    import android.content.res.AssetManager;
    import android.graphics.drawable.Drawable;    
    import org.osmdroid.ResourceProxy.string;
    import org.osmdroid.tileprovider.tilesource.BitmapTileSourceBase;
    import org.osmdroid.tileprovider.util.StreamUtils;
    
    import java.io.InputStream;
    
    /**
     * Custom tile source,
     * used to load map tiles from the assets
     */
    public class AssetsTileSource extends BitmapTileSourceBase {
        private final AssetManager mAssetManager;
    
        public AssetsTileSource(final AssetManager assetManager, final String aName, final string aResourceId,
                final int aZoomMinLevel, final int aZoomMaxLevel, final int aTileSizePixels,
                final String aImageFilenameEnding) {
            super(aName, aZoomMinLevel, aZoomMaxLevel, aTileSizePixels, aImageFilenameEnding);
            mAssetManager = assetManager;
        }
    
        @Override
        public Drawable getDrawable(final String aFilePath) {
            InputStream inputStream = null;
            try {
                inputStream = mAssetManager.open(aFilePath);
                if (inputStream != null) {
                    final Drawable drawable = getDrawable(inputStream);
                    return drawable;
                }
            } catch (final Throwable e) {
                // Tile does not exist in assets folder.
                // Ignore silently
            } finally {
                if (inputStream != null) {
                    StreamUtils.closeStream(inputStream);
                }
            }       
            return null;
        }
    }
    

/**
 * Map tile provider, loads tile from assets folder
 */
public class MapTileFileAssetsProvider extends MapTileModuleProviderBase {

    protected ITileSource mTileSource;

    public MapTileFileAssetsProvider(final ITileSource pTileSource) {
        super(OpenStreetMapTileProviderConstants.NUMBER_OF_TILE_FILESYSTEM_THREADS, OpenStreetMapTileProviderConstants.TILE_FILESYSTEM_MAXIMUM_QUEUE_SIZE);

        mTileSource = pTileSource;
    }

    @Override
    public boolean getUsesDataConnection() {
        return false;
    }

    @Override
    protected String getName() {
        return "Assets Folder Provider";
    }

    @Override
    protected String getThreadGroupName() {
        return "assetsfolder";
    }

    @Override
    protected Runnable getTileLoader() {
        return new TileLoader();
    }

    @Override
    public int getMinimumZoomLevel() {
        return mTileSource != null ? mTileSource.getMinimumZoomLevel() : Constants.MAP_ZOOM_ZOOM_MAX;
    }

    @Override
    public int getMaximumZoomLevel() {
        return mTileSource != null ? mTileSource.getMaximumZoomLevel() : Constants.MAP_ZOOM_ZOOM_MIN;
    }

    @Override
    public void setTileSource(final ITileSource pTileSource) {
        mTileSource = pTileSource;
    }

    private class TileLoader extends MapTileModuleProviderBase.TileLoader {

        @Override
        public Drawable loadTile(final MapTileRequestState pState) throws CantContinueException {

            if (mTileSource == null) {
                return null;
            }

            final MapTile pTile = pState.getMapTile();
            String path = mTileSource.getTileRelativeFilenameString(pTile);

            Drawable drawable;
            try {
                drawable = mTileSource.getDrawable(path);
            } catch (final LowMemoryException e) {
                // low memory so empty the queue
                throw new CantContinueException(e);
            }

            return drawable;
        }
    }
}
  1. 添加常量:
 // map min zoom level    
 public static final int MAP_ZOOM_ZOOM_MIN = 12;    
 // map max zoom level    
 public static final int MAP_ZOOM_ZOOM_MAX = 14;     
 // maps folder name in assets       
 public static final String MAP_ASSETS_FOLDER_NAME = "map";  

您可能已经猜到了,它们代表了我们之前使用 Mobile Atlas Creator 创建的最小和最大缩放级别。

  1. 最后但并非最不重要
    的实现代码片段:

        // making the map not use internet     
        mBinding.mapView.setUseDataConnection(false);    
    
        // Initializing the tile provider to use offline maps from the assets
        // This will load for instance from /map/14/12345/12345.png
        AssetsTileSource tileSource = new AssetsTileSource(
                getAssets(),
                Constants.MAP_ASSETS_FOLDER_NAME,
                ResourceProxy.string.offline_mode,
                Constants.MAP_ZOOM_ZOOM_MIN,
                Constants.MAP_ZOOM_ZOOM_MAX,
                256, ".png");
    
        MapTileModuleProviderBase moduleProvider = new
                MapTileFileAssetsProvider(tileSource);
        SimpleRegisterReceiver simpleReceiver = new
                SimpleRegisterReceiver(this);
        MapTileProviderArray tileProviderArray = new
                MapTileProviderArray(tileSource, simpleReceiver, new
                MapTileModuleProviderBase[] { moduleProvider });
    
        mBinding.mapView.setTileProvider(tileProviderArray);
    
        // not forget to invalidate the map on zoom
        mBinding.mapView.setMapListener(new MapListener() {
            @Override
            public boolean onScroll(ScrollEvent scrollEvent) {
                return false;
            }
    
            @Override
            public boolean onZoom(ZoomEvent zoomEvent) {
                mBinding.mapView.invalidate();
                return false;
            }
        });
    
于 2016-10-13T10:10:15.963 回答
0

资产路径是“file:///android_asset/”,如果你需要一个输入流,你可以通过 AssetManager 获得它。

于 2012-11-01T22:33:18.280 回答
0

看看BitmapAssetTileSource。iBurn -2012也可能有助于查看它的实际运行情况。

于 2014-04-24T14:51:22.247 回答