文章目录
- 概要
- 效果预览
- 技术思路
- 技术细节
- 小结
概要
本篇文章还是关于最近做到的 mapboxgl 地图展开的。
借鉴官方示例:https://iclient.supermap.io/examples/mapboxgl/editor.html#heatMapLayer
效果预览
技术思路
- 将接口数据渲染到地图中形成热力图。
- 还需要将热力图中渲染的点做鼠标移上显示详情 popup 的效果。
注意:因为热力图本身不可以添加鼠标以上效果,所以还是使用了点,将鼠标以上效果加给点,然后把点的透明度设置为0,大小和热力图中点相同,即可完成上图中效果。
技术细节
- 地图的加载不再赘述,之前文章中写到了。
- 所需要规范的点数据
其中point是自定义的,传啥都可以, createPopupStyle 就是生成 popup 的 html
featuresList.push({
'type': 'Feature',
'properties': {
...point,
'description': that.createPopupStyle(point)
},
'geometry': {
'type': 'Point',
'coordinates': [Number(point.lng), Number(point.lat)]
}
})
- 新建热力图
/**
* 添加热力图
*/
createHeatPoints(featuresList) {
const that = this
const map = this.map
let heatMapLayer = new mapboxgl.supermap.HeatMapLayer(
"heatMap",
{
"map": map,
"id": "heatmap",
"radius": 50,
// 设置图层透明度:(参数方式)
"opacity": 0.6,
// featureWeight指定以哪个属性值为热力权重值创建热力图:
"featureWeight": "value",
}
);
let heatPoints = {
"type": "FeatureCollection",
"features": featuresList
};
heatMapLayer.addFeatures(heatPoints);
// 设置图层透明度:(函数方式)
// heatMapLayer.setOpacity(0.5);
map.addLayer(heatMapLayer);
},
- 添加透明度为0的点以及鼠标移上效果
/**
* 添加坐标点及鼠标移上效果
*/
addPoints(featuresList) {
const map = this.map
map.addSource('places', {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': featuresList
}
})
// 加载 circle 定位圆
let img = {
name: 'circle_img',
sdf: true
}
this.addCircleImage(img)
map.addLayer({
'id': 'places',
'type': 'symbol',
'source': 'places',
'layout': {
'icon-image': img.name, // 图标ID
'icon-size': 0.4, // 图标的大小
// 'icon-size': ['get', 'imgSize'], // 图标的大小
'icon-anchor': 'center', // 图标的位置
// 'text-field': ['get', 'num'],
},
'paint': {
'text-color': '#333',
'icon-color': 'rgba(0,0,0,0)'
},
});
// Create a popup, but don't add it to the map yet.
const popup = new mapboxgl.Popup({
closeButton: false,
closeOnClick: false
});
map.on('mouseenter', 'places', (e) => {
// Change the cursor style as a UI indicator.
map.getCanvas().style.cursor = 'pointer';
// Copy coordinates array.
const coordinates = e.features[0].geometry.coordinates.slice();
const description = e.features[0].properties.description;
// Ensure that if the map is zoomed out such that multiple
// copies of the feature are visible, the popup appears
// over the copy being pointed to.
while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
}
// Populate the popup and set its coordinates
// based on the feature found.
popup.setLngLat(coordinates).setHTML(description).addTo(map);
});
map.on('mouseleave', 'places', () => {
map.getCanvas().style.cursor = '';
popup.remove();
});
},
- 引入图片使用方法
注意:vue中引入图片要使用require引入,路径不能以传参的形式传入,最好写相对路径。不然都会报错。
/**
* 引入图片
* img obj : name, sdf
*/
addCircleImage(img) {
const map = this.map
map.loadImage(require('./circle.png'), (error, image) => {
if (error) throw error;
if (!map.hasImage(img.name)) map.addImage(img.name, image, {
sdf: img.sdf || false
});
})
}
小结
本方法主要还是使用点和热力图重叠同时显示效果。