如何使用资源作为osmdroid离线地图的来源

时间:2012-11-01 22:07:34

标签: android osmdroid

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

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); 

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

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

看看BitmapAssetTileSource。此外,iBurn-2012可能有助于查看其实际效果。

答案 2 :(得分:0)

好的,这个问题已在几年前提出,
但是仍然没有关于如何使用assets文件夹中的离线地图的明确信息 所以这是我的解决方案。

  1. 使用Mobile Atlas Creator创建地图 我使用了Atlas format = osmdroid zip和maps source = 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;
        }
    }
    
  4. /**
     * 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;
       //在资产中映射文件夹名称  public static final String MAP_ASSETS_FOLDER_NAME =" map&#34 ;;

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

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

        //使地图不使用互联网
                mBinding.mapView.setUseDataConnection(假);

            // 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;
                }
            });