一、背景
目前互联网地图基本都采用了矢量瓦片地图的形式,包括百度、高德等主流互联网地图。栅格瓦片地图的更新频率越来越低,需要离线部署的地图引擎都要考虑适配互联网的矢量瓦片。此前尝试用mapbox匹配百度矢量瓦片,发现百度矢量瓦片的结构非mvt格式的,难以适配,但在适配过程中,提取了百度矢量瓦片的请求方法,供大家研究参考。
二、请求格式
百度矢量瓦片的请求形式与栅格瓦片相似,也是通过发送一个http请求,返回一个瓦片。但区别是矢量瓦片的参数形式是经过编码的,无法直接在参数上输入瓦片的行列,返回的瓦片也是个二进制数组,需要百度地图引擎才能解析。
(1)URL请求形式
百度矢量瓦片请求例子:
请求形式:https://maponline3.bdimg.com/pvd/?qt=vtile & param=[参数内容]
其中maponline3.bdimg.com是瓦片服务器,百度有四个瓦片服务器,分别是1-4,有兴趣的可以试试。
param的参数内容是一个经过算法编码的字符串,它的编码前的内容如下:
"x=6199&y=1252&z=17&styles=pl&textimg=1&scaler=2&v=088&udt=20230817&json=0"
x:是瓦片列数,y:是瓦片行数,z:是级别,
scaler:是缩放比例,具体含义不是特别清楚,当浏览器的缩放比例大于1.25,这个scaler就会填2.
udt:是瓦片的版本时间,v:是瓦片的版本
里面还有个隐藏参数styleId=0或1,看起来是普通模式和暗黑模式的区别。
原始参数经过“瓦片参数编码算法”编码,就可以获得param实际的请求参数(上面请求中param=之后的那一段乱码)
(2)瓦片参数的编码算法
编码算法直接从引擎提取出来,已经过混淆,所以比较难读,不过也不需要纠结如何实现,
应用时直接使用即可。
export function encryptParam(t: string): string {
for (var e = "", i = 0; i < t.length; i++) {
var n = t.charCodeAt(i) << 1
, o = n.toString(2)
, a = o.length
, r = o;
8 > a && (r = "00000000" + o,
r = r.substr(o.length, 8)),
e += r
}
for (var s = 5 - e.length % 5, l = [], i = 0; s > i; i++)
l[i] = "0";
e = l.join("") + e;
for (var h = [], i = 0; i < e.length / 5; i++) {
var n = e.substr(5 * i, 5)
, c = parseInt(n, 2) + 50;
h.push(String.fromCharCode(c))
}
let result = h.join("") + s.toString()
return window.encodeURIComponent(result);
}
三、结束语
矢量瓦片适配非常困难,这里只是初步研究,后续需要研究互联网地图矢量瓦片的内部结构,对应的图标怎么组织的,各个图层的Style是如何控制的。