封装icon图层
class IconLayer {
constructor(map, layername, option, mapStyle) {
this.map = map;
this.layername = layername;
this.mapStyle = mapStyle || {};
this.option = option;
this.iconImg = option?.icon;
this.callback = option?.callback;
this.clickFun = (data) => {
this.mapClickFun(data);
};
this.initLayer();
}
图层初始化
//初始化图层
initLayer () {
if (!this.map?.getSource(this.layername)) {
this.map.addSource(this.layername, {
type: 'geojson',
data: {
type: 'Feature',
features: [],
},
});
}
if (!this.map?.getLayer(this.layername + '_icon')) {
this.map.loadImage(this.iconImg, (error, image) => {
if (error) throw error;
this.map.addImage(this.layername + '_icon', image);
this.map.addLayer({
id: this.layername + '_icon',
type: 'symbol',
source: this.layername,
layout: {
'icon-image': this.layername + '_icon',
'icon-size': 1,
...this.mapStyle,
},
});
});
this.map.on('click', `${this.layername}_icon`, this.clickFun);
}
}
添加图层数据,更新图层数据
addMapLayer (geoJsondata) {
this.updateLayer(geoJsondata);
}
/**
*更新数据源
*/
updateLayer (data) {
if (this.map?.getLayer(this.layername + '_icon')) {
let geojson = {
type: 'FeatureCollection',
features: data,
};
this.map.getSource(this.layername).setData(geojson);
}
}
删除图层数据
removeMapLayer () {
if (this.map?.getLayer(this.layername + '_icon')) {
this.map.off('click', `${this.layername}_icon`, this.clickFun);
this.map.removeLayer(this.layername + '_icon');
this.map.removeSource(this.layername);
}
if (this.map?.hasImage(this.layername + '_icon')) {
this.map.removeImage(this.layername + '_icon');
}
}
控制图层显隐
setLayerVisible (visibility) {
if (this.map?.getLayer(this.layername + '_icon')) {
if (visibility) {
this.map.setLayoutProperty(this.layername + '_icon', 'visibility', 'visible');
} else {
this.map.setLayoutProperty(this.layername + '_icon', 'visibility', 'none');
}
}
}
点击方法
mapClickFun (data) {
console.log(this.layername, data, 'this.layername');
if (this.callback) {
let coordinates = data?.features[0]?.geometry?.coordinates || [
data.lngLat.lng,
data.lngLat.lat,
];
let lnglat = { lng: coordinates[0], lat: coordinates[1] };
this.callback(lnglat, data.features[0].properties, this.layername);
}
}
封装完成之后可以直接在需要的模块引入iconLayer组件,再使用封装的方法进行操作
this.iconLayers=new IconLayer(
map,
'icon_1',//图层名称
{
icon: menu[i].icon,//icon图片
callback: (lngLat, properties, layerName) => {
this.puporfun(lngLat, properties, layerName);
},//点击事件返回的数据
},
// { 'icon-allow-overlap': true },
)
//添加数据
this.iconLayers.addMapLayer(data)