:::warning 聚合实现逻辑:在数据源中开启聚合效果,图层通过筛选是否存在point_count值,分别展示不同效果。 :::
一、地图展示效果
二、聚合效果初步实现
1、添加数据源
export const addCluster = async (map,list) => {let features = []features = list.map((item) => {return {type: 'Feature',geometry: {type: 'Point',coordinates: item.lnglat, // 点位经纬度[lng,lat]},properties: item,}})map.addSource(`test_points`, {type: 'geojson', // geojson类型资源data: {/* geojson数据 */type: 'FeatureCollection',features: features,},cluster: true, // 是否开启聚合clusterMaxZoom: 15, //最大缩放到聚合clusterRadius: 100, // 每一组点的半径,默认50})}
2、添加图标
export const addImages = async (map) => {// 注册图标let icon = require('@/assets/images/icon_ranks_warehouse@2x.png') // 图标地址,可自定义,也可传值map.loadImage(icon, (err, imgIcon) => {map.addImage(`test-icon`, imgIcon)})}
3、添加图层
export const addLayers = async (map) => {// 外围有数字的圆圈,加晕染(聚合点)map.addLayer({id: 'cluster-point-layer',type: 'circle',// minzoom: 12,source: 'test_points',filter: ['has', 'point_count'], // 筛选已聚合的点paint: {'circle-color': '#ff9969', // 圆圈颜色'circle-radius': 20, // 圆圈'circle-stroke-color': 'rgba(255, 153, 105,0.5)',// 光晕颜色'circle-stroke-width': 7, // 光晕大小,单位px},})// 聚合图圆圈中的数字map.addLayer({id: 'cluster-count-layer',type: 'symbol',source: 'test_points',filter: ['has', 'point_count'], // 筛选已聚合的点layout: {'text-field': '{point_count_abbreviated}','text-size': 11,},// 文字样式属性paint: {'text-color': '#fff','text-opacity': 1,},})// 离散在外部的图标map.addLayer({id: `discrete-ponit-layer`,type: 'symbol',source: `test_points`,filter: ['!', ['has', 'point_count']],layout: {'text-field': `{label}`,'text-size': 12,'icon-image': `test-icon`,'icon-size': 0.25,'icon-offset': [0, 0],'text-offset': [0, 1],'text-anchor': 'top','icon-allow-overlap': true,'icon-ignore-placement': true,'text-allow-overlap': true, // 是否允许文本重叠(可选,默认值为 false。当值为 true 时,文本即使和其他符号触碰也会显示)'text-ignore-placement': false, // 是否忽略文本位置(可选,默认值为 false。当值为 true 时,其他符号即使与此文本触碰也会显示)'text-optional': false, // 文本是否可不显示(可选,默认值为 false。当值为 true 时,如果文本与图标碰撞,则显示图标)},paint: {'text-color': 'rgba(255,255,255,0)',},})// 聚合图标点击效果,下探一层map.on('click', 'cluster-point-layer', (e) => {var features = map.queryRenderedFeatures(e.point, {layers: ['cluster-point-layer'],})var clusterId = features[0].properties.cluster_idmap.getSource('test_points').getClusterExpansionZoom(clusterId, function (err, zoom) {if (err) returnmap.easeTo({center: features[0].geometry.coordinates,zoom: zoom,})})})}}
三、权重效果添加
方法1,利用step进行范围筛选
(其他代码如二 — addLayers所示)
// 外围有数字的圆圈,加晕染(聚合点)map.addLayer({id: 'cluster-point-layer',type: 'circle',// minzoom: 12,source: 'test_points',filter: ['has', 'point_count'], // 筛选已聚合的点paint: {'circle-color': '#ff9969','circle-radius': ['step',['get', 'point_count'],20, // 当点数小于100时为20px圆100, // 筛选条件,点数100以内21, // 点计数在100到750之间时为21px圆750, //筛选条件,点数750以内22, //点计数大于或等于750时为22像素的圆],'circle-stroke-color': 'rgba(255, 153, 105,0.5)','circle-stroke-width': ['step', ['get', 'point_count'], 5, 100, 6, 750, 7], // 同上'circle-radius'},})
方法2:根据mapbox表达式计算
// 外围有数字的圆圈,加晕染(聚合点)map.addLayer({id: 'cluster-point-layer',type: 'circle',// minzoom: 12,source: 'test_points',filter: ['has', 'point_count'], // 筛选已聚合的点paint: {'circle-color': '#ff9969','circle-radius': ['*', 0.5, ['get', 'point_count']], // point_count值*0.5'circle-stroke-color': 'rgba(255, 153, 105,0.5)','circle-stroke-width': ['*', 0.1, ['get', 'point_count']], // 同上'circle-radius'},})
四、其他效果实现
其他代码与二相同,只替换了 addLayers 方法
export const addLayers = async (map,countLength) => {// countLength为图标总数// 聚合图标(权重、数字)map.addLayer({id: 'cluster-point-layer',type: 'symbol' /* symbol类型layer,一般用来绘制点*/,source: `test_points`,filter: ['has', 'point_count'],layout: {'text-field': '{point_count_abbreviated}','text-size': 14,'icon-image': `test-icon`,'icon-size': ['*', 0.25, ['+', 1, ['/', ['get', 'point_count'], countLength]]],'text-offset': {property: 'point_count', // 属性名(填写后 stops 的输入值就是对应的属性值)stops: [// 断点(除了 type 为 identity 外必填,由输入值和输出值为一组,作为数组的元素)[0, [-0.1, -1.5]], // 属性 point_count 的值为 0 时,text-offset 为 [-0.1, -1.5][countLength, [-0.1, -2.2]], // 属性 point_count 的值为 countLength 时,text-offset 为 [-0.1, -2.2]],}, //property function可以限定最大值最小值,对其中的数值进行平滑插入变化'icon-allow-overlap': true,'icon-ignore-placement': true,'text-allow-overlap': true, // 是否允许文本重叠(可选,默认值为 false。当值为 true 时,文本即使和其他符号触碰也会显示)'text-ignore-placement': false, // 是否忽略文本位置(可选,默认值为 false。当值为 true 时,其他符号即使与此文本触碰也会显示)'text-optional': false, // 文本是否可不显示(可选,默认值为 false。当值为 true 时,如果文本与图标碰撞,则显示图标)},paint: {'text-color': 'rgba(255,255,255,1)','text-opacity': 1, // 文本的不透明度(可选,取值范围为 0 ~ 1,默认值为 1)// 'text-color': '#000000', // 文本的颜色(可选,默认值为 #000000)},})// 离散图标map.addLayer({id: `discrete-ponit-layer`,type: 'symbol' /* symbol类型layer,一般用来绘制点*/,source: `test_points`,filter: ['!', ['has', 'point_count']],layout: {'icon-image': `ss-icon`,'icon-size': 0.25,'icon-offset': [0, 0],'icon-allow-overlap': true,'icon-ignore-placement': true,},})
