首先找到的是这段代码:
map.addLayer({
id: "id",
type: "symbol",
source: "source",
"source-layer": sourceLayer,
"layout": {
"icon-image": ['case', [">", "weight", 1], "img1", "img2"], // 重点!
"icon-size": scale,
"icon-allow-overlap": true,
"icon-anchor": "center"
}
});
通过case的方法,确实可以让一个图层里有多种图标展示,但它需要叠加之前就把识别参数填好。问题在于,怎么让鼠标移到上面,再改变单个点的属性?用evt.features[0].properties.weight = 1是没有用的,就算第一次mouseenter进入方法里改了它的属性,再次进入时它的weight值还是原样。
于是,我找到了setFeatureState,它的写法是:
map.setFeatureState({source: 'source', id: evt.features[0].properties.id}, { weight: 1 });
但我这样用,直接报错:The sourceLayer parameter must be provided for vector source types,我查了官方的接口介绍,原来这个方法针对的是vector or GeoJSON sources。示例里的是多边形数据,所以能成功,而我这边要处理的是mvt矢量瓦片数据,无法使用。
最后一筹莫展的时候,突然想到了之前查资料看到的setLayoutProperty,只要改变layout中判定条件,就可以实现图标的转变,所以最终的代码为:
map.on('mouseenter', 'source', (evt) => {
map.getCanvas().style.cursor = 'pointer';
map.setLayoutProperty('source', "icon-image", [
'case',
["==", ["get", "id"], evt.features[0].properties.id],
"img1",
"img2"
]);
});
map.on('mouseleave', 'source', (evt) => {
map.getCanvas().style.cursor = '';
map.setLayoutProperty('source', "icon-image", "img2");
});
效果图: