vue集合离线百度地图

一、需求场景

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

二、开发步骤

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

访问此链接

打开会看到以下内容
image.png

在代码中找到
src=http://api.map.baidu.com/getscript?v=3.0&ak=biuHZmoAow03mjwThwt8f2whaf4mVdHf&services=&t=20191018171908
打开src里的链接,就可以获得百度api的js代码
vue集合离线百度地图_第1张图片

2、js代码清洗,保存

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

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

再然后将此js文件放在vue项目中,我的放在了static/js下
vue集合离线百度地图_第2张图片

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

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

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



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

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

下载api依赖模块的地址

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

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

然后新建以打印出的模块为命名的js,将通过地址搜索到的js复制到此js文件里。这样模块文件就下载好了。
vue集合离线百度地图_第4张图片

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

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

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

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

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

1.1、下载瓦片

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

选择百度
vue集合离线百度地图_第5张图片

下载 -> 选择行政区划,选完了之后该区域就会出现ufo图标
vue集合离线百度地图_第6张图片

点击图标,选择 地图:
vue集合离线百度地图_第7张图片

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

下载完成后可在这里查看:
vue集合离线百度地图_第8张图片

找到存储目录:我这里下载了重庆12级的瓦片,所有的瓦片就存储在了12这个文件夹下
vue集合离线百度地图_第9张图片

将所有瓦片文件夹整个复制到项目static/tiles目录下
vue集合离线百度地图_第10张图片
你会发现除了下载了12级,还下载了9、10、11级,因为离线的关系,在地图上进行缩放操作到11级,但是如果没有11级的瓦片,地图就什么都不显示。所以如果想要缩放多少级,这些级别的瓦片必须都下载到本地。

1.2、瓦片配置文件

static目录下新建mp_load.js文件,定义瓦片路径及瓦片格式即地图api的主目录:
vue集合离线百度地图_第11张图片

我们的瓦片是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文件之前引入该配置文件:


                    
                    

你可能感兴趣的:(vue.js,百度地图api,离线)