百度离线地图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文件格式化一下 方便修改
- 搜索 &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]
};
...
- 在文件的开始位置添加一个配置项 , 写你放地图文件的位置
const bmapcfg = {
'tiles_dir' : window.location.origin + '/map', // 瓦片地图的位置
'home': window.location.origin + '/map' // 其他js文件的位置
};
- 搜索 "//map.baidu.com" 找到apiHost的配置位置, 注释掉 换成bmapcfg.home
// apiHost: f3 + "//api.map.baidu.com",
apiHost: bmapcfg.home,
- (这点可以不做, 可以跳过) 如果你的地图有固定的开始位置 比如北京, 可以在百度地图中定位到北京, 然后在network查找到qt=cen 有这个参数的请求 把这个请求的response保存成center.js文件, 然后在webgl.js中搜索 "._rd._cbk"
在这个方法的底部 将刚刚保存的js文件替换上去
- (这点可以不做, 可以跳过) 如果你的地图有固定的开始位置 比如北京, 可以在百度地图中定位到北京, 然后在network查找到qt=cen 有这个参数的请求 把这个请求的response保存成center.js文件, 然后在webgl.js中搜索 "._rd._cbk"
...
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 文件同理, 这里就不写了
- 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
- modules文件, 我目前需要用到的只有 9个, 发现缺少的可以自行补充, 下载之后建一个modules文件夹 放里面, 一个一个存
在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 然后放到你放瓦片的位置, 其他的下载器像水经微图 北斗 都可以试试
接着 在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.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