前端技術選型 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.實現效果