美文网首页
百度离线地图WebGL版 (包括个性化地图)

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

作者: NanaCti | 来源:发表于2021-02-25 20:48 被阅读0次
    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文件格式化一下 方便修改

      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 文件同理, 这里就不写了
    

    在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 = '<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

    相关文章

      网友评论

          本文标题:百度离线地图WebGL版 (包括个性化地图)

          本文链接:https://www.haomeiwen.com/subject/fpzufltx.html