一、为什么有离线地图的存在

项目要在局域网内使用,也就是我们所说的在内网中使用,无法连接外网,所以需要开发离线地图功能。
(在看以下步骤前,先提示这个vue项目是vue-cli生成的,并且你需要确保你的在线地图是成功的,在线地图如果不知道怎么做,可以看我另一篇博客:在线地图)

二、离线百度地图开发步骤

其实理解了离线百度地图,它的使用很简单,就是把在线百度地图的一些js文件下载到本地,再引用一下就可以啦

1、获取百度地图api的js代码

访问此链接
http://api.map.baidu.com/api?v=3.0&ak=biuHZmoAow03mjwThwt8f2whaf4mVdHf
这里特别注意一下,不是说直接用这个链接,这里只是给出了步骤,你需要将ak替换为你自己的(申请ak,点击这里),再进行如下步骤!!!
多说一句:申请ak时选择浏览器端哦!!!
打开会看到以下内容

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

2、js代码格式化,保存

在代码格式化工具中,将上面的代码格式化,以便查看和修改。
2021-08-04 更新start:这里代码格式化可以直接在浏览器上进行,步骤如图


2021-08-04 更新end

然后新建js文件,将格式化后的代码粘贴进去,命名为baidu-api.js
再然后将此js文件放在vue项目中,我的放在了static下

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

3、修改百度地图API文件

3.1 下载本地资源

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

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

load: function(a, b, c) {var e = this.ob(a);if (e.Le == this.Bj.Mp) c && b();else {if (e.Le == this.Bj.bG) {this.UJ(a);this.hN(a);var f = this;f.fC == t && (f.fC = p, setTimeout(function() {for (var a = [], b = 0, c = f.Qd.fn.length; b < c; b++) {var e = f.Qd.fn[b],n = "";ia.oy.PJ(e) ? n = ia.oy.get(e) : (n = "", a.push(e + "_" + Bc[e]));f.Qd.Cv.push({zM: e,rE: n})}f.fC = t;f.Qd.fn.length = 0;console.log("打印所需模块") console.log(a)//打印所需模块,这很重要!!!!!!//console.log(f.TF.IP)//打印下面一行oa()里面的值,你需要通过这个链接下载模块--2021-08-04// 0 == a.length ? f.DK() : oa(f.TF.IP + "&mod=" + a.join(","))//引用本地下载好的模块文件资源if (a.length > 0) {for (let i = 0; i < a.length; i++) {let mf='./static/modules/'+a[i]+'.js'//let mf = bmapcfg.home + 'modules/' + a[i] + '.js';oa(mf);console.log('加载模块文件:' + mf) //IE error}} else {f.DK()//这里的函数DK(),根据你上面注释的那一行函数名而定}},1));e.Le = this.Bj.xP}e.yu.push(b)}},

3.2 在baidu-api.js文件中,用Math.random()全局查找几次(我的是第5次),定位到以下代码位置:

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

function oa(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 = L("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 = q},1)};

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

if (/^http/.test(a)) return; //如果是调用外部资源就退出去

如下:

function oa(a, b) {//添加一行,对http拦截,不进行外部访问///if (/^http/.test(a)) return; //如果是调用外部资源就退出去-2020.7.29//这里的a其实就是3.1步骤中oa(mf)里的mf,即你下载的模块路径-2021-08-04/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 = L("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 = q},1)};

3.3 设置引用本地资源路径

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

 D.Zt = window.HOST_TYPE || "0";D.url = D.s0[D.Zt];D.ep = D.url.proto + D.url.domain.baidumap + "/";D.nd = D.url.proto + ("2" == D.Zt ? D.url.domain.main_domain_nocdn.other: D.url.domain.main_domain_nocdn.baidu) + "/";D.oa = D.url.proto + ("2" == D.Zt ? D.url.domain.main_domain_cdn.other[0] : D.url.domain.main_domain_nocdn.baidu) + "/";D.Yi = D.url.proto + D.url.domain.main_domain_cdn.webmap[0] + "/";

然后将
D.Yi = D.url.proto + D.url.domain.main_domain_cdn.webmap[0] + “/”;
改为 D.Yi = ‘’ ;
如下:

D.Zt = window.HOST_TYPE || "0";D.url = D.s0[D.Zt];D.ep = D.url.proto + D.url.domain.baidumap + "/";D.nd = D.url.proto + ("2" == D.Zt ? D.url.domain.main_domain_nocdn.other: D.url.domain.main_domain_nocdn.baidu) + "/";D.oa = D.url.proto + ("2" == D.Zt ? D.url.domain.main_domain_cdn.other[0] : D.url.domain.main_domain_nocdn.baidu) + "/";// D.Yi = D.url.proto + D.url.domain.main_domain_cdn.webmap[0] + "/";D.Yi = '';

然后,我们在需要使用地图的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页,关注控制台,就能看到要实现这些地图功能所需要的模块名,是个数组集合,如下图,我这里需要以下17个模块:

通过下面的地址,只需要更换mod后面的值就可以找到需要的模块
下载api依赖模块的地址:点击这里下载依赖模块

2021-08-04 更新start
可能有些小伙伴通过上面的链接获取到的是空,这里更新下
在3.1步骤中,你可以看到这样一句话

0 == a.length ? f.DK() : oa(f.TF.IP + "&mod=" + a.join(","))

f.TF.IP打印出来,在后面加上&mod=,后面再加上你要下载的模块名称即可

2021-08-04 更新end

在static下建一个modules文件夹来存放即将下载的模块文件
然后新建以打印出的模块为命名的js,将通过地址搜索到的js复制到此js文件里。这样模块文件就下载好了。

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

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

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

1、瓦片嵌入在项目中的应用

1.1下载瓦片

太乐地图下载器----由于我电脑目前装不上这个软件,没有亲自下载,该过程暂时省略,后续会补上的哈
这里就先默认小伙伴们都已经拿到离线地图的图片资源了!!!
将所有瓦片文件夹整个复制到项目static/tiles目录下

因为离线的关系,在地图上进行缩放操作,想要缩放多少级,这些级别的瓦片必须都下载到本地。

1.2 瓦片配置文件

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

我的瓦片是png格式的:

var bmapcfg={'imgext':'.png',//瓦片图的后缀  根据需要修改  一般.jpg  .png'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主目录,我这里打印出来为./static/

然后,在vue项目的启动入口index.html的head中引入map_load.js文件,要在baidu-api.js文件之前引入该配置文件:

1.3 修改baidu-api.js文件,加载瓦片路径

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

pe.getTilesUrl = function(a, b, c) {var e = a.x,a = a.y,f = Tb("normal"),g = 1,c = oe[c];this.map.lx() && (g = 2); e = this.map.$e.fw(e,b).Zl; return (ne[Math.abs(e + a) % ne.length] + "?qt=vtile&x=" + (e + "").replace(/-/gi,"M") + "&y=" + (a + "").replace(/-/gi, "M") + "&z=" + b + "&styles=" + c + "&scaler=" + g + (6 == A.fa.na ? "&color_dep=32&colors=50" : "") + "&udt=" + f + "&from=jsapi3_0").replace(/-(\d+)/gi,"M$1")};

修改如下:

pe.getTilesUrl = function(a, b, c) {var e = a.x,a = a.y,f = Tb("normal"),g = 1,c = oe[c];// this.map.lx() && (g = 2); // e = this.map.$e.fw(e,b).Zl; // return (ne[Math.abs(e + a) % ne.length] + "?qt=vtile&x=" + (e + "").replace(/-/gi,"M") + "&y=" + (a + "").replace(/-/gi, "M") + "&z=" + b + "&styles=" + c + "&scaler=" + g + (6 == A.fa.na ? "&color_dep=32&colors=50" : "") + "&udt=" + f + "&from=jsapi3_0").replace(/-(\d+)/gi,"M$1")//加载本地瓦片-2020.7.29let 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:我最初没有加模块文件,客户端直接调试时谷歌浏览器都没报错,相关功能也全部正常;但放到nginx中就凉啦,打印区会提示需要相应的模块文件哒)

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

 if (a.length > 0) {for (let i = 0; i < a.length; i++) {// let mf='./static/modules/'+a[i]+'.js'let mf = bmapcfg.home + 'modules/' + a[i] + '.js';debugger oa(mf);console.log('加载模块文件:' + mf) //IE error}} else {f.DK()}

到这里,离线地图就开发完成啦!

四、回答评论中常见的问题 2021-08-04 更新

1、Error in nextTick: “ReferenceError: BMap is not defined”

需要进行vue.config.js配置,详细见我另一篇文章:在线地图

2、地图瓦片对应不上,修改的getTilesUrl这个地方的a里面的x,y都是代表的什么


附上图给大家参考下,具体暂时没研究

3、Uncaught SyntaxError: Unexpected token ‘<’,

这里列一下小伙伴们出现并且已经解决的情况:
1、ak是你自己去百度官网申请的
2、申请ak时选择的是浏览器端
3、js等等的路径不正确也会有这个错
4、实在不行,参考问题5,还不行的话可能又是个新问题,可以一起讨论看看

4、下载的依赖模块js点开提示 We’re sorry but section doesn’t work properly without JavaScript enabled. Please enable it to continue.

这句话的意思是浏览器不支持javascript,但是不可能的,这不科学,所以一般都是js文件报错了,比如你想要获取js文件,但是响应头content-type却是html
解决方法参考:
这里需要看下加载的js文件资源名称是否为.js后缀,如果不是,找到加载该js路径的地方进行修改,详细步骤参考问题5

5、Uncaught SyntaxError: Unexpected token ‘<’ map_e1g5hy.js&v=3.0&seckey=undefined:1 ;

首先感谢这几位小伙伴,详细的报错引起了我的关注,因为我之前并没有出现这个问题,评论里有部分小伙伴在我提醒常见问题3中的解决方法后成功运行,我就一直以为是文件路径之类的问题,也没自己去试,近几天特别多小伙伴跟我提到这个问题,于是自己重新试了下,果然……就离谱啊,于是开始排查原因,这里省略一万只羊驼……
解决方法参考:
1、首先是这样的现象,报了一堆错,地图就展示了一张图,不能拖动也不能缩放,标记点也不出现(前提是这里的功能你都设置了),模块已经下载了,却还是打印,怎么刷新也不管用,如下

2、咱们点击map_e1g5hy.js&v=3.0&seckey=undefined:1会跳转到资源管理,现在我们会发现,明明是加载js,却显示index.html报错了,离谱


3、我们点击network,选择js,会发现content-type为html;点击preview,会出现问题4中描述的现象


4、我们点点其他js文件,发现js就要有js的样子嘛,map_e1g5hy.js&v=3.0&seckey=undefined:1你这整了一堆什么玩意儿,后缀还不是.js


5、这个其实就是我们加载模块时,模块资源加载路径出错了,我只要加载map_e1g5hy.js却给我整了map_e1g5hy.js&v=3.0&seckey=undefined:1,于是回到baidu-api.js,用 &mod=查找(步骤3.1),看到加载模块oa(mf),在下面最新的截图中是qa(mf),这里mf就是模块路径,一看写的对的呀,其实这不是我们的问题,嘎嘎,baidu-api.js会不定时更新,每个人都不一样,隔段时间也会不一样,大家看步骤吼(这里附上的图是最近会出问题的版本,跟上面步骤中的图参数会不一样,知道是这个函数就好),ctrl+点击qa,定位到qa(mf)函数,我们发现就是步骤3.2中限制调用外部资源的地方,然后我们发现官方给模块地址加上了"&v=3.0&seckey=" + pa这个玩意儿,其中pa是window.BMAP_SECKEY,最要命的是,这里的key还undefined!!!,对比之前的oa(mf)函数,我们发现的确是最新版本才出现的赋值,于是我们把它注释掉,再去刷新一下页面就ok啦!具体官方为什么会更新这一步,原因不详,后面知道了我再更新吧。

最后,这篇关于离线地图的步骤记录呢大部分都是参照vue集合离线百度地图这个作者的,再写一遍主要就是加深印象,也为了自己以后查阅方便,如有小伙伴不清楚怎么下载和使用太乐地图下载器,可以点这个链接查看哦
对于出现的问题,大家可以参考下,如有不当,欢迎指出,评论中出现新的问题,解决过后将及时更新

vue--百度地图之离线地图相关推荐

  1. 百度、高德离线地图SDK开发工具,局域网内离线地图开发环境

       相关下载:For Linux版本下载 快速搭建离线地图开发环境     局域网地图服务   离线地图数据服务  二次开发 一.软件介绍     BIGEMAP离线地图服务器,提供一站式搭建离线/ ...

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

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

  3. vue--百度地图之离线地图--大量标注点造成卡顿问题--海量点聚合性能优化

    如果你啥都不想看,只想解决问题,直接跳转–四.步骤 目录 一.需求 二.地图的引入.聚合点的使用 1.如图:引入百度地图和其他相关插件(按需引入,这些百度地图官网上都可以下载到) 2.初始化地图准备: ...

  4. 三维地图(3D地图)离线地图开发

    三维地图(3D地图)离线地图开发 发布时间:2020-03-03 版权:               1.如何搭建离线地图开发环境    视频教程               2.下载离线地图数据(金 ...

  5. 三维地图(3D地图)离线地图开发发布时间:2020-03-03 版权:

    三维地图(3D地图)离线地图开发 发布时间:2020-03-03 版权:               1.如何搭建离线地图开发环境    视频教程               2.下载离线地图数据(金 ...

  6. vue使用echarts引入离线地图(geo.json)并切换省市(以四川为例)可下钻

    首先安装echarts npm install echarts --save 1 然后再main.js中引入echarts import echarts from 'echarts' Vue.prot ...

  7. vue使用echarts引入离线地图(geo.json)并切换省市(以四川为例)

    首先安装echarts npm install echarts --save 然后再main.js中引入echarts import echarts from 'echarts' Vue.protot ...

  8. 百度android导航sd卡上,[转载]关于安卓4.4.2系统下,高德手机导航和百度手机导航离线地图在外置SD卡的...

    2014年4月三星向S4 I9500手机用户推送了安卓4.4.2系统更新.由于google安卓4.4系统对第3方应用程序读写外置SD卡的限制,导致搜狗离线及高德离线地图在外置SD卡的安装均出现无法访问 ...

  9. java gis离线地图_java离线地图web GIS制作

    因为项目需求,要做一个web地图,之前做过高德的在线地图,它提供了一系列的API,并且由于是国产的,所以开发起来比较容易,现在由于项目是内网使用的,所以需要使用离线地图,由此便开始了: Web GIS ...

最新文章

  1. 基于图像的三维模型重建——稠密点云重建
  2. 意大利物联网技术发展现状
  3. 【kafka】confluent_kafka重置offset
  4. Android Binder基本概念流程学习
  5. Apache Mahout 0.9、10.1、11. CardinalityException: Required cardinality 60 but got 29
  6. wms地图绘制工具_移情地图,了解用户需求的利器
  7. BugkuCTF-Crypto题告诉你个秘密
  8. 进程间内存共享问题[转]
  9. Redis解读持久化RDB和AOF原理
  10. 继续推荐几款VisualStudio的插件
  11. 八段锦八个动作名称_八段锦工间操“动”起来 全民健身精气神“燃”起来
  12. 语言 OJ 高低位逆转_用于检测污水井内水位高低的报警器--液位开关
  13. UVa 483 - Word Scramble
  14. Java单例模式实现方式
  15. VMware虚拟机中Windows内存扩展
  16. 关于MSNSHELL加密MSN聊天记录问题
  17. aptio2018设置u盘启动_怎么设置bios从u盘启动|bios设置u盘启动方法
  18. 第68页的gtk+编程例子——选择菜单
  19. viper4Android md风格,ViPER4Android音效驱动
  20. 阿里云python中文社区_python 写中文

热门文章

  1. 解决数据库报错:Table ‘*.*‘ doesn‘t exist错误
  2. 关于海盗分金币问题的讨论(面试题)[]
  3. nn.Flatten()函数详解及示例
  4. 博弈论 —— 海盗分金
  5. 现在计算机怎样读硬盘端口,组装电脑之硬盘识别篇
  6. oracle计算本月天数,oracle中计算某月的天数
  7. 豆瓣电影数据分析--Tableau
  8. 支付宝 SDK6001 错误码 或 支付繁忙
  9. 查询按键控制数码管的显示
  10. JS中的click事件无反应