在项目开发中,遇到地图上有很多点位要展示时,使用点图层PointLayer的简单点,在缩放等级较大时,看起来效果正常,但缩放等级变小后,整个地图都被点图层占满,看起来很不协调,今天就使用点图层PointLayer的另一种类型——聚合图。
聚合图:顾名思义就是根据某一区域点的集中程度,自动算出这一区域聚集中心。缩放等级越小,聚合的数据越多,聚合中心也相对越大,如下图
实现代码
import { Scene, PointLayer } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
const scene = new Scene({
id: 'map',
map: new GaodeMap({
center: [ 120.19382669582967, 30.258134 ],
style: 'dark',
zoom: 3
})
});
scene.on('loaded', () => {
fetch('https://gw.alipayobjects.com/os/basement_prod/d3564b06-670f-46ea-8edb-842f7010a7c6.json')
.then(res => res.json())
.then(data => {
const pointLayer = new PointLayer({})
.source(data, {
cluster: true
})
.shape('circle')
.scale('point_count', {
type: 'quantile'
})
.size('point_count', [ 5, 10, 15, 20, 25 ])
.active(true)
.color('yellow')
.style({
opacity: 0.5,
strokeWidth: 1
});
scene.addLayer(pointLayer);
});
});
若想使用自定义的简单数据来实现聚合图,以下是简单案例
实现代码如下。特别注意:如 缩放等级为6时,地图上展示2个点位,缩放等级更改为5时,地图上展示1个聚合点(该聚合点的坐标会根据聚合点内所有坐标取中间值动态计算,暂不支持固定经纬度写入),若给点图层添加事件(click、mouseenter),普通点位能展示当前点位信息,聚合图不能展示聚合内所有点位的信息
import { onMounted } from 'vue'
import ChinaJson from '@/assets/json/China.json'
import { Scene, PolygonLayer, LineLayer, PointLayer } from '@antv/l7';
import { Map } from '@antv/l7-maps';
let scene: any; //地图实例
let pointList = [
{
id: 1,
name: '点位1',
lat: 31.805850550197775,
lng: 100.0627789619167
},
{
id: 2,
name: '点位2',
lat: 31.817060785568714,
lng: 100.66960236143416
},
{
id: 3,
name: '点位3',
lat: 31.626301949273454,
lng: 101.7777146562068
},
{
id: 4,
name: '点位4',
lat: 31.682448232557164,
lng: 102.6087988772851
},
{
id: 5,
name: '点位5',
lat: 31.682448232557164,
lng: 103.59818485475921
},
{
id: 6,
name: '点位6',
lat: 31.682448232557164,
lng: 104.48203632796947
},
{
id: 7,
name: '点位7',
lat: 31.615068623098026,
lng: 105.74845037913633
}
]
function initMap() {
scene = new Scene({
id: 'map',
logoVisible: false,
map: new Map({
center: [120.19382669582967, 30.258134],
style: 'dark',
zoom: 3.5
})
});
scene.on('loaded', () => {
//添加区域图层
addPolygon()
//添加点位图层
addPointLayers()
})
}
function addPolygon() {
let ChinaLayer = new PolygonLayer()
.source(ChinaJson)
.color('#ccc')
let ChinaLineLayer = new LineLayer()
.source(ChinaJson)
.color('red')
scene.addLayer(ChinaLayer)
scene.addLayer(ChinaLineLayer)
}
function addPointLayers() {
//聚合图点位
let pointLayer = new PointLayer()
.source(pointList, {
parser: {
type: 'json',
x: 'lng',
y: 'lat'
},
cluster: true //是否启用聚合图
})
.scale('point_count', {
type: 'quantile'
})
.color('green')
.size('point_count', [5, 10, 15, 20, 25]) //最大尺寸25,最小尺寸5,自适应
.shape('circle')
//聚合图点位文字
let pointLayerText = new PointLayer({
autoFit: false
})
.source(pointList, {
parser: {
type: 'json',
x: 'lng',
y: 'lat'
},
cluster: true //是否启用聚合图
})
.shape('point_count', 'text')
.size(15)
.active(true)
.color('#fff')
.style({
strokeWidth: 0,
stroke: '#fff'
});
scene.addLayer(pointLayer)
scene.addLayer(pointLayerText)
}
onMounted(() => {
initMap()
})