OSMDroid 从资产文件夹加载自定义离线图块

2024-03-08

我想知道是否可以做这样的事情。我知道需要修改一些现有代码才能实现这一目标,但我想知道是否有人知道在哪里查看以及如何执行此操作。

我在地图上的特定区域放置了一些自定义图块,作为 OSM 图块提供程序的替代品,但需要将它们存储在 /assets/ 文件夹中。有任何想法吗?


我使用接下来的课程来做到这一点。

import java.io.InputStream;

import org.osmdroid.ResourceProxy.string;
import org.osmdroid.tileprovider.util.StreamUtils;

import android.content.res.AssetManager;
import android.graphics.drawable.Drawable;

public class AssetsTileSource extends CustomBitmapTileSourceBase {
        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, aResourceId, 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;
        }
}

MapTileFileAssetsProvider.java

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() : MAXIMUM_ZOOMLEVEL;
            }

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

            @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;
                    }
            }
    }

And

import java.io.File;
import java.io.InputStream;
import java.util.Random;

import org.osmdroid.ResourceProxy;
import org.osmdroid.ResourceProxy.string;
import org.osmdroid.tileprovider.ExpirableBitmapDrawable;
import org.osmdroid.tileprovider.MapTile;
import org.osmdroid.tileprovider.constants.OpenStreetMapTileProviderConstants;
import org.osmdroid.tileprovider.tilesource.ITileSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;

public abstract class CustomBitmapTileSourceBase implements ITileSource,
                OpenStreetMapTileProviderConstants {

        private static final Logger logger = LoggerFactory.getLogger(CustomBitmapTileSourceBase.class);

        private static int globalOrdinal = 0;

        private final int mMinimumZoomLevel;
        private final int mMaximumZoomLevel;

        private final int mOrdinal;
        protected final String mName;
        protected final String mImageFilenameEnding;
        protected final Random random = new Random();

        private final int mTileSizePixels;

        private final string mResourceId;

        public CustomBitmapTileSourceBase(final String aName, final string aResourceId,
                        final int aZoomMinLevel, final int aZoomMaxLevel, final int aTileSizePixels,
                        final String aImageFilenameEnding) {
                mResourceId = aResourceId;
                mOrdinal = globalOrdinal++;
                mName = aName;
                mMinimumZoomLevel = aZoomMinLevel;
                mMaximumZoomLevel = aZoomMaxLevel;
                mTileSizePixels = aTileSizePixels;
                mImageFilenameEnding = aImageFilenameEnding;
        }

        @Override
        public int ordinal() {
                return mOrdinal;
        }

        @Override
        public String name() {
                return mName;
        }

        public String pathBase() {
                return mName;
        }

        public String imageFilenameEnding() {
                return mImageFilenameEnding;
        }

        @Override
        public int getMinimumZoomLevel() {
                return mMinimumZoomLevel;
        }

        @Override
        public int getMaximumZoomLevel() {
                return mMaximumZoomLevel;
        }

        @Override
        public int getTileSizePixels() {
                return mTileSizePixels;
        }

        @Override
        public String localizedName(final ResourceProxy proxy) {
                return proxy.getString(mResourceId);
        }

        @Override
        public Drawable getDrawable(final String aFilePath) {
                try {
                        // default implementation will load the file as a bitmap and create
                        // a BitmapDrawable from it
                        final Bitmap bitmap = BitmapFactory.decodeFile(aFilePath);
                        if (bitmap != null) {
                                return new ExpirableBitmapDrawable(bitmap);
                        } else {
                                // if we couldn't load it then it's invalid - delete it
                                try {
                                        new File(aFilePath).delete();
                                } catch (final Throwable e) {
                                        logger.error("Error deleting invalid file: " + aFilePath, e);
                                }
                        }
                } catch (final OutOfMemoryError e) {
                        logger.error("OutOfMemoryError loading bitmap: " + aFilePath);
                        System.gc();
                }
                return null;
        }

        @Override
        public String getTileRelativeFilenameString(final MapTile tile) {
                final StringBuilder sb = new StringBuilder();
                sb.append(pathBase());
                sb.append('/');
                sb.append(tile.getX());
                sb.append('_');
                sb.append(tile.getY());
                sb.append('_');
                sb.append(tile.getZoomLevel());
                sb.append(imageFilenameEnding());
                return sb.toString();
        }


        @Override
        public Drawable getDrawable(final InputStream aFileInputStream) {
                try {
                        // default implementation will load the file as a bitmap and create
                        // a BitmapDrawable from it
                        final Bitmap bitmap = BitmapFactory.decodeStream(aFileInputStream);
                        if (bitmap != null) {
                                return new ExpirableBitmapDrawable(bitmap);
                        }
                        System.gc();
                } catch (final OutOfMemoryError e) {
                        logger.error("OutOfMemoryError loading bitmap");
                        System.gc();
                        //throw new LowMemoryException(e);
                }
                return null;
        }

        public final class LowMemoryException extends Exception {
                private static final long serialVersionUID = 146526524087765134L;

                public LowMemoryException(final String pDetailMessage) {
                        super(pDetailMessage);
                }

                public LowMemoryException(final Throwable pThrowable) {
                        super(pThrowable);
                }
        }
}

修改方法 getTileRelativeFilenameString() 以获取图块(我使用下一个格式:x_y_zoom.png)

例子:

mapView = new MapView(getApplicationContext(), 256);
mapView.setClickable(true);
mapView.setTag("Mapa");
mapView.setTileSource(TileSourceFactory.MAPNIK);
mapView.setMultiTouchControls(true);
mapView.setUseDataConnection(true);

MapTileModuleProviderBase moduleProvider = 
    new MapTileFileAssetsProvider(ASSETS_TILE_SOURCE);
SimpleRegisterReceiver simpleReceiver = 
    new SimpleRegisterReceiver(getApplicationContext());
MapTileProviderArray tileProviderArray = 
    new MapTileProviderArray(ASSETS_TILE_SOURCE, simpleReceiver, 
        new MapTileModuleProviderBase[] { moduleProvider });
TilesOverlay tilesOverlay = 
    new TilesOverlay(tileProviderArray, getApplicationContext());

mapView.getOverlays().add(tilesOverlay);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OSMDroid 从资产文件夹加载自定义离线图块 的相关文章

随机推荐

  • UIImageView 上的用户交互

    我有许多 UIImageView 上面有按钮 我想在这些按钮后面的 UIImageView 上启用用户交互 我在 IB 中看到了该选项 但想知道如何在实际触摸 UIImageView 时触发一些代码 如何做到这一点以及如何在代码而不是 IB
  • 如何正确使用 multiprocessing.Pool 与 PySide 来创建非阻塞 GUI

    我尝试使用多处理来创建非阻塞 GUI 函数 Multiprocessing Pool appy async 允许添加回调函数 以便在完成时间密集型操作后轻松更新主 GUI 但是 当单击button1时 以下代码仍然会阻塞 我怎样才能修改这个
  • Python ConfigParser:检查选项是否存在

    我正在使用 Python 的 ConfigParser 来创建配置文件 我想检查某个部分是否定义了特定选项 如果有 则获取该值 如果未定义该选项 我只想继续而不进行任何特殊行为 似乎有两种方法可以做到这一点 if config has op
  • 通过条件逻辑嵌套玉

    我有一个检索到的 json 数据结果集 称为 data list 我想迭代它并提取它的名称字段并将其嵌入 Twitter 引导网格隐喻中 其输出如下所示 div class row div class span4 Name 1 div di
  • 使用媒体流扩展 (MSE) 显示 getUserMedia Stream 实时视频

    我正在尝试使用 getUserMedia 显示从网络摄像头获取的 MediaStream 并使用任何可能播放的机制将其中继到远程对等点 作为实验 我没有直接使用 webRTC 因为我想控制原始数据 我遇到的问题是我的视频元素不显示任何内容
  • Bash 布尔测试

    如果一个标志设置为 true 而另一个标志设置为 false 我将尝试运行一段代码 IE var1 true var2 false if var1 var2 then var2 something fi 由于这没有按照我预期的方式进行评估
  • 使用 AutoMapper 映射分组集合

    我有以下代码不起作用 var groupedZones this zoneDataManager GetZonesGroupedByCountry IEnumerable
  • 无法获取 Master Kerberos 主体以用作 Talend Batch 作业的续订者

    我们正在尝试使用 talend 批处理 spark 作业来访问 Kerberos 集群中的配置单元 但我们收到以下 无法获取主 Kerberos 主体以用作更新程序 错误 通过使用 talend 中的标准作业 非 Spark 我们可以毫无问
  • 如何删除 UIToolBar 上的顶部边框

    我已将 UIToolBar 色调颜色设置为某个值 并且我看到了要删除的边框线 如何去掉这个黑色边框 gt 你可以这样做 self navigationController toolbar clipsToBounds YES
  • d3 按路径制作动画组

    这是我要增强的下一个问题原问题 https stackoverflow com questions 64954518 d3 animate path by arc 64954839 所以我正在尝试的是沿着填充路径为三角形标记和文本工具提示设
  • JNI char[](char数组)的方法描述符是什么?

    我的 JAVA 类代码片段 我想使用 JNI 从我的 C 文件访问 getReg chal 方法 public char getReg chal return reg chal 我的 C 文件执行一些 jni 操作 mid env gt G
  • Facebook 登录窗口在屏幕旋转时关闭

    我已经在我的应用程序中实现了 facebook 登录过程工作正常 当我点击 Facebook 图像时 它会打开 Facebook 登录窗口 但是当我旋转模拟器时 它会关闭登录窗口 任何解决方案 将其添加到您的活动的清单文件中 android
  • Sequelize 测试 - 有时会出现验证错误

    我正在通过 Mocha Chai 对续集定义运行单元测试 如下所示 运行的主要tests jsmocha tests js Testing Dependencies expect require chai expect should req
  • 在 netfilter 挂钩中查找发送数据包的可执行文件的名称

    我正在编写一个内核模块 它使用 netfilter 挂钩来过滤 TCP 数据包 并且需要找出发送数据包的可执行文件的路径 到目前为止 我已经使用了以下方法 但它打印的名称似乎与所使用的可执行文件无关 usr lib firefox fire
  • 如何模拟 aws-sdk gem?

    我有一些代码可以使用以下命令将文件上传到 Amazon S3aws sdk宝石 显然它执行了一个 HTTP put 来上传文件 有没有一种好方法来模拟 aws sdk gem 的此功能 我尝试使用 Webmock 但是 aws sdk ge
  • 如何忽略 Git 合并中的文件?

    我正在开发一个有两个分支的 Django 网站 master and dev master是生产版本 不应直接在此处完成任何工作 所有的改变都应该来自合并dev分支 一旦被认为是稳定的 dev正如您可能猜到的那样 是开发分支 所有更改都在这
  • ViM-LaTeX、python 和 Mac OS 10.8.1 以及一个奇怪的错误

    我刚刚将我的机器更新到 Mountain Lion 10 8 1 并尝试安装 vim latex 我已经每天使用该套件大约 5 年了 但是当尝试进行全新安装并打开 tex 文件时 我收到以下错误消息 UnitCircleAnalysis t
  • 提取模式后的值

    一个初学者的问题 我有一个这样的列表 x lt c aa v12 bb x21 cc f35 xx r53 bb g 25 yy h48 nn u75 bb 26 gg m98 但还有更多行 我需要提取 bb 和 之间的内容 IE 我想 x
  • 父类可以调用子类方法吗?

    参考here https stackoverflow com questions 1385895 accesing a function via string stored in hashtable A是预编译的Java类 我也有源文件 B
  • OSMDroid 从资产文件夹加载自定义离线图块

    我想知道是否可以做这样的事情 我知道需要修改一些现有代码才能实现这一目标 但我想知道是否有人知道在哪里查看以及如何执行此操作 我在地图上的特定区域放置了一些自定义图块 作为 OSM 图块提供程序的替代品 但需要将它们存储在 assets 文