前端系列(2),mapbox 与 ol-cesium 的兼容问题
背景是这样的,因为项目里使用的地图库是 mapbox,所以采用的数据格式都是 mapbox 标准的。但有一个功能之前使用了 ol-cesium,所以在将 mapbox 标准的数据给到 ol-cesium 时,不可避免的有了冲突。
在此针对几点,简单给下思路:
layer 压盖问题
针对压盖问题,在 mapbox 中,如果将一个 layer 按照特征拆分成一组 layers,对 layers 的排序方法不变。
- style.layers = orderLayers 自己控制添加的layer顺序即可
- movelayer(id, beforeId?) 移动特定layer
而在 ol-cesium 中,排序的方式不太一样,其是通过 renderOrder 在渲染前对特征进行排序:
我将我的代码贴下,很简单,你自己打印下 catetitle 的值,应该就知道怎么排了:
vectorLayer = new ol.layer.VectorTile({
...
zIndex: originalLayerIndex,
renderOrder: (p0, p1) => { // sort feature
if (p0 && p1 && p0.getProperties() && p0.getProperties().catetitle
&& p1.getProperties() && p1.getProperties().catetitle) {
return reverseLegends.indexOf(p0.getProperties().catetitle)
- reverseLegends.indexOf(p1.getProperties().catetitle);
}
return 0;
},
});
表达式
在 mapbox 中支持表达式作为属性,如这样:
width = ["interpolate", ["linear"], ["zoom"], 5, 1, 10, 5]
但在 ol-cesium 中,Stroke 只支持一个 num 作为线宽,
style.setStroke(new ol.style.Stroke({
width: widthNum,
}));
这个时候,我们就只能监听 zoom 变化,根据表达式去动态计算当前 zoom 下的线宽了,没有 mapbox 那样方便,如线性表达式的代码我贴下:
function handleWidthExpression(value, zoom, defalultValue = 2) {
// value: ["interpolate", ["linear"], ["zoom"], 5, 1, 10, 5, ...]
if (!value) {
return defalultValue;
}
if (!Array.isArray(value)) {
return value;
}
if (value.length < 5) {
return defalultValue; // error data
}
if (zoom <= value[3]) {
return value[4];
}
if (zoom >= value[value.length - 2]) {
return value[value.length - 1];
}
let startX, startY, endX, endY;
for (let i = 3; i < value.length; i+=2) {
const z = value[i];
if (zoom >= z) {
startX = z;
startY = value[i + 1];
}
if (zoom <= z) {
endX = z;
endY = value[i + 1]
}
}
if (startY && endY) {
return (endY - startY) * (zoom - startX) * 1.0 / (endX - startX) + startY;
} else {
return 2; // error data
}
}
其他表达式也是同理,需要自己去处理。
开发过程中,随时补充..
转载自:https://juejin.cn/post/7241161381982109755