我试图在用户点击群集时显示所有标记.
这是我到目前为止所做的:
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];
if (cluster_feature && cluster_feature.properties.cluster) {
map.jumpTo({
around: e.lngLat,
zoom: map.getZoom() + 2
});
}
});
每次用户点击标记时,这会增加2级缩放.它有效,但有时我需要进一步缩放以查看标记.
有关如何通过单击缩放到实际标记的任何建议?
最佳答案 鉴于当前版本的Mapbox-gl 0.37.0,这是一个复杂的解决方案.
I’m trying to show all the markers when the user click on a cluster
给出这一陈述有两种可能的解决方案.
>在下一个缩放级别显示标记和聚类
>显示所有标记(与缩放级别无关).
在mapbox-gl中,群集功能由supercluster提供.
从0.37.0开始,没有直观的API来定制通过map.addSource设置源代码时超级集群的工作方式…
因此,您可能需要在使用mapbox-gl的条目文件中使用/ import supercluster作为库依赖项(通过npm或其他方式).
1.使用超级集群查找标记取消群集时的下一个缩放级别.
在超级集群中,您可以使用方法getClusterExpansionZoom(clusterId,clusterZoom),这将为您提供所选集群的下一个缩放,从中可以看到标记(无论是1,2,4,还是来自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.显示所有标记(与缩放级别无关).
我们执行与上面类似的操作,但是我们可以使用getLeaves而不是仅使用nextZoomLevel / getClusterExpansionZoom.
getLeaves returns all markers from the cluster –
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.
第二种解决方案的问题是,只要视图被更改,您就需要删除/更新标记,以反映mapview的当前位置.
从上到下的角度来看,这没关系,但是如果你开始透视,那么视图渲染会有点凹凸不平,所以我不建议从UI的角度来看.