贴个群号
WebGIS学习交流群461555818,欢迎大家
思路
众所周知,mapbox的style主要分成paint属性和layout属性,paint下的属性是无极缩放的,而layout并不是,即使是利用插值表达式进行计算,仍然不是无极缩放,只会在zoom到达整数的时候,才会进行插值,比如以下表达式,会在zoom为1,2,3的时候插值,但是8到9之间呢,比如8.1,8.2,这个时候是不会插值的。
'icon-size':{
"type": "interval",
"stops": [
[0, 0.3],
[8, 0.4],
[9, 0.5]
]
},
但是总有个别领导不想看到图片在级别转换的时候突然的改变这种图片大小,想要平滑的过渡,依靠插值表达式是无法解决的了,那么我们该如何实现这种伪需求呢?
这里提供一个思路就是手动插值,监听地图zoom的改变,手动插值,编写一个函数,接收三个参数,第一个参数为zoom数组,第二个参数为插值的数组,比如文中例子的icon-size,第三个参数为当前的zoom等级。
比如第一个参数为[0,17],第二个参数为[0.1,0.2],第三个参数为5,那就是计算zoom为5的时候,对应的值,当然数组长度不一定要为2个,可以多个,这样的话,就先计算zoom在那个区间,再进行插值,然后利用setPaintProperty进行赋值即可。
map.setPaintProperty(
'你的图层ID',
'icon-size',
'你的插值出来的值'
);
示例方法
//从渐变区间中插值取出对应的颜色 zoom数组 对应值数组 想要插值出来的数值
export const getInterpolateValue=(gradientZoom,gradientValues,valueToMatch)=>{
//如果要素超过最大
if(valueToMatch> gradientZoom[gradientZoom.length-1]){
return gradientValues[gradientValues.length-1]
}
//如果要素小于最小
if(valueToMatch< gradientZoom[0]){
return gradientValues[0]
}
//插值计算
const interpolateValue=(value1, value2, percentage)=>{
// return Math.round(value1 + (value2 - value1) * percentage)
return value1 + (value2 - value1) * percentage
}
let value = '';
for (let i = 1; i < gradientZoom.length; i++) {
//寻找目标值在那一个渐变区间
if (valueToMatch <= gradientZoom[i]) {
//计算比例 上区间和下区间的比例
const percentage = (valueToMatch - gradientZoom[i - 1]) / (gradientZoom[i] - gradientZoom[i - 1]);
value = interpolateValue(gradientValues[i - 1], gradientValues[i], percentage);
break;
}
}
return value
}