由于客户需求,之前使用的json形式的可钻取型地图被放弃了,要好看,没有网~,于是开启了打地鼠(bug)模式,总结如下:
网上搜索,百度离线地图资料很有限啊,可以用的几个要么年代久远,要么不能满足需求。不过还是从前辈们那里理清了思路
1.前期准备
需要的东西
- 百度地图API文件(替代<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=#"></script>)
- getModules.js
- 地图瓦片
2.百度地图API文件
2.1 下载API主文件
下载最新的api文件,不需要申请ak,地址:http://api.map.baidu.com/api?v=2.0, 打开可以看到:
复制划线部分并打开,拿到主文件,为方便后续查看修改,先格式化一下,工具:http://www.bejson.com/,命名为apiv2.0.min.js
2.2 改造apiv2.0.min.js
去掉ak验证
搜索charset = 'utf-8',添加 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)
};
引用本地工具资源
搜索 domain.main_domain_cdn.baidu[0],找到使用它定义的z.ma,修改为z.ma = '';
加载模块短路处理
搜索 &mod=,替换。那个 console.log(a),是为了给后面创建getModules.js用
3. 创建本地工具资源文件getModules.js
在这里面放API需要调用的模块,上面打印的数组a里面是需要请求的模块,打印出来,通过下面方式获取,放到getmodules2.0.js,例如 canvablepath_lf2t4w, 通过
http://api0.map.bdimg.com/getmodules?v=2.0&t=20140707&mod=canvablepath_lf2t4w
下载。
这个时候已经可以用了:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Hello, World</title>
<style type="text/css">
html{height:100%}
body{height:100%;margin:0px;padding:0px}
#main{height:100%}
</style>
<script type="text/javascript" src="js/apiv2.0.min.js">
</script>
</head>
<body>
<div id="main"></div>
<script type="text/javascript">
var map = new BMap.Map("main"); // 创建地图实例
var point = new BMap.Point(116.404, 39.915); // 创建点坐标
map.centerAndZoom(point, 15); // 初始化地图,设置中心点坐标和地图级别
</script>
</body>
</html>
4.获取地图瓦片
很多人推荐了诸如太乐地图下载器、全能地图下载器、水经注地图下载等等,无奈都要花钱购买,再加上用的mac,各种不方便。最后用node自己写的。新建文件夹tiles,放图片,最终目标形成按级分类(百度地图瓦片层级分为16级,可根据需要选择)的文件夹:
下面分步讲解:
4.1 获取地图图片请求地址
查看请求图片的地址,
在apiv2.0.min.js中找到相关代码,搜索 getTilesUrl,有好几个,对照URL地址的构成,可以找到
方框内是获取图片地址,url是原始地址,nname是即将存入的本地地址。根据需要对页面的地图进行拖拽和缩放,在调用页面,拿到xxxUrls。
先对地图进行拖拽(加载图片),确保想要的省市(比如我要江浙沪)都出现在可是范围内,每缩放到一个等级,都要把江浙沪拖到可视区域溜一圈。
4.2 下载图片
nodejs的主要代码贴上:
const imgArr = xxxUrls;
const newArr = new Set(imgArr); //去重
const finalArr = Array.from(newArr);
//创建目录
const fs = require('fs');
const axios = require('axios');
const request = require('request');
const path = require('path')
const hostdir = "./";
function mkdirSync(dirname) {
if (fs.existsSync(dirname)) {
return true;
} else {
if (mkdirSync(path.dirname(dirname))) {
fs.mkdirSync(dirname);
return true;
}
}
return false
}
const n = 0;
for (const item of finalArr) {
const last = item.name.lastIndexOf('/')
if (last > 0) {
const name = item.name.substr(last + 1)
const dir = item.name.substr(0, last)
const dstpath = hostdir + dir + '/' + name
if (name.length && dir.length && !fs.existsSync(dstpath)) {
if (mkdirSync(hostdir + dir)) {
++n;
request(item.url).pipe(fs.createWriteStream(dstpath))
}
}
}
}
长这样
4.3 修改获取图片地址
在apiv2.0.min.js中找到相关代码,搜索 getTilesUrl,同上, 找到后修改。
开始的时候我把这api,getModues的文件都放在调用页面那边,图片加载报错,后来移到项目最外层的static中才解决。最终的目录结构:
5.与echarts结合
引入BMap,两种方法,一种是引入echarts安装包里的bmap.js文件(本文采用这用),另一种是从windows中直接拿
const newMap = echarts.init(document.getElementById('newMap'));
newMap.setOption(this.newOption);
// bmap
const bmap = newMap.getModel().getComponent('bmap').getBMap();
const point = new BMap.Point(118.78, 31.04); // 设置中心点
// 设置缩放范围(地图层级),这次只需要到10级就好,最小能看中国地图5级就好。
bmap.setMaxZoom(10);
bmap.setMinZoom(5);
// 限制拖拽范围,就是限制拖拽的边界,图片没那么多,一直拖,等图片用完,就出现空白。
const b = new BMap.Bounds(new BMap.Point(111.64, 26.40), new BMap.Point(125.95, 35.28)); // 左下角,右上角
try {
BMapLib.AreaRestriction.setBounds(bmap, b);
} catch (e) {
alert(e);
};
bmap.centerAndZoom(point, 7);
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。