Mapbox GL cluster zoom

I try to show all tokens when a user clicks on a cluster.

This is what I have done so far:

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
        });
    }
});

This adds 2 zoom levels each time the user clicks on the marker. It works, but sometimes I need to scale even further to see markers.

Any suggestion on how I can scale to actual markers with one click?

+4
source share
2 answers

This is a bit tricky, considering the current version of Mapbox-gl 0.37.0.

I try to show all tokens when a user clicks on a cluster

There are two possible solutions to this single statement.

  • ( ).

mapbox-gl supercluster.

0.37.0 API map.addSource...

/ , mapbox-gl ( npm, ).

1. , .

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.

, / , , mapview.

, , , .

+1
0

All Articles