vue集合离线百度地图

vue.js百度地图api离线

发布于 1月9日

一、需求场景

所谓离线,大概都是项目在内网中使用,无法连接外网,所以需要开发离线地图功能。
在看以下步骤前,先提示这个vue项目是vue-cli生成的

二、开发步骤

1、通过API下载百度接口JS

访问此链接

打开会看到以下内容

在代码中找到
src=http://api.map.baidu.com/getscript?v=3.0&ak=biuHZmoAow03mjwThwt8f2whaf4mVdHf&services=&t=20191018171908
打开src里的链接,就可以获得百度api的js代码

2、js代码清洗,保存

在在线JSON校验工具,将上面的代码,格式化,以便下面查看与修改。

然后新建js文件,将格式化后的代码粘贴进去,命名为baidu-api.js

再然后将此js文件放在vue项目中,我的放在了static下

最后,在vue项目的启动入口index.html的head中引入这个js

3、修改API文件

3.1、在baidu-api.js文件中,用Math.random()全局查找几次,定位到以下代码位置:

(以下代码会在百度更新有些出入,但基本样式不变,找相似)

function pa(a, b) {if (b) {var c = (1E5 * Math.random()).toFixed(0);D._rd["_cbk" + c] = function(a) {b && b(a);delete D._rd["_cbk" + c]};a += "&callback=BMap._rd._cbk" + c}var e = O("script", {type: "text/javascript"});e.charset = "utf-8";e.src = a;e.addEventListener ? e.addEventListener("load", function(a) {a = a.target;a.parentNode.removeChild(a)}, t) : e.attachEvent && e.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(e);e = s}, 1)
};

到此步,默认你已找到!!!
然后修改上面的代码,对HTTP拦截,不进行外部访问,只需在最开始添加一行:

if (/^http/.test(a)) return;

就是如下样式

function pa(a, b) {//if (/^http/.test(a)) return; // !!!!!这里加判断,如果是调用外部资源就退出去//if (b) {var c = (1E5 * Math.random()).toFixed(0);D._rd["_cbk" + c] = function(a) {b && b(a);delete D._rd["_cbk" + c]};a += "&callback=BMap._rd._cbk" + c}var e = O("script", {type: "text/javascript"});e.charset = "utf-8";e.src = a;e.addEventListener ? e.addEventListener("load", function(a) {a = a.target;a.parentNode.removeChild(a)}, t) : e.attachEvent && e.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(e);e = s}, 1)
};

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

在baidu-api.js文件中,用url.domain.main_domain_cdn.baidu[0]全局多查找几次,定位到下面的代码:

D.Nt = window.HOST_TYPE || "0";
D.url = D.I_[D.Nt];
D.Uo = D.url.proto + D.url.domain.baidumap + "/";
D.Cd = D.url.proto + ("2" == D.Nt ? D.url.domain.main_domain_nocdn.other : D.url.domain.main_domain_nocdn.baidu) + "/";
D.oa = D.url.proto + ("2" == D.Nt ? D.url.domain.main_domain_cdn.other[0] : D.url.domain.main_domain_cdn.baidu[0]) + "/";
D.Ri = D.url.proto + D.url.domain.main_domain_cdn.webmap[0] + "/";

然后将
D.Ri = D.url.proto + D.url.domain.main_domain_cdn.webmap[0] + "/"
改为 D.Ri = '' :

如下样式:

D.Nt = window.HOST_TYPE || "0";
D.url = D.I_[D.Nt];
D.Uo = D.url.proto + D.url.domain.baidumap + "/";
D.Cd = D.url.proto + ("2" == D.Nt ? D.url.domain.main_domain_nocdn.other : D.url.domain.main_domain_nocdn.baidu) + "/";
D.oa = D.url.proto + ("2" == D.Nt ? D.url.domain.main_domain_cdn.other[0] : D.url.domain.main_domain_cdn.baidu[0]) + "/";
///
D.Ri = '';
///
D.Yh = function(a, b) {var c, e, b = b || "";

3.3、下载本地资源

所谓本地资源,就是在使用地图时需要用到的一些模块(module),比如图层类,标记类,控件类。
当你在地图中用到这些模块时,它会自动加载,因此我们需要先把这些模块的js文件下载下来,保存到本地。
这些模块有几十个之多,我们这里并不都存本地,而是用到哪个下载哪个,那么如何知道用到了哪个模块呢?

首先,在 baidu-api.js 文件中,用 &mod= 定位到下面的代码,然后加一行代码将用到的模块打印出来:

load: function(a, b, c) {var e = this.lb(a);if (e.Ke == this.tj.Bp) c && b();else {if (e.Ke == this.tj.BF) {this.nJ(a);this.EM(a);var f = this;f.OB == t && (f.OB = p, setTimeout(function() {for (var a = [], b = 0, c = f.Pd.Vm.length; b < c; b++) {var e = f.Pd.Vm[b],n = "";ja.Zx.iJ(e) ? n = ja.Zx.get(e) : (n = "", a.push(e + "_" + Tb[e]));f.Pd.qv.push({VL: e,UD: n})}f.OB = t;f.Pd.Vm.length = 0;//!!!!!!!!!!!!!!!!!!!!console.log("打印所需模块");console.log(a);   //!!!!!打印所需模块,这很重要//!!!!!!!!!!!!!!!!!!!!//0 == a.length ? f.XJ() : pa(f.tF.$O + "&mod=" + a.join(","))//引用本地下载好的模块文件资源if( a.length > 0 ){for(let i=0; i<a.length;i++){let mf = './static/modules/'+a[i]+'.js';pa( mf );console.log('加载模块文件:'+mf); //IE error}} else {f.XK()}//}, 1));e.Ke = this.tj.RO}

然后,我们在需要使用地图的vue页面里,按照官方文档正常使用:

<template><div id='MapBox'><div  class='baiduMap' id='mapShow' ref="mapShow"></div></div>
</template>
<script>export default {name:'baiduMap',data() {return{map: undefined,overView: undefined,marker: undefined,BMap: undefined,}},methods:{baiduMap(){debuggerthis.BMap = BMap;// 创建地图实例this.map = new BMap.Map("mapShow");// 创建点坐标let point = new BMap.Point(118.8035, 32.0658);//创建标注this.marker=new BMap.Marker(point);//缩略地图控件。this.overView=new BMap.OverviewMapControl({isOpen: true});//添加控件this.map.addControl(this.overView);//添加一个标注this.map.addOverlay(this.marker);// 初始化地图,设置中心点坐标和地图级别this.map.centerAndZoom(point, 12);//this.map.setCurrentCity("南京");//开启鼠标滚轮缩放this.map.enableScrollWheelZoom(true);}},mounted(){this.$nextTick(() => {this.baiduMap();})}}
</script>
<style>#MapBox {width: 100%;height: 100%;padding: 10px;position: relative;}/* 地图 */.baiduMap{height: 100%;width: 100%;}/* 去除地图上,左下字体标注 */.anchorBL{display:none;}
</style>

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

从上继续:
刷新这个vue页,关注控制台,就能看到要实现这些地图功能所需要的模块名,是个数组集合,如下图,我这里需要以下十一个模块:

下载api依赖模块的地址

http://api.map.baidu.com/getm...

通过上面的地址,只需要更换mod后面的值就可以找到需要的模块
然后在static下建一个modules文件夹来存放即将下载的模块文件

然后新建以打印出的模块为命名的js,将通过地址搜索到的js复制到此js文件里。这样模块文件就下载好了。

3.4、引用本地资源

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

load: function(a, b, c) {var e = this.lb(a);if (e.Ke == this.tj.Bp) c && b();else {if (e.Ke == this.tj.BF) {this.nJ(a);this.EM(a);var f = this;f.OB == t && (f.OB = p, setTimeout(function() {for (var a = [], b = 0, c = f.Pd.Vm.length; b < c; b++) {var e = f.Pd.Vm[b],n = "";ja.Zx.iJ(e) ? n = ja.Zx.get(e) : (n = "", a.push(e + "_" + Tb[e]));f.Pd.qv.push({VL: e,UD: n})}f.OB = t;f.Pd.Vm.length = 0;//!!!!!!!!!!!!!!!!!!!!console.log("打印所需模块");console.log(a);   //!!!!!打印所需模块,这很重要//!!!!!!!!!!!!!!!!!!!!//0 == a.length ? f.XJ() : pa(f.tF.$O + "&mod=" + a.join(","))//引用本地下载好的模块文件资源if( a.length > 0 ){for(let i=0; i<a.length;i++){let mf = './static/modules/'+a[i]+'.js';pa( mf );console.log('加载模块文件:'+mf); //IE error}} else {f.XK()}//}, 1));

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

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

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

1、瓦片嵌入在项目中引用

1.1、下载瓦片

网上提供了水经注或者太乐地图下载器下载瓦片,介绍我用的太乐
太乐地图下载器

选择百度

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

点击图标,选择 地图:

选择直接保存瓦片后,存储标准选择百度瓦片,存储格式会自动选择 .png。然后选择级别之后确定即可:

级别就是调用百度地图api处设置的缩放级别:

下载完成后可在这里查看:

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

将所有瓦片文件夹整个复制到项目static/tiles目录下

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

1.2、瓦片配置文件

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文件之前引入该配置文件:

<script type="text/javascript" src="static/mp\_load.js"\></script\>

1.3、修改API文件加载瓦片路径

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

Hd.getTilesUrl = function(a, b, c) {var e = a.x,a = a.y,f = Sb("normal"),g = 1,c = Gd[c];this.map.Yw() && (g = 2);e = this.map.oh.Uv(e, b).Ol;return (Fd[Math.abs(e + a) % Fd.length] + "?qt=vtile&x=" + (e + "").replace(/-/gi, "M") + "&y=" + (a + "").replace(/-/gi, "M") + "&z=" + b + "&styles=" + c + "&scaler=" + g + (6 == z.ga.ma ? "&color_dep=32&colors=50" : "") + "&udt=" + f).replace(/-(\d+)/gi, "M$1")
};

修改如下:

Hd.getTilesUrl = function(a, b, c) {var e = a.x,a = a.y,f = Sb("normal"),g = 1,c = Gd[c];// this.map.Yw() && (g = 2);// e = this.map.oh.Uv(e, b).Ol;// return (Fd[Math.abs(e + a) % Fd.length] + "?qt=vtile&x=" + (e + "").replace(/-/gi, "M") + "&y=" + (a + "").replace(/-/gi, "M") + "&z=" + b + "&styles=" + c + "&scaler=" + g + (6 == z.ga.ma ? "&color_dep=32&colors=50" : "") + "&udt=" + f).replace(/-(\d+)/gi, "M$1")//加载本地瓦片let tdir = bmapcfg.tiles_dir.length>0?bmapcfg.tiles_dir:bmapcfg.home + "tiles";console.log(tdir + "/" + b + "/" + e + "/" + a + bmapcfg.imgext);return tdir + "/" + b + "/" + e + "/" + a + bmapcfg.imgext; // 使用本地的瓦片//
};

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


如果瓦片存在,且路径正确,就能正常显示地图了。
ps:地图不能显示出来,是瓦片相关有问题
地图的功能不能实现,是模块相关有问题
这里在 mp_load.js 里已经取到了主路径,可以将之前加载模块处代码修改成:

1.4、关于地图下载器

太乐

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

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

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

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

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

15级的凑合:

17级:

--------------------------------------------特别注意------------------------------------------
作为一个技术猿,怎会花钱去买,所以经过不懈努力,找到了可以下载完整瓦片的地图下载器,作为题主,自然要拿出来分享,通过以下内容,到百度云下载即可:
https://pan.baidu.com/s/1Mxvf...
提取码:
ojji

----------------------新增---------------------------
如果通过上面的软件找不到保存位置的话,我下面先提供一个1-17层的切片,先供使用
https://pan.baidu.com/s/1vdND...
提取码:
xhq1

如果可以帮助到你,麻烦小手点个赞,走一波爱心支持,小生在此谢过

2、通过Nginx反向代理在项目中引用瓦片

转载链接

vue集合离线百度地图相关推荐

  1. Vue中使用百度地图做路径分析并根据起终点坐标模拟道路里程桩

    1.我们先要在vue中引入百度地图的API 第一步:在vue中的index.html文件中加上一个script标签: <script type="text/javascript&quo ...

  2. vue 页面使用百度地图

    前言 vue 3.x 百度地图JavaScript API GL v1.0 百度地图的源码编辑器:http://lbs.baidu.com/jsdemo.htm#webgl0_0 本文代码在百度地图的 ...

  3. Vue项目使用百度地图——经纬度地图组件的封装及使用

    1 前言 要在vue项目使用百度地图api,首先应做以下配置 (1)index.html index.html添加script <script src="http://api.map. ...

  4. qaxwidget传递参数到html,记一次QT使用QAxWidget打开.html文件调用显示离线百度地图不能缩放,自定义图片不能显示解决方法...

    主要问题: 一开始用的是在线的,都没有什么问题,自定义图片均可以显示,可是后面试了一下离线百度地图,在qt中运行打开.html文件和在电脑上面直接双击打开此文件显示是有差别的,在qt生成的程序中,地图 ...

  5. vue项目引入百度地图BMapGL鼠标绘制和BMap辅助工具

    目录 引言 1.引用百度地图 2.在项目中使用百度地图 2-1.页面结构部分 2-2.js逻辑部分 3-1.页面结构部分 Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架.它旨 ...

  6. vue中调用百度地图 获取经纬度

    项目中,需要实现获取当前位置的经纬度,或者搜索某个位置并获取经纬度信息,我使用的的是vue,地图使用的是百度地图. 默认自动获取当前位置经纬度 拖动小红标 获取经纬度 关键词 查询获取经纬度 前期准备 ...

  7. Vue中使用百度地图

    安装 npm $ npm install vue-baidu-map --save cdn <script src="https://unpkg.com/vue-baidu-map&q ...

  8. vue + echarts + ( bmap) 百度地图 实现公交、骑行、车辆 轨迹图

    vue + echarts + ( bmap) 百度地图 实现公交.骑行.车辆 轨迹图 最终目标 最终目标:个性化的实现公交路线图 先看看效果以免白看一场,如果你是想实现类似的效果可以继续往下看 码起 ...

  9. VUE中使用百度地图BaiduMap

    VUE中使用百度地图BaiduMap 以前在html页中使用了echart,做了很多图表,也集成了百度地图,效果很好.最近,开始研究vue加 .net core的框架,所以也想把echart和百度地图 ...

最新文章

  1. 区块链论文: Bitcoin-NG: A Scalable Blockchain Protocol
  2. ASP.NET MVC使用Bootstrap系统(2)——使用Bootstrap CSS和HTML元素
  3. 采用NAND Flash设计存储设备的挑战在哪里?
  4. 【错误记录】Groovy 工程编译报错 ( java.lang.NoClassDefFoundError: org/apache/tools/ant/util/ReaderInputStream )
  5. Excel 工作表,单元格破解密码宏
  6. python爬微博粉丝最多的明星_2020明星微博粉丝排行榜,谁的粉丝数量最多呢
  7. P-Associated-URI
  8. python统计字典中元素个数_Python计数器 | collections.Counter
  9. java2实用教程 第5版 课本案例
  10. mac数字键盘错乱_苹果本键盘按键错位错乱是为什么?
  11. 论文阅读笔记 | Enemy At the Gateways:Censorship-Resilient Proxy Distribution Using Game Theory(NDSS 2019)
  12. 计算机关闭应用窗口的方法,电脑怎么从后台关闭程序应用
  13. Linux之日志系统
  14. 电子电路学习笔记(5)——三极管
  15. Kali Linux 使用远程桌面连接——xrdpxfce
  16. 两台Exadata搭建RAC+DG
  17. python3 高斯函数
  18. IDesign C#编程规范(二)
  19. C4D R19学习之 001界面认识
  20. 武汉首秀!看近百名开发者碰撞火花,超多干货分享丨Cocos Star Meetings

热门文章

  1. 慢腾腾的Quartus prime16.0加快编译速度
  2. 五个强盗分金币的问题分析(博弈论)
  3. 字典树 ZJM 与生日礼物
  4. 利用html做一个3D 图片动态效果
  5. 单页双曲面 matlab,如何画双叶双曲面
  6. 【小5聊】C#一键设置桌面壁纸同时叠加今天工作或备注内容到壁纸上(windows窗体篇)
  7. 重读数据结构之爬楼梯问题(动态规划)
  8. 中级财管电脑操作不会用计算机,很全面!2018年中级无纸化考试财管公式输入方法及计算器操作说明...
  9. glibc 知:手册06:字符集处理
  10. 一位MIT计算机博士对数学知识的思考