android 没有asset_Mapbox:Android端支持本地离线Mbtiles了

本文介绍了如何通过对Mapbox Android SDK源码的改造,实现支持使用`mbtiles://`协议头加载本地MBTiles文件,从而实现离线地图功能。通过详细解析源码和开发过程,展示了在不改变Mapbox接口的情况下,如何无缝地整合MBTiles资源,提供了一种无需网络即可加载本地瓦片数据的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写在前面的话

    哈哈,终于做了一次标题党!giser小伙伴们是不是也像我一样朝思慕想这个功能的出世呢?可惜Mapbox团队只是增加了缓存机制,对此仍未支持。虽说有对本地离散文件瓦片的支持,可面对瓦片数量时,你懂的!无奈之下只能深入源码自力更生,并分享予大家。

一、先从源码说起

    经历了一层层剖析源码的各种曲折(Java与C++的双向交互),改造源码的各种尝试(希望对Mapbox现有接口最小化改造),编译调试源码时的焦急等待,效果出来时的那份激动(小雨中、夜色中黄河岸边溜达了好久),才有了这篇技术干货分享。此等经历有兴趣的小伙伴可以亲身体验体验哦,也欢迎留言交流分享源码心得。

    最后寻找到的最佳改造方式是什么样的呢?那要从下面这段资源请求(外部设置的uri)的核心代码说起了。

if (AssetFileSource::acceptsURL(resource.url)) {
    //Asset request--对应传入URI的协议头为"asset://"
    tasks[req] = assetFileSource->request(resource, callback);
} else if (LocalFileSource::acceptsURL(resource.url)) {
    //Local file request--对应传入URI的协议头为"file://"
    tasks[req] = localFileSource->request(resource, callback);
} else {//--对应传入URI的协议头为"http(s)://"
    // Try the offline database--本地离线缓存中查找URI资源
    if (resource.hasLoadingMethod(Resource::LoadingMethod::Cache)) {
        auto offlineResponse = offlineDatabase->get(resource);
        。。。。。。
    }
    // Get from the online file source--在线请求传入的URI资源
    if (resource.hasLoadingMethod(Resource::LoadingMethod::Network)) {
        MBGL_TIMING_START(watch);
        tasks[req] = onlineFileSource.request(resource, [=] (Response onlineResponse) {
        //--将请求到的资源保存到本地缓存
        this->offlineDatabase->put(resource, onlineResponse);
        。。。。。。
    }
}

源码中对应的是Mapbox定义和支持的三种协议头,分别是:

http://,load resources using HyperText Transfer Protocol,通过http协议请求网络资源。

file://,load resources from the Android file system,请求Android本地文件系统资源。

asset://,load resources from the binary packaged assets folder,请求assets包中的资源。

    接下来咱来看看开发过程中调用栅格瓦片的常见代码:

mapboxMap.setStyle(styleUri, new Style.OnStyleLoaded() {
    @Override
    public void onStyleLoaded(@NonNull Style style) {
        // 访问天地图注记
        TileSet vecTileSet = new TileSet("1.0.0", "http://t0.tianditu.gov.cn/DataServer?T=cia_w&X={x}&Y={y}&L={z}&tk=你的token");
        RasterSource vecRasterSource = new RasterSource("TDT_CIA_SOURCEID", vecTileSet, 128);
        style.addSource(vecRasterSource);
        RasterLayer vecRasterLayer = new RasterLayer("TDT_CIA_LAYERID", "TDT_CIA_SOURCEID");
        style.addLayer(vecRasterLayer);
    }
});

类推下TileSet中的URI地址可以更换为可访问的asset://和file://协议头,经验证确实是可以的,但这两种协议头只能加载离散的瓦片(栅格或矢量)文件。

二、我们做了什么

    经过上节源码剖析的过程,便有了一个大胆设想:可以在不改变现有Mapbox接口的情况下新增一个mbtiles://协议头将请求mbtiles中瓦片的代码直接植入上节提到的资源请求代码块中,最后妥妥的成功了。

if (AssetFileSource::acceptsURL(resource.url)) {    //Asset request
    tasks[req] = assetFileSource->request(resource, callback);
} else if (LocalFileSource::acceptsURL(resource.url)) {    //Local file request
    tasks[req] = localFileSource->request(resource, callback);
} else if(LocalFileSource::acceptsMbtilesURL(resource.url)){    // Local mbtiles request--对应传入扩展的mbtiles://协议头requestMbtilesTile(resource, callback);
}else if(LocalFileSource::acceptsEsriBundle2URL(resource.url)){    // TODO:Local esri arcgis10.2 bundle request    // 后续增加对arcgis10.2以下版本bundle紧凑栅格瓦片的支持    //requestEsriBundle2Tile(resource, callback);
}else if(LocalFileSource::acceptsEsriBundle3URL(resource.url)){    // TODO:Local esri arcgis10.3 bundle request    // 后续增加对arcgis10.3及以上版本bundle紧凑栅格瓦片的支持    //requestEsriBundle3Tile(resource, callback);
} else {
    。。。。。。
}

    咱再来看看开发过程中调用栅格瓦片的代码:

mapboxMap.setStyle(styleUri, new Style.OnStyleLoaded() {            // 加载本地指定的mbtiles文件(下载的谷歌影像瓦片)

事先下载谷歌影像瓦片并存储为mbtiles格式(没有下载工具也不用担心,开放提供的测试包中提供了一份mbtiles包含了1-10级的的影像瓦片),然后在TileSet中采用mbtiles://协议头加上Android本地mbtiles文件的全路径,成功加载显示,不仅感叹与源码的完美融合。

0af70b556de2719546350dba18ebb4e4.png

我们是开放的

开放下载重新编译的Mapbox Android SDK(基于8.2.0分支源码);

开放下载SDK的测试代码;

开放下载一份mbtiles测试数据。

扫码联系获取以上开放资源

备注单位+姓名

723eff960df996194535d7a9d1fd2317.gif

74ba46ac8aaf0ad99778fc11adaab1dc.png

730bd32805bc2d033a93f826c180134c.gif b4d40e291cc32b2c8fb2ccbd7c6f5c56.png

关于ChinaGISer

从明天起,做一个幸福的人,喂马、劈柴,周游世界。

从明天起,关心粮食和蔬菜,我有一所房子,面朝大海,春暖花开。

海子所描述的美好愿景,可能是当前我们每个年轻人所期盼的生活吧。

我们就从愿景说起,我们尝试着能否聚拢一群有情怀的GISers,摒弃拿来主义的习性,主张自主的创新、创造和贡献、共享,在开源GIS领域展现中国GISER的力量。

d9d52c7994b276f8f5dc87a5a2c743f7.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值