问题提出
给定一系列具有不同属性大小的点(如相关性),相关性越大点的颜色越红,半径越大。点越密集,热力图的颜色越深。样例如下图所示。
问题思考
我们如何用mapbox实现这个效果呢?在mapbox studio中有绘制heatmap的功能,但同一图层每个点的半径只能设置成一样的,如果为不同的点设置不同的图层,就会超出mapbox的限制。这时候我们就可以考虑调用功能更为灵活的mapbox GS接口。仿照官网的样例(https://docs.mapbox.com/mapbox-gl-js/example/heatmap-layer/),我们可以得出以下代码
代码实现
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>绑定属性数值大小的热力图</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.5.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.5.0/mapbox-gl.css' rel='stylesheet' />
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
;
</style>
</head>
<body>
<div id='map'></div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoidnZmZ2ZnIiwiYSI6ImNqdzdsdHo1eDF5aWs0OW56dGo1NHo0Y3MifQ.S5HzUS4CiqLOyQIJc0HmbQ';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/vvfgfg/ck3o4yf0j1r4w1dnki6inrua2',
//style采用的之前自定义的黑色背景+道路亮化
center: [151.191423,-33.888681],
//设置初始化时视图的中心点
zoom: 12
//设置用户视角的缩放,zoom越大缩放越大
});
map.on('load', function () {
// Add a geojson point source.
// Heatmap layers also work with a vector tile source.
map.addSource('trafficdata', {
"type": "geojson",
"data": "*/绑定属性的热力图/test.geojson"
//相关性数据的json文件地址
});
//添加热力范围区域的图层
map.addLayer({
"id": "traffic-heat",
"type": "heatmap",
"source": "trafficdata",
"maxzoom": 20,
"paint":{
// Increase the heatmap weight based on frequency and property magnitude
"heatmap-weight": [
"interpolate",
["linear"],
["get", "correlation"], //获取相关性的值
0, 0,
5, 1,
//表示correlation从0变化到5时,heatmap-weight从0变化到1
] ,
// Increase the heatmap color weight weight by zoom level
// heatmap-intensity is a multiplier on top of heatmap-weight
"heatmap-intensity": [
"interpolate",
["linear"],
["zoom"],
0, 0,
5, 1
//表示correlation从0变化到5时,heatmap-intensity从0变化到1
],
"heatmap-color": [
"interpolate",
["linear"],
["heatmap-density"],
0,"rgba(0, 0, 255, 0)",
0.1,"royalblue",
0.3,"cyan",
0.5,"lime",
0.7,"yellow",
1,"red"
//表示随着correlation的变化,颜色的变化
],
// Adjust the heatmap radius by zoom level
"heatmap-radius": [
"interpolate",
["linear"],
["zoom"],
8, 200,
15, 300
// 表示zoom在[0,9]内变化时heatmap-radius的变化
],
// Transition from heatmap to circle layer by zoom level
"heatmap-opacity": [
"interpolate",
["linear"],
["zoom"],
10, 1,
15, 0,
// 表示zoom在[0,9]内变化时heatmap-opacity的变化
],
}
});
//添加点的样式的图层
map.addLayer({
"id": "earthquakes-point",
"type": "circle",
"source": "trafficdata",
"minzoom": 7,
"paint": {
// 这里是一个嵌套关系,指的是点半径与zoom和correlation都有关
"circle-radius": [
"interpolate",
["linear"],
["zoom"],
7, [
"interpolate",
["linear"],
["get", "correlation"],
0, 1,
5, 4,
// 表示correlation在[0,9]内变化时circle-radius的变化
],
16, [
"interpolate",
["linear"],
["get", "correlation"],
1, 5,
6, 50,
// 表示correlation在[0,9]内变化时circle-radius的变化
]
],
//点的颜色随着correlation变化而产生的变化
"circle-color": [
"interpolate",
["linear"],
["get", "correlation"],
0,
"rgb(0, 0, 255)",
2.1,
"lime",
2.3,
"yellow",
2.5,
"red"
],
"circle-stroke-color": "white",
"circle-stroke-width": 1,
"circle-opacity": [
"interpolate",
["linear"],
["zoom"],
10, 1,
15, 0.8
// 表示zoom在[10,15]内变化时circle-opacity的变化
]
}
});
//添加标志的图层
map.addLayer({
"id": "points",
"type": "symbol",
"source": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
// feature for Mapbox DC
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [151.199044, -33.884015]
},
"properties": {
"title": "UTS",
"icon": "college"
}
}]
}
},
//添加图标的文字说明
"layout": {
"icon-image": ["concat", ["get", "icon"], "-15"],
// get the title name from the source's "title" property
"text-field": ["get", "title"],
"text-font": ["Open Sans Semibold", "Arial Unicode MS Bold"],
"text-offset": [0, 0.6],
"text-anchor": "top"
}
});
});
</script>
</body>
</html>
常见问题
由于用到了本地文件的绑定,直接用浏览器可能无法加载。因此需要在浏览器的快捷方式中加上--allow-file-access-from-files
(注意开头空一格),用修改过的快捷方式打开浏览器输入地址进行访问即可。