百度离线地图WebGL版 (包括个性化地图)

image.png

点这里跳转查看源码

百度地图离线化 (API type=webgl&v=1.0)

webgl版本的代码与之前普通版本的代码不同, 但是基本的逻辑是差不多的, 制作思路也差不多

1. 下载主要文件

访问 webgl的api地址

api.map.baidu.com/api?type=webgl&v=1.0&ak=您的密钥

打开之后 可以看到是一个js文件和一个css样式文件, 将这两个文件下载下来并重命名

(function() {
  window.BMapGL_loadScriptTime = (new Date).getTime();
  document.write('');
  document.write('');
})();

放到项目目录下 通过script标签跟link标签引入
vue + ts项目的示例代码

declare const window: Window & typeof globalThis & { BMapGL: BMapGLType };
export function BMPGL(ak?: string) {
  return new Promise((resolve: (value?: BMapGLType ) => void, reject) => {
    const csslink = document.createElement('link');
    csslink.type = "text/css";
    csslink.rel = "stylesheet";
    csslink.href = "map/bmap.css"; // css文件地址
    const script  = document.createElement('script') as HTMLScriptElement & { readyState: any, onreadystatechange: () => void };
    script.type = 'text/javascript';
    script.src = `map/webgl.js`; // js文件地址
    script.onerror = reject;
    // 兼容ie
    script.onload = script.onreadystatechange = function () {
      if( ! this.readyState //这是FF的判断语句,因为ff下没有readyState这人值,IE的readyState肯定有值
        || this.readyState=='loaded' || this.readyState=='complete'   // 这是IE的判断语句
      ){
        resolve(window.BMapGL);
      }
    };
    document.head.appendChild(script);
  })
}
//  npm i @types/BMapGL 安装类型文件(这个类型文件不够全的 部分类型需要自己补充)
//  安装后在tsconfig.json 文件中修改配置引入
//    ...
//    "types": [
//      "webpack-env",
//      "bmapgl" 添加这个
//    ],
//    ...
//  用法
// declare interface BMapGLType {
//   Map: { new (container: string | HTMLElement, opts?: BMapGL.MapOptions): BMapGL.Map };
//   Point: { new (lng: number, lat: number): BMapGL.Point };
// }

2. 修改js文件, 我将js文件命名为webgl.js

将整个js文件格式化一下 方便修改

    1. 搜索 &callback=BMapGL._rd._cbk 找到这个方法 在第一行的位置加上if (/^http/.test(hR)) return;
...
var D = {
    request: function (hR, e) {
      if (/^http/.test(hR)) return; // 加这一行
      if (e) {
        var T = (Math.random() * 100000).toFixed(0);
        BMapGL._rd["_cbk" + T] = function (hS) {
          e && e(hS);
          delete BMapGL._rd["_cbk" + T]
        };
...
    1. 在文件的开始位置添加一个配置项 , 写你放地图文件的位置
const bmapcfg = {
  'tiles_dir'   : window.location.origin + '/map', // 瓦片地图的位置
  'home': window.location.origin + '/map' // 其他js文件的位置
};
    1. 搜索 "//map.baidu.com" 找到apiHost的配置位置, 注释掉 换成bmapcfg.home
  // apiHost: f3 + "//api.map.baidu.com",
  apiHost: bmapcfg.home,
    1. (这点可以不做, 可以跳过) 如果你的地图有固定的开始位置 比如北京, 可以在百度地图中定位到北京, 然后在network查找到qt=cen 有这个参数的请求 把这个请求的response保存成center.js文件, 然后在webgl.js中搜索 "._rd._cbk"
      在这个方法的底部 将刚刚保存的js文件替换上去
      ...
      var e = e3.apiHost + "/" + hW + "?" + hV + "&ie=utf-8&oue=1&fromproduct=jsapi";
      if (!T) {
        e += "&res=api"
      }
      e += "&callback=" + eA + "._rd._cbk" + hS;
      e += "&ak=" + ge;

      e = e3.apiHost + "/center.js" // 加这一行
      hm.load(e) // 如果不加 就把这个 hm.load(e) 注释掉 不要这个请求
      ...
  • 5 下载这两个文件
    worker_asm_p0g4zg.js
    worker_wasm_0szpq3.js
    下载后在地图文件目录按 res/webgl/10/worker_asm_p0g4zg.js 结构放好
    在webgl.js 分别搜索worker_asm_p0g4zg 跟worker_wasm_0szpq3 替换掉下载链接
...
case ax("0x70"):
// hU = (window.location.protocol === "http:" ? "http:" : "https:") + "//api.map.baidu.com/res/webgl/10/worker_asm_p0g4zg.js";
hU = bmapcfg.home + "/res/webgl/10/worker_asm_p0g4zg.js"; // 换成这个
hV = T["\x69\x64\x6c\x69\x69"];
break;
...
worker_wasm_0szpq3 文件同理, 这里就不写了
    1. modules文件, 我目前需要用到的只有 9个, 发现缺少的可以自行补充, 下载之后建一个modules文件夹 放里面, 一个一个存
      glcommon_olnscx.js
      marker_qtxdnt.js
      poly_2yxwby.js
      mapgl_f3yhch.js
      oppcgl_52eaok.js
      scommon_m12rh0.js
      control_zcqb51.js
      otherSearch_vjh3bs.js
      hotspot_ospxri.js

在webgl.js 搜索/getmodules 替换请求地址

Config: {
      // baseUrl: e3.apiHost + "/getmodules?v=1.0&type=webgl",
      baseUrl: bmapcfg.home + "/modules/", // 换成这个
      jsModPath: (dw.inMapHost ? "" : e3.mapHost) + "/res/newui/",
      timeout: 5000
    },

在webgl.js 中搜索Config.baseUrl 替换掉请求逻辑

setTimeout(function() {
// var hU = T.Config.baseUrl + "&mod=" + T._getMd5ModsStr(T.Module.modulesNeedToLoad);
// hm.load(hU);
// 上面两行注释掉换成
// ↓
var hS = T._getMd5ModsStr(T.Module.modulesNeedToLoad)
for (var hV = 0, T_index = hS.length; hV < T_index; hV++) {
  var hU = T.Config.baseUrl + hS[hV] + ".js";
  hm.load(hU);
}
// ↑
T.Module.modulesNeedToLoad.length = 0;
T.delayFlag = false
}, 1)

搜索return hS.join(",")

// return hS.join(",")
return hS  // 改成这个
    1. 替换瓦片地址
      在文件开头加上配置
window.offLineIPAddress = bmapcfg.tiles_dir 

在webgl.js 中搜索"pvd/"]

if (window.offLineIPAddress) {
  // h0 = [window.offLineIPAddress + "pvd/"];
  h0 = [window.offLineIPAddress + "/pvd/"]; // 仔细看就加多了一个/ 
  hZ = h0[0]
}
// 在这里加多一行
return hZ + h1 + '/' + i + '/' + h3

webgl用的地图是矢量地图, 用望远网可以下载一点测试, 选出区域右键选下载矢量地图就可以 , 下载下来解压是tiles的文件夹, 把tiles名字换成pvd 然后放到你放瓦片的位置, 其他的下载器像水经微图 北斗 都可以试试

    1. 个性地图 没用到的可以跳过
      把ui妹纸给你的mapstyle配置文件用个性化地图编辑器打开, 到达这个页面之后 先不要替换json配置 , 先打开F12, 清空network, 然后把json配置替换掉, 会看到network加载了一个mapstyle文件跟许多瓦片文件, 把mapstyle文件下载下来按照/custom/v2/mapstyle的这个文件结构放到你的地图文件夹下
      也可以用望远网 有获取mapstyle文件的便捷教程
image.png

接着 在webgl.js 中搜索 bo.customStyleInfo.xhr 应该能搜出来两个 一般替换第一个就好

// bo.customStyleInfo.xhr = gA.post(hT, hY, styleCbk)
bo.customStyleInfo.xhr = gA.get(hT, styleCbk, null, null, hY)

搜索var gA找到get方法 把整个方法替换掉

// 原来的
get: function (i, hS, e, T) {
      var hR = new XMLHttpRequest();
      hR.open("GET", i, true);
      hR.timeout = 10000;
      hR.ontimeout = function () {
        T && T()
      };
      hR.onreadystatechange = function (hT) {
        if (this.readyState === 4) {
          if (this.status === 200) {
            hS && hS(hR.responseText)
          } else {
            e && e()
          }
        }
      };
      hR.send()
    },

// 替换成
get: function(i, hS, e, T, hT) {
        // xiewanna
          var hR = new XMLHttpRequest();
          hR.open("GET", i, true);
          hR.timeout = 10000;
          hR.ontimeout = function() {
              T && T()
          }
          ;
          hR.onreadystatechange = function(hU) {
              if (this.readyState === 4) {
                  if (this.status === 200) {
                      hS && hS(hR.responseText, hT)
                  } else {
                      e && e()
                  }
              }
          }
          ;
          hR.send(hT)
          return hR
      },

搜索hX.textureSources[hU[i].processedInZoom]

// textureSource: hX.textureSources[hU[i].processedInZoom],
// textureHeight: hX.textureHeights[hU[i].processedInZoom],
替换成
textureSource: hX.textureSources ? hX.textureSources[hU[i].processedInZoom] : hX.textureSources,
textureHeight: hX.textureHeights ? hX.textureHeights[hU[i].processedInZoom] : hX.textureHeights,

搜索logo_hd.png 然后一整行注释掉 这个是去掉水印

// e.innerHTML = '';

下载 indoor_fs.js 跟 icons_2x.js 按照/sty/icons_2x.js的结构去存放
搜索indoor_fs.js 找到上一行的地址改掉

var e = bmapcfg.home + "/sty/"; // 就改这行
return [e + "icons_2x" + hT + ".js?" + hR, e + "fs" + hT + ".js?" + hR, e + "indoor_fs.js?" + hR]

到这里js修改就结束了

目录结构

这个文件不要放在项目里, 地图文件很大, 也可以把地图文件单独抽出来放服务器(记得改配置地址)

image.png

你可能感兴趣的:(百度离线地图WebGL版 (包括个性化地图))