前端技术选型 mapbox gl.js+react+dva
1.构建mapview
并在mapbox onload 事件里面进行聚类点图层初始化
import React from 'react';
import styles from './MapView.css';
import mapboxgl from 'mapbox-gl';
import ClusterPointLayer from '../components/MapLayer/ClusterPointLayer';
import earthquakes from '../assets/data/earthquakes.geojson';
export default class MapView extends React.Component{
constructor(props) {
super(props);
}
componentDidMount() {
mapboxgl.accessToken = '自己申请的token';
let map = new mapboxgl.Map({
container: 'mapContainer',
style: 'mapbox://styles/mapbox/streets-v9',
maxZoom: 18,
minZoom: 0,
zoom:3,
center:[116,39]
});
map.on('load', () => {
//构造方法,传值map对象、数据对象、图层名称、是否显示标签
const pointlayer = new ClusterPointLayer(map, earthquakes, 'earthquakes', true);
pointlayer.addLayer();
});
}
render(){
return (<div id="mapContainer" className={styles.map}>
</div>);
}
};
2.封装ClusterPointLayer类
由于data默认就是geojson格式的,所以这里没有进行数据的解析
class ClusterPointLayer {
constructor(map, data, layername, islabel) {
this.map = map;
this.data = data;
this.layername = layername;
this.islabel = islabel;
}
addData = () => {
return {
"id": this.layername,
"type": "circle",
"source": {
"type": "geojson",
"data": this.data,
"cluster": true,
"clusterMaxZoom": 14, // Max zoom to cluster points on
"clusterRadius": 50, // Radius of each cluster when clustering points (defaults to 50)
},
filter: ["has", "point_count"],
paint: {
// Use step expressions (https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-step)
// with three steps to implement three types of circles:
// * Blue, 20px circles when point count is less than 100
// * Yellow, 30px circles when point count is between 100 and 750
// * Pink, 40px circles when point count is greater than or equal to 750
"circle-color": [
"step", ["get", "point_count"],
"#51bbd6",
100,
"#f1f075",
750,
"#f28cb1",
],
"circle-radius": [
"step", ["get", "point_count"],
20,
100,
30,
750,
40,
],
},
};
};
addLabelData = () => {
const name = this.layername;
return {
"id": "${name}-count",
"type": "symbol",
"source": name,
"filter": ["has", "point_count"],
"layout": {
"text-field": "{point_count_abbreviated}",
"text-size": 12,
},
};
};
addLayer = () => {
const option = this.addData();
this.map.addLayer(option);
if (this.islabel) {
const labeloption = this.addLabelData();
this.map.addLayer(labeloption);
}
}
}
export default ClusterPointLayer;
3.实现效果