鉴于 Mapbox-gl 的当前版本,这是一个有点复杂的解决方案0.37.0
。
当用户单击集群时,我正在尝试显示所有标记
鉴于这一说法,有两种可能的解决方案。
- 在下一个缩放级别显示标记和集群或
- 显示所有标记(与缩放级别无关)。
其中mapbox-gl
,集群功能由supercluster提供。
截至0.37.0
目前,当您通过以下方式设置源时,没有直观的 API 可以自定义超集群的工作方式map.addSource...
因此,您可能需要在使用的入口文件中使用/导入超集群作为库依赖项mapbox-gl
(通过 npm 或其他方式)。
1. 使用 supercluster 查找标记去簇时的下一个缩放级别。
在超集群中,您可以使用方法getClusterExpansionZoom(clusterId, clusterZoom)
,这将为您提供所选集群的下一次缩放,从中可以看到标记(无论是1,2,4,n
zoomlevels
从currentZoomLevel
.
var supercluster = require('supercluster');
let features;
map.on('load', function(e) {
features = supercluster().load(FEATURES);
});
// helper function
function findNearestCluster(map, marker, i) {
let clusterSelected = marker;
// get bounds
let south = map.getBounds()._sw;
let north = map.getBounds()._ne;
let bounds = [south.lng, south.lat, north.lng, north.lat];
let currentClusters = i.getClusters(bounds, Math.floor(map.getZoom()));
let compare = {
lng: clusterSelected.geometry.coordinates[0],
lat: clusterSelected.geometry.coordinates[1]
};
let minClusters = currentClusters.map(cluster => {
let lng = cluster.geometry.coordinates[0];
let lat = cluster.geometry.coordinates[1];
return {
id: cluster.properties.cluster_id,
geometry: cluster.geometry,
value: Math.pow(compare.lng - lng,2) * Math.pow(compare.lat-lat,2)
};
});
return minClusters.sort(function(a,b) {
return a.value - b.value;
});
}
map.on('click', function (e) {
var cluster_features = map.queryRenderedFeatures(e.point, {
layers: [
'cluster-0',
'cluster-1',
'cluster-2'
]
});
var cluster_feature = cluster_features[0];
// we need to find the nearest cluster as
// we don't know the clusterid associated within supercluster/map
// we use findNearestCluster to find the 'nearest'
// according to the distance from the click
// and the center point of the cluster at the respective map zoom
var clusters = findNearestCluster(map, cluster_feature, features);
var nearestCluster = clusters[0];
var currentZoom = Math.floor(map.getZoom());
var nextZoomLevel = supercluster()
.getClusterExpansionZoom(nearestCluster.id, currentZoom);
if (cluster_feature && cluster_feature.properties.cluster) {
map.jumpTo({
around: e.lngLat,
zoom: nextZoomLevel
});
}
});
2. 显示所有标记(与缩放级别无关)。
我们做与上面类似的事情,但是我们可以使用. 而不是只使用nextZoomLevel
/ 。getClusterExpansionZoom
getLeaves
getLeaves 返回集群中的所有标记 -
var clusters = findNearestCluster(map, cluster_feature, features);
var nearestCluster = clusters[0];
var currentZoom = Math.floor(map.getZoom());
var getLeaves = supercluster()
.getLeaves(nearestCluster.id, currentZoom, Infinity);
从这里,您可以根据mapbox.Markers
需要渲染叶子,类似于leaflet.markercluster
.
第二种解决方案的问题是,每当视图发生更改时,您都需要删除/更新标记,以反映地图视图的当前位置。
从自上而下的角度来看,这没问题,但是如果您开始旋转,视图渲染会有点卡顿,所以从 UI 角度来看,我不建议这样做。