底图(矢量切片图层的url)不变,但是需要添加上不同的style形成动画轮播的效果。
给图层更换样式不难,找到对应的feature
,使用feature.setStyle
就可以了。但是我在项目中遇到的问题是获取不到feature,或者获取到的feature
不可用(我一同事就遇到了使用feature.setStyle
不生效的情况,最后也没有找到原因,最后每次更换样式时添加不同样式的图层,然后添加了一堆的layers
,导致地图非常庞大)。
这篇文章就是讲的就是没有feature
的时候如何更换样式——layer.setStyle
// prop: 用来拼接url的
// layerId: 图层id,唯一标识
// geom:用来更改不同style
loadRainForcastLayer(prop, layerId,geom) {
let levelJson = JSON.parse(geom);
// style 和 setStyle 方法中会出现this指向不同问题,所以先提出来
let that = this
//在地图中找到所有的layer,判断要添加的图层是否已存在
this.getLayers().forEach((layer) => {
if (layer.getProperties().id&&layer.getProperties().id == layerId) {
this.rainForcastLayer = layer;
}
});
//如果图层存在,直接更改样式
if (this.rainForcastLayer) {
this.rainForcastLayer.setVisible(true);
this.rainForcastLayer.setStyle(function(feature,res){
let id = feature.get("id");
// 从这里往下 通过id获取铺图层的样式 颜色 ↓
let number=levelJson[id]?levelJson[id]:0
let level=that.getLevel(number)
let text=String(number)==0?"":String(number)
let color=conf.mapViewer.Predicforeca[level]
// 从这里往上 通过id获取铺图层的样式 颜色 ↑
let vectorTileStyle = new Style({
stroke: new Stroke({
color: "rgba(255,255,255,0)",
width: 2,
}),
fill: new Fill({
color: color
}),
text: new Text({ //文本样式
font: '12px Calibri,sans-serif',
fill: new Fill({
color: '#000'
}),
stroke: new Stroke({
color: '#000',
width: 1,
}),
// 注意这个text只能是 string 格式,所以前面进行了转换
text:text
}),
});
return vectorTileStyle
})
return;
}
let style = "";
//这里开始拼接url,如果有完整的可用的url可以不看这一段 ↓
var gridsetName = "EPSG:4326";
var gridNames = [
"EPSG:4326:0",
"EPSG:4326:1",
"EPSG:4326:2",
"EPSG:4326:3",
"EPSG:4326:4",
"EPSG:4326:5",
"EPSG:4326:6",
"EPSG:4326:7",
"EPSG:4326:8",
"EPSG:4326:9",
"EPSG:4326:10",
"EPSG:4326:11",
"EPSG:4326:12",
"EPSG:4326:13",
"EPSG:4326:14",
"EPSG:4326:15",
"EPSG:4326:16",
"EPSG:4326:17",
"EPSG:4326:18",
];
let format = "application/vnd.mapbox-vector-tile";
var resolutions = [0.703125, 0.3515625, 0.17578125, 0.087890625, 0.0439453125, 0.02197265625, 0.010986328125, 0.0054931640625, 0.00274658203125, 0.001373291015625, 6.866455078125E-4, 3.4332275390625E-4, 1.71661376953125E-4, 8.58306884765625E-5, 4.291534423828125E-5, 2.1457672119140625E-5, 1.0728836059570312E-5, 5.364418029785156E-6, 2.682209014892578E-6, 1.341104507446289E-6, 6.705522537231445E-7, 3.3527612686157227E-7];
let vectorTileParams = {
REQUEST: "GetTile",
SERVICE: "WMTS",
VERSION: "1.0.0",
LAYER: prop.layer,
STYLE: style,
TILEMATRIX: gridsetName + ":{z}",
TILEMATRIXSET: gridsetName,
FORMAT: format,
TILECOL: "{x}",
TILEROW: "{y}",
};
var projection = new Projection({
code: "EPSG:4326",
units: "degrees",
axisOrientation: "neu",
});
let baseUrl = ipConfig.geoServer + "/gwc/service/wmts";
let url = baseUrl + "?";
for (var param in vectorTileParams) {
url = url + param + "=" + vectorTileParams[param] + "&";
}
//这里结束拼接url,如果有完整的可用的url可以不看这一段 ↑
//第一次添加该图层
this.rainForcastLayer = new VectorTileLayer({
style: function(feature){
let id = feature.get("id");
let number=levelJson[id]?levelJson[id]:0;
let level=that.getLevel(number)
let text=String(number)==0?"":String(number)
let color=conf.mapViewer.Predicforeca[level]
let styles=new Style({
stroke: new Stroke({
color: "rgba(255,255,255,0)",
width: 2,
}),
fill: new Fill({
color: color
}),
text: new Text({ //文本样式
font: '12px Calibri,sans-serif',
stroke: new Stroke({
color: '#000',
width: 1,
}),
fill: new Fill({
color: '#000'
}),
text:text
})
})
return styles;
},
zIndex: ZINDEXCONSTANT.NINECLASSLAYER,
id: layerId,
projection: projection,
maxResolution: 350,
source: new VectorTileSource({
projection: projection,
tileGrid: new WMTSTileGrid({
tileSize: [256, 256],
origin: [-180.0, 90.0],
resolutions: resolutions,
matrixIds: gridNames,
}),
format: new MVT(),
url: url,
wrapX: true,
tilePixelRatio: 1,
}),
});
this.addLayer(this.rainForcastLayer);
}
对地图操作的方法写好了,然后动画的时候直接设置一个定时器就可以了:
play(){
this.timeInterval = setInterval(() => {
if (this.currentRowIndex < this.forecastList.length - 1) {
this.currentRowIndex++;
} else {
this.currentRowIndex = 0;
}
this.levelJson=JSON.parse(this.forecastList[this.currentRowIndex].predicProduct)
this.loadRainForcastLayer(
{
key: 'layer-rainForcast',
layer:"meteo_qpf:QPF",
title: '降雨预报',
},
"layer-rainForcast",
this.forecastList[this.currentRowIndex].predicProduct
);
}, 3000);}
然后在停止的时候:
stop(){
//将对应图层隐藏
this.rainForcastLayer && this.rainForcastLayer.setVisible(false);
//清除定时器
clearInterval(this.timeInterval)
}
然后功能就可以完成了!