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

2021-02-25  本文已影响0人  NanaCti
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('<script type="text/javascript" src="http://api.map.baidu.com/getscript?type=webgl&v=1.0&ak=E4805d16520de693a3fe707cdc962045&services=&t=20210220110549"></script>');
  document.write('<link rel="stylesheet" type="text/css" href="http://api.map.baidu.com/res/webgl/10/bmap.css"/>');
})();

放到项目目录下 通过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文件格式化一下 方便修改

...
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]
        };
...
const bmapcfg = {
  'tiles_dir'   : window.location.origin + '/map', // 瓦片地图的位置
  'home': window.location.origin + '/map' // 其他js文件的位置
};
  // apiHost: f3 + "//api.map.baidu.com",
  apiHost: bmapcfg.home,
      ...
      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) 注释掉 不要这个请求
      ...
...
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 文件同理, 这里就不写了

在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  // 改成这个
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 然后放到你放瓦片的位置, 其他的下载器像水经微图 北斗 都可以试试

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 = '<img src="' + e3.apiHost + '/images/logo_hd.png"  style="height:21px;width:62px;"/>';

下载 indoor_fs.jsicons_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
上一篇下一篇

猜你喜欢

热点阅读