百度离线地图开发,node实现地图瓦片下载

最近有个Web项目要用离线地图,项目是在内网环境,找了很多资料,踩了很多坑,好在已经实现了,下面把资料整理一下。

首先是百度离线地图开发包,原文地址是http://www.xiaoguo123.com/p/baidumap_offline_v21

这是数据包-百度离线地图API V2.1

里面有在线地图的基本API,可以满足绝大部分需求,不行的在自己扩展,附两张目录结构图

百度离线地图开发,node实现地图瓦片下载_第1张图片

百度离线地图开发,node实现地图瓦片下载_第2张图片


项目所需的两个入口文件,其他按正常百度地图API开发即可

之后就是瓦片地图的下载,也就是文件夹tiles,里面是百度地图的底图瓦片目录,下面贴上我的下载代码

var request = require('request') // 用于请求瓦片地图
var fs = require("fs");  // 文件操作
var bagpipe = require('bagpipe')  //  用于异步请求数量控制
var TileLnglatTransform = require('tile-lnglat-transform'); //  用于经纬度转换为瓦片坐标
var x1 = 120.128465, y1 = 30.393577 // 起始点坐标(左上角)
var x2 = 120.708555, y2 = 29.914415 // 终点坐标(右下角)

// 根据地图平台使用转换类
var TileLnglatTransformBaidu = TileLnglatTransform.TileLnglatTransformBaidu;
var all = [] // 保存所有层级瓦片坐标等信息
for(i = 3; i <= 18; i++){
  all[i] = {}
  p1 = TileLnglatTransformBaidu.lnglatToTile(x1, y1, i)
  p2 = TileLnglatTransformBaidu.lnglatToTile(x2, y2, i)
  all[i].t = i // 层级
  all[i].x = [p1.tileX, p2.tileX] // 瓦片横坐标范围(左至右)
  all[i].y = [p2.tileY, p1.tileY] // 瓦片纵坐标范围(下至上)
}
// console.log(all)
var bag = new bagpipe(100, {timeout: 1000}) //限制请求数,此处为100,可根据网络情况修改
var path = './tiles' // 瓦片目录
fs.access(path, fs.constants.F_OK, err => {
  // 创建tiles文件夹
  if (err) fs.mkdir(path, err => {})
  for (let z = 3; z <= all.length - 1; z++) {
    fs.access(`${path}/${z}`, fs.constants.F_OK, err => {
      // 创建tiles/Z文件夹 ,Z是层级
      if (err) fs.mkdir(`${path}/${z}`, err => {})
      for (let x = all[z].x[0]; x <= all[z].x[1]; x++) {
        fs.access(`${path}/${z}/${x}`, fs.constants.F_OK, err => {
          // 创建tiles/Z/X文件夹 ,X是瓦片横坐标
          if (err) fs.mkdir(`${path}/${z}/${x}`, err => {})
        })
      }
    })
  }
  // 文件夹可能较多,等待1s开始下载
  setTimeout(() => {
    task()
  }, 1000)
})
function task() {
  for (let z = 3; z <= all.length - 1; z++) {
    for (let x = all[z].x[0]; x <= all[z].x[1]; x++) {
      for (let y = all[z].y[0]; y <= all[z].y[1]; y++) {
        // 将下载任务推入队列,bag会以100张为单位批量下载
        bag.push(download, x, y, z)
      }
    }
  }
}
function download(i, j, z) {
  // url是百度服务器上的图片资源,尾部时间可根据需要修改,最好下载最新的
  let url = `http://online0.map.bdimg.com/tile/?qt=tile&x=${i}&y=${j}&z=${z}&styles=pl&scaler=1&udt=20180711`
  request({url, timeout: 4000}, (err, res, body) => {
    if (err) {console.log(err)}
  }).pipe(fs.createWriteStream(`${path}/${z}/${i}/${j}.png`));
}

这里引用了两个包,一个BagPipe用来限制并发,一个tile-lnglat-transform用来转换坐标

部分用法在代码注释里有,详细的可参考他们的项目。图片量较大,上图是杭州市萧山区3到18级瓦片总共8W+png,约300M。

19级加上的话要30W+png,没敢下有点多。。。

之后就是将下载好的tiles文件夹覆盖到项目目录下,目录结构第二张的tiles文件夹,

这里再提供一个好用的瓦片下载器

至此,离线地图基本完成,愉快的开发吧!

你可能感兴趣的:(百度离线地图开发,node实现地图瓦片下载)