效果图
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title> heatMap </title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"/>
<link href="../lib/mapboxgl/mapbox-gl.css" rel="stylesheet"/>
<script src="../lib/mapboxgl/mapbox-gl.js"></script>
<script src="../lib/mapboxgl/turf.min.js"></script>
<style>
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
.input-card {
position: relative;
top: 20px;
}
</style>
</head>
<body>
<div id="map" style="width: 100%; height: 100%"></div>
<div id='text'></div>
<div class="input-card" style="width: 24rem">
<div class="input-item">
<button class="btn" style="margin-right: 1rem" onclick="addHeat()">添加heat图层</button>
<button class="btn" onclick="upHeatData()">更改数据</button>
<button class="btn" onclick="delHeat()">删除图层</button>
<button class="btn" style="margin-right: 1rem" onclick="hideHeat()">heat隐藏</button>
<button class="btn" onclick="showHeat()">heat展示</button>
</div>
</div>
<script>
var map, popupDOM;
mapboxgl.accessToken =
'pk.eyJ1IjoiZXRlcm5pdHkteHlmIiwiYSI6ImNqaDFsdXIxdTA1ODgycXJ5czdjNmF0ZTkifQ.zN7e588TqZOQMWfws-K0Yw';
initMap();
function initMap() {
map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
zoom: 11,
// 地图中心点
center: [106.337428, 38.3390923],
// 地图默认字体
localIdeographFontFamily: "Microsoft YoHei",
});
map.on("click", (e) => {
popupDOM.remove();
console.log(`${e.lngLat.lng},${e.lngLat.lat}`);
});
map.on('load', () => {
// Insert the layer beneath any symbol layer.
const layers = map.getStyle().layers;
const labelLayerId = layers.find(
(layer) => layer.type === 'symbol' && layer.layout['text-field']
).id;
popupDOM = new mapboxgl.Popup({
// closeButton: false,
closeOnClick: false,
offset: {
bottom: [0, -40]
}
});
});
map.on('mouseenter', 'heatDemos', (e) => {
console.log(e.features[0].geometry);
let features = e.features[0].properties;
document.getElementById('text').innerHTML = "";
for (let key in features) {
let div = document.createElement('div');
div.innerHTML = key + " : " + features[key];
document.getElementById('text').appendChild(div);
}
popupDOM.setLngLat(e.features[0].geometry.coordinates)
.setHTML(document.getElementById('text').innerHTML)
.setMaxWidth('400px')
.addTo(map)
});
}
// 添加icon
function addHeat(/*heatParam*/) {
let heatParam = {
layerId: 'heatDemo',
data: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106.33, 38.333]
},
properties: {
name: '测试点',
value: 4
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 64
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 164
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 114
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 6
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 4
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 64
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 104
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 64
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 64
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 4
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 1
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 2
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 3
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 5
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 31
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 22
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 44
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 13
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 5
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 2
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 1
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 6
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 7
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 8
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 9
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 22
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 13
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 13
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 11
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 14
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 41
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 31
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 21
}
}]
};
//画 heat
if (map.getLayer(heatParam.layerId) == null) {
map.addLayer({
id: heatParam.layerId,
type: 'heatmap',
source: {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: heatParam.data
}
},
layout:{
visibility: 'visible',
},
paint: {
// 详见下方 PaintOptions
'heatmap-weight': [
// 衡量单个点对热图的贡献程度
'interpolate',
['linear'],
['get', 'value'],
0,
0,
150,
1.5
],
'heatmap-intensity': [
// 用于根据缩放级别调整热图
'interpolate',
['linear'],
['zoom'],
0,
1,
17,
10
],
"heatmap-color": [
"interpolate",
["linear"],
["heatmap-density"],
0,
"rgba(255, 0, 0, 0)",
0.1,
"rgba(0, 30, 255, .6)",
0.2,
"rgba(7, 208, 255, .6)",
0.3,
"#2cc946",
0.4,
"#d5fb0c",
0.5,
"#e04e4e",
0.6,
"#f33900",
0.9,
"rgba(243, 57, 0, .6)",
1.5,
"rgba(243, 57, 0, .8)"
],
'heatmap-radius': [
// 根据像素来定义半径
'interpolate',
['linear'],
['zoom'],
0,
10,
14,
30
],
'heatmap-opacity': [
// 根据缩放强度定义透明度
'interpolate',
['linear'],
['zoom'],
5,
0.8,
17,
0.8
]
}
})
// 圆形
map.addLayer({
id: heatParam.layerId+"s",
type: 'circle',
source: {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: heatParam.data
}
},
layout:{
visibility: 'visible',
},
paint: {
'circle-radius': [
'interpolate',
['linear'],
['zoom'],
0,
10,
14,
30
],
'circle-color': {
property: 'value',
type: 'exponential',
stops: [
[0, 'rgba(236,222,239,0)'],
[10, 'rgb(236,222,239)'],
[20, 'rgb(208,209,230)'],
[30, 'rgb(166,189,219)'],
[40, 'rgb(103,169,207)'],
[50, 'rgb(28,144,153)'],
[60, 'rgb(1,108,89)']
]
},
'circle-opacity': 0.1,
'circle-stroke-color': 'white',
'circle-stroke-width': 1,
'circle-stroke-opacity': 0.1
}
});
} else {
upHeatData(/*iconParam*/);
}
}
function upHeatData(/*iconParam*/) {
let heatParam = {
layerId: 'heatDemo',
data: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106.33, 38.333]
},
properties: {
name: '测试点',
value: 4
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 64
}
}, {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [106 + Math.random(), 38 + Math.random()]
},
properties: {
name: '测试点',
value: 164
}
}]
};
map.getSource(heatParam.layerId).setData({
type: 'FeatureCollection',
features: heatParam.data
})
map.getSource(heatParam.layerId+"s").setData({
type: 'FeatureCollection',
features: heatParam.data
})
}
// 移除icon
function delHeat(/*id*/) {
if (map.getLayer("heatDemo")) {
map.removeLayer("heatDemo");
map.removeSource("heatDemo");
}
}
function hideHeat(/*id*/) {
var visibility = map.getLayoutProperty("heatDemo", 'visibility');
if (visibility === 'visible') {
map.setLayoutProperty("heatDemo", 'visibility', 'none')
map.setLayoutProperty("heatDemos", 'visibility', 'none')
}
}
function showHeat(/*id*/) {
var visibility = map.getLayoutProperty("heatDemo", 'visibility');
if (visibility === 'none') {
map.setLayoutProperty("heatDemo", 'visibility', 'visible')
map.setLayoutProperty("heatDemos", 'visibility', 'visible')
}
}
</script>
</body>
</html>