13

由于客户需求,之前使用的json形式的可钻取型地图被放弃了,要好看,没有网~,于是开启了打地鼠(bug)模式,总结如下:

网上搜索,百度离线地图资料很有限啊,可以用的几个要么年代久远,要么不能满足需求。不过还是从前辈们那里理清了思路

1.前期准备

需要的东西

2.百度地图API文件

2.1 下载API主文件

下载最新的api文件,不需要申请ak,地址:http://api.map.baidu.com/api?v=2.0, 打开可以看到:

clipboard.png
复制划线部分并打开,拿到主文件,为方便后续查看修改,先格式化一下,工具: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 = '';

clipboard.png

加载模块短路处理
搜索 &mod=,替换。那个 console.log(a),是为了给后面创建getModules.js用

clipboard.png

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级,可根据需要选择)的文件夹:

clipboard.png

下面分步讲解:

4.1 获取地图图片请求地址

查看请求图片的地址,

clipboard.png

在apiv2.0.min.js中找到相关代码,搜索 getTilesUrl,有好几个,对照URL地址的构成,可以找到

clipboard.png

方框内是获取图片地址,url是原始地址,nname是即将存入的本地地址。根据需要对页面的地图进行拖拽和缩放,在调用页面,拿到xxxUrls。

clipboard.png

先对地图进行拖拽(加载图片),确保想要的省市(比如我要江浙沪)都出现在可是范围内,每缩放到一个等级,都要把江浙沪拖到可视区域溜一圈。

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))
      }
    }
  }
}

长这样
clipboard.png

4.3 修改获取图片地址

在apiv2.0.min.js中找到相关代码,搜索 getTilesUrl,同上, 找到后修改。

clipboard.png

开始的时候我把这api,getModues的文件都放在调用页面那边,图片加载报错,后来移到项目最外层的static中才解决。最终的目录结构:

clipboard.png

5.与echarts结合

引入BMap,两种方法,一种是引入echarts安装包里的bmap.js文件(本文采用这用),另一种是从windows中直接拿

clipboard.png

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);

皮卡丘那个丘
169 声望14 粉丝