web百度离线地图开发(详细教程)

  • 需求情景
  • 主要参考
  • 开发步骤
    • 一、JS API文件下载
    • 二、修改API文件
      • 1、屏蔽ak验证
      • 2、设置引用本地资源路径
      • 3、下载本地资源
      • 4、引用本地资源
    • 三、加载瓦片改为本地离线瓦片
      • 1、存储目录
      • 2、下载瓦片
      • 3、瓦片配置文件
      • 4、修改加载瓦片路径
    • 四、关于离线
    • 五、关于地图下载器
      • 1、免费/付费
      • 2、瓦片文件的大小

需求情景

项目在内网上使用,不得连接外网,所以需要开发离线地图功能
这个项目是vue+vue-cli的,需要对vue和这种项目结构有些了解
这是自己写的vue项目构建的文章,很详细,不了解的可以看看:
https://blog.csdn.net/PGguoqi/article/details/88977403

主要参考

我这里算是对这次开发做个总结,主要参考了下面两篇文章,但是因为或多或少都不是很详细,中间卡了好久,最后捣鼓出来了,所以写个文章记录分享下,照着一步一步走,绝对能开发出来。
https://blog.csdn.net/wml00000/article/details/82219015
https://blog.csdn.net/a312024054/article/details/70213444
如有谬误,还望指正。希望对大家有所帮助

开发步骤

一、JS API文件下载

访问这个地址 http://api.map.baidu.com/api?v=3.0 ,打开之后是一段代码:
在代码中找到 src="http://api.map.baidu.com/getscript?v=3.0&ak=&services=&t=20180823175819",打开这个链接,就可以看到压缩后的js代码,这个是我们要用到的代码:

在站长工具 http://tool.chinaz.com/tools/jsformat.aspx 将上面的压缩代码格式化备用,以便下面查看与修改。
static/js目录下新建个js文件,我这里命名为 bmap_offline_api_min.js ,将上面格式化后的js代码复制到这个文件中:

最后,需要在入口index.html的head中引入这个js:

二、修改API文件

1、屏蔽ak验证

bmap_offline_api_min.js 文件中,用 Math.random() 多找几次,定位到下列代码位置:
(以下代码方法名称和一些变量名称可能会有出入,我下载的代码就和网上一些贴子上看到的代码不尽相同)

function oa(a, b) {if (b) {var c = (1E5 * Math.random()).toFixed(0);z._rd["_cbk" + c] = function(a) {b && b(a);delete z._rd["_cbk" + c]};a += "&callback=BMap._rd._cbk" + c}var d = K("script", {type: "text/javascript"});d.charset = "utf-8";d.src = a;d.addEventListener ? d.addEventListener("load",function(a) {a = a.target;a.parentNode.removeChild(a)},q) : d.attachEvent && d.attachEvent("onreadystatechange",function() {var a = window.event.srcElement;a && ("loaded" == a.readyState || "complete" == a.readyState) && a.parentNode.removeChild(a)});setTimeout(function() {document.getElementsByTagName("head")[0].appendChild(d);d = p},1)
};

然后修改上面的代码,对http拦截,不进行外部访问,只需在最开始加一行代码if (/^http/.test(a)) return;

function oa(a, b) {//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!if (/^http/.test(a)) return; // !!!!!这里加判断,如果是调用外部资源就退出去//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!if (b) {var c = (1E5 * Math.random()).toFixed(0);z._rd["_cbk" + c] = function(a) {b && b(a);delete z._rd["_cbk" + c]};a += "&callback=BMap._rd._cbk" + c}var d = K("script", {type: "text/javascript"});d.charset = "utf-8";d.src = a;d.addEventListener ? d.addEventListener("load",function(a) {a = a.target;a.parentNode.removeChild(a)},q) : d.attachEvent && d.attachEvent("onreadystatechange",function() {var a = window.event.srcElement;a && ("loaded" == a.readyState || "complete" == a.readyState) && a.parentNode.removeChild(a)});setTimeout(function() {document.getElementsByTagName("head")[0].appendChild(d);d = p},1)
};

2、设置引用本地资源路径

bmap_offline_api_min.js 文件中,用 url.domain.main_domain_cdn.baidu[0] 多找几次,定位到下面的代码:

z.url = z.Y_[z.Qy];
z.wp = z.url.proto + z.url.domain.baidumap + "/";
z.wc = z.url.proto + ("2" == z.Qy ? z.url.domain.main_domain_nocdn.other: z.url.domain.main_domain_nocdn.baidu) + "/";
z.ma = z.url.proto + ("2" == z.Qy ? z.url.domain.main_domain_cdn.other[0] : z.url.domain.main_domain_cdn.baidu[0]) + "/";
z.cj = z.url.proto + z.url.domain.main_domain_cdn.webmap[0] + "/";
z.rg = function(a, b) {var c, d, b = b || "";switch (a) {case "main_domain_nocdn":
...

然后将 z.cj = z.url.proto + z.url.domain.main_domain_cdn.webmap[0] + "/" 改为 z.cj = ''

z.url = z.Y_[z.Qy];
z.wp = z.url.proto + z.url.domain.baidumap + "/";
z.wc = z.url.proto + ("2" == z.Qy ? z.url.domain.main_domain_nocdn.other: z.url.domain.main_domain_nocdn.baidu) + "/";
z.ma = z.url.proto + ("2" == z.Qy ? z.url.domain.main_domain_cdn.other[0] : z.url.domain.main_domain_cdn.baidu[0]) + "/";
//!!!!!!!!!!!!!!!!!!!!!!!
z.cj = '';
//!!!!!!!!!!!!!!!!!!!!!!!
z.rg = function(a, b) {var c, d, b = b || "";switch (a) {case "main_domain_nocdn":
...

3、下载本地资源

所谓本地资源,就是在使用地图时需要用到的一些模块(module),比如图层类,标记类,控件类。

当你在地图中用到这些模块时,它会自动加载,因此我们需要先把这些模块的js文件下载下来,保存到本地。

这些模块有几十个之多,我们这里并不都存本地,而是用到哪个下载哪个,那么如何知道用到了哪个模块呢?

  • 首先,在 bmap_offline_api_min.js 文件中,用 &mod= 定位到下面的代码,然后加一行代码将用到的模块打印出来:
load: function(a, b, c) {var d = this.ib(a);if (d.Bd == this.Fj.cq) c && b();else {if (d.Bd == this.Fj.pG) {this.lK(a);this.zN(a);var e = this;e.DC == q && (e.DC = o, setTimeout(function() {for (var a = [], b = 0, c = e.Pd.Fn.length; b < c; b++) {var d = e.Pd.Fn[b],l = "";ia.Ly.fK(d) ? l = ia.Ly.get(d) : (l = "", a.push(d + "_" + Rb[d]));e.Pd.Tv.push({TM: d,KE: l})}e.DC = q;e.Pd.Fn.length = 0;//!!!!!!!!!!!!!!!!!!!!console.log(a);   //!!!!!打印所需模块,这很重要//!!!!!!!!!!!!!!!!!!!!0 == a.length ? e.XK() : oa(e.iG.$P + "&mod=" + a.join(","))0 == a.length ? e.UK() : Qb("js/getmodules2.0.js")},1));d.Bd = this.Fj.JP}d.Ru.push(b)}
},
  • 然后,我们在需要使用地图的vue页面里,按照官方文档正常使用:(具体功能去官网找dome示例即可)
mounted(){this.$nextTick(() => {// 百度地图var map = new BMap.Map("container");var point = new BMap.Point(106.550963, 29.572012);map.centerAndZoom(point, 12);//设置定位点的弹跳动画var marker = new BMap.Marker(point);  // 创建标注map.addOverlay(marker);               // 将标注添加到地图中marker.setAnimation(BMAP_ANIMATION_BOUNCE); //跳动的动画map.enableScrollWheelZoom(true);//添加工具条比例尺控件var top_left_control = new BMap.ScaleControl({anchor: BMAP_ANCHOR_TOP_LEFT});// 左上角,添加比例尺var top_left_navigation = new BMap.NavigationControl();  //左上角,添加默认缩放平移控件var top_right_navigation = new BMap.NavigationControl({anchor: BMAP_ANCHOR_TOP_RIGHT, type: BMAP_NAVIGATION_CONTROL_SMALL}); //右上角,仅包含平移和缩放按钮map.addControl(top_left_control);map.addControl(top_left_navigation);map.addControl(top_right_navigation);})
},

特别注意:如果你要在进入页面就初始化地图,最好像上面那样,放在 mounted 生命函数的 this.$nextTick(() => {}) 里,以确保地图容器 #container 元素渲染完成,不然有可能因为初始化时地图容器还未渲染而报错:

刷新这个vue页,关注控制台,就能看到要实现这些地图功能所需要的模块名,是个数组集合,如下图,我这里需要"control_ff1mc0", "navictrl_wxtn3y"两个模块:

  • 这样获得模块文件
    这个链接 http://api0.map.bdimg.com/getmodules?v=2.0&t=20140707&mod=infowindow_omcokh,将其中 &mod= 之后的参数替换成我们打印出来的模块名,比如:
    http://api0.map.bdimg.com/getmodules?v=2.0&t=20140707&mod=control_ff1mc0
    http://api0.map.bdimg.com/getmodules?v=2.0&t=20140707&mod=navictrl_wxtn3y
    分别访问上述链接,就可以看到模块文件代码:
  • 在static文件夹下新建modules文件夹来存放即将下载的模块文件:

    新建以模块名命名的js文件,将模块文件代码粘贴到响应模块js文件里。这样需要的模块文件就下载好了。有几个模块下载几个文件:

4、引用本地资源

在上面步骤打印模块名的地方,做如下修改:

load: function(a, b, c) {var d = this.ib(a);if (d.Bd == this.Fj.cq) c && b();else {if (d.Bd == this.Fj.pG) {this.lK(a);this.zN(a);var e = this;e.DC == q && (e.DC = o, setTimeout(function() {for (var a = [], b = 0, c = e.Pd.Fn.length; b < c; b++) {var d = e.Pd.Fn[b],l = "";ia.Ly.fK(d) ? l = ia.Ly.get(d) : (l = "", a.push(d + "_" + Rb[d]));e.Pd.Tv.push({TM: d,KE: l})}e.DC = q;e.Pd.Fn.length = 0;console.log(a);   //!!!!!!打印所需模块// 0 == a.length ? e.XK() : oa(e.iG.$P + "&mod=" + a.join(","))// 0 == a.length ? e.UK() : Qb("js/getmodules2.0.js")// !!!!!!!!!!!!!!!!!!!!!!!!引用本地下载好的模块文件资源if( a.length > 0 ){for(let i=0; i<a.length;i++){let mf = './static/modules/'+a[i]+'.js';oa( mf );console.log('加载模块文件:'+mf); //IE error}} else {e.XK()}// !!!!!!!!!!!!!!!!!!!!!},1));d.Bd = this.Fj.JP}d.Ru.push(b)}
},

现在就能成功加载模块资源了。
这里要注意路径问题,如果路径不对,找不到模块文件,会报错:

三、加载瓦片改为本地离线瓦片

离线瓦片可以理解为地图离线包,没有它,离线地图是无法显示的。

1、存储目录

首先,在 static 目录下新建文件夹 tiles 来存放瓦片:

2、下载瓦片

用水经注或者太乐地图下载器下载瓦片,我用太乐。

选择百度

下载 -> 选择行政区划,选完了之后该区域就会出现ufo图标

点击图标,选择 地图

选择直接保存瓦片后,存储标准选择百度瓦片,存储格式会自动选择 .png。然后选择级别之后确定即可:
级别就是调用百度地图api处设置的缩放级别:

下载完成后可在这里查看:
找到存储目录:我这里下载了重庆12级的瓦片,所有的瓦片就存储在了12这个文件夹下

将12这个文件夹整个复制到项目static/tiles目录下

你会发现除了下载了12级,还下载了9、10、11级,因为离线的关系,在地图上进行缩放操作到11级,但是如果没有11级的瓦片,地图就什么都不显示。所以如果想要缩放多少级,这些级别的瓦片必须都下载到本地。

3、瓦片配置文件

static目录下新建mp_load.js文件,定义瓦片路径及瓦片格式即地图api的主目录:

我们的瓦片是png格式的:

var bmapcfg = {'imgext'      : '.png',   //瓦片图的后缀  根据需要修改,一般是 .png .jpg'tiles_dir'   : '',       //普通瓦片图的地址,为空默认在tiles/ 目录
};
var scripts = document.getElementsByTagName("script");
var JS__FILE__ = scripts[scripts.length - 1].getAttribute("src");  //获得当前js文件路径
bmapcfg.home = JS__FILE__.substr(0, JS__FILE__.lastIndexOf("/")+1); //地图API主目录

然后在API文件之前引入该配置文件:

4、修改加载瓦片路径

bmap_offline_api_min.js 文件中,可以用 getTilesUrl 多找几次,定位到下面代码:

Yc.getTilesUrl = function(a, b, c) {var d = a.x,a = a.y,e = Qb("normal"),f = 1,c = Xc[c];this.map.Ix() && (f = 2);d = this.map.eb.Bw(d, b).ds;return (Wc[Math.abs(d + a) % Wc.length] + "?qt=vtile&x=" + (d + "").replace(/-/gi, "M") + "&y=" + (a + "").replace(/-/gi, "M") + "&z=" + b + "&styles=" + c + "&scaler=" + f + (6 == x.da.la ? "&color_dep=32&colors=50": "") + "&udt=" + e).replace(/-(\d+)/gi, "M$1")
}

修改如下:

Yc.getTilesUrl = function(a, b, c) {var d = a.x,a = a.y,e = Qb("normal"),f = 1,c = Xc[c];// this.map.Ix() && (f = 2);// d = this.map.eb.Bw(d, b).ds;// return (Wc[Math.abs(d + a) % Wc.length] + "?qt=vtile&x=" + (d + "").replace(/-/gi, "M") + "&y=" + (a + "").replace(/-/gi, "M") + "&z=" + b + "&styles=" + c + "&scaler=" + f + (6 == x.da.la ? "&color_dep=32&colors=50": "") + "&udt=" + e).replace(/-(\d+)/gi, "M$1")//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!let tdir = bmapcfg.tiles_dir.length>0?bmapcfg.tiles_dir:bmapcfg.home + "tiles";console.log(tdir + "/" + b + "/" + d + "/" + a + bmapcfg.imgext)return tdir + "/" + b + "/" + d + "/" + a + bmapcfg.imgext; // 使用本地的瓦片//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
};

在这里可将调用瓦片的地址打印出来看看是否正确:


如果瓦片存在,且路径正确,就能正常显示地图了。

ps:地图不能显示出来,是瓦片相关有问题
地图的功能不能实现,是模块相关有问题

这里在 mp_load.js 里已经取到了主路径,可以将之前加载模块(三 - 4)处代码修改成:(不修改也可)

四、关于离线

离线并不是指断网,而是指只连内部局域网,表现在你无法访问百度,但是本地跑项目localhost的页面是能展示的。
想调试的话可以将本地的ip改为你知道的内网中一个计算机的ip。

五、关于地图下载器

1、免费/付费

  • 太乐
    太乐地图下载器在没有付费的情况下,最高只能下载12级,而且文件数量有限制,也就是说如果你选择的区域很大,可能连12级都无法下载,比如这里,我要下载中国地图,只能下载到第8级:

    而且下载下来的瓦片会有很大很夸张的水印:

    但是,如果你买了vip,那就没有任何限制了,具体收费情况我没问
  • 水经注
    我没用水经注来说明,是因为水经注下载器,如果没有付费,下载不了瓦片。水经注的购买费用大概800元,买了后没有限制,一直可用。

2、瓦片文件的大小

这是中国地图瓦片,可以看到第11级就1G了,16级1T,17级4T。如果你的地图需要带缩放功能,就吧这些大小累加,几T吧~~

来感受下11级的缩放程度,根本不够用

15级的凑合:

17级:

web百度离线地图开发(详细教程)2019相关推荐

  1. 【web百度离线地图开发】原生实现百度地图离线版速览

    需求如下,在基于在线地图的基础上展现离线地图 //在线用以下插件展示"vue-baidu-map": "^0.21.22", vue中展示离线地图 第一步:把配 ...

  2. Vue-cli3实现web百度离线地图(v3.0)开发

    需求 实现基于Vue-cli3的web百度离线地图(v3.0)开发 Vue-cli3,目录如下,注意:需要把地图相关的文件放在public下,vue-cli2需要放在static下!!! 参考 主要参 ...

  3. 百度离线地图开发,node实现地图瓦片下载

    最近有个Web项目要用离线地图,项目是在内网环境,找了很多资料,踩了很多坑,好在已经实现了,下面把资料整理一下. 首先是百度离线地图开发包,原文地址是http://www.xiaoguo123.com ...

  4. 百度离线地图开发教程?

    离线地图分为两种:一种叫"金字塔瓦片"数据,一种叫"矢量地图数据".我们看的在线地图比如,百度,谷歌,高德等等网页上的地图,都是金字塔瓦片:另外一种是手机上用来 ...

  5. LINUX系统下部署百度离线地图开发API

    Bigemap离线地图发布服务器 for Linux SDK下载地址:http://www.bigemap.com/reader/download/detail2019041117.html 当前版本 ...

  6. Java --- Web 百度在线地图开发

    1 准备工作 申请 ak (百度地图API 密钥): 2  查看百度地图坐标工具(坐标拾取器) http://api.map.baidu.com/lbsapi/getpoint/index.html ...

  7. php离线地图,如何发布百度离线地图及二次开发API

    相关教程: 1.说明 离线地图开发环境支持谷歌地图.百度地图.高德地图等等所有常用地图类型,支持在局域网内的地图部署.二次开发. 2.实现 第一步:下载安装离线地图开发环境 下载安装好之后,启动软件, ...

  8. 8、 谷歌离线地图开发教程

    谷歌(百度.高德)离线地图开发环境搭建 发布时间:2018-01-17 版权: 1.说明 离线地图开发环境支持谷歌地图.百度地图.高德地图等等所有常用地图类型,支持在局域网内的地图部署.二次开发. 2 ...

  9. BIGEMAP谷歌(百度、高德)离线地图开发环境搭建

    谷歌(百度.高德)离线地图开发环境搭建 发布时间:2018-01-17 版权: 1.说明 离线地图开发环境支持谷歌地图.百度地图.高德地图等等所有常用地图类型,支持在局域网内的地图部署.二次开发. 2 ...

最新文章

  1. sklearn中cross_val_score、cross_val_predict的用法比较
  2. 软件项目版本号的命名规则及格式
  3. JVM - 实现自定义的ClassLoader就是这么简单
  4. 图像处理技术(二)滤波去噪
  5. MySQL日期处理-查询间隔数据
  6. polkit启动失败_linux某服务启动失败,提示Authorization not available. Check if polkit...问题解决...
  7. win10恢复出厂设置_电脑Win10系统恢复出厂设置
  8. 人工智能感知技术是机器人应用支撑技术之一
  9. jQuery 学习-样式篇(四):jQuery 设置和删除元素的属性
  10. 单个字段中根据条件剔除数据
  11. CS API 测试3
  12. tomcat设置JSessionID长度问题
  13. matlab 入门 实验,matlab入门实验.doc
  14. selenium docker
  15. It has been compressed and nested jar files must be stored without compression
  16. 红队攻防之PC端微信个人信息与聊天记录取证
  17. LiveGBS流媒体平台国标GB/T28181功能-国标流媒体服务平台作为上级接入海康大华华为宇视等下级平台及摄像头
  18. 最新php开发学习资料网盘下载
  19. html5 声控游戏,7款好玩的声控游戏,用声音征服世界!
  20. 电池充放电管理-锂电池充电过程及电路设计

热门文章

  1. 由“三姬分金”到“海盗分金”
  2. 上班一个月挣10万,居然全靠它...
  3. 2023-2028年中国燕麦奶行业市场预测与投资规划分析报告
  4. 什么是5G消息?有什么应用价值?如何开通服务?
  5. oracle安装界面空白,在windows 2012中安装oracle 12c R2界面空白挂起无响应CPU达到100%的问题...
  6. linux apache 配置文件位置,Apache主配置文件httpd.conf 详解
  7. 为什么不要把鸡蛋放在同一个篮子里?
  8. 木子-后端-随机验证码的各种实现方法
  9. 阅读笔记_一本书读懂财报
  10. 为什么很多人会觉得FPGA难学?