Mapbox GL群集缩放 [英] Mapbox GL cluster zoom

查看:343
本文介绍了Mapbox GL群集缩放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当用户单击集群时,我试图显示所有标记.

I'm trying to show all the markers when the user click 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
        });
    }
});

每次用户单击标记时,这将添加2级缩放.它可以正常工作,但有时我需要进行更大的缩放才能看到标记.

This is adding 2 levels of zoom every time the user click on a marker. It works but sometimes I need to zoom even more to see the markers.

关于我如何单击即可放大实际标记的任何建议?

Any suggestion about how I could zoom to the actual markers with a single click?

推荐答案

考虑到当前版本的Mapbox-gl 0.37.0,这有点复杂.

This is a bit of a complicated solution given the current version of Mapbox-gl 0.37.0.

当用户单击集群时,我试图显示所有标记

I'm trying to show all the markers when the user click on a cluster

根据这一陈述,有两种可能的解决方案.

There are two possible solutions given this one statement.

  1. 在下一个缩放级别显示标记以及聚类,或者
  2. 显示所有标记(与缩放级别无关).

mapbox-gl中,集群功能由超级集群提供.

In mapbox-gl, the clustering functionality is provided by supercluster.

0.37.0开始,当您通过map.addSource...

因此,在使用mapbox-gl的条目文件中(通过npm或其他方式),您可能需要使用/导入超级集群作为库依赖项.

therefore you may need to use/import supercluster as a library dependency in your entry file where mapbox-gl is used (either via npm or otherwise).

1.使用超级群集查找标记取消群集时的下一个缩放级别.

在超级集群中,可以使用方法getClusterExpansionZoom(clusterId, clusterZoom),这将为您提供所选集群的下一个缩放,从中可以看到标记(是否是currentZoomLevel中的1,2,4,n zoomlevels.

In supercluster, you can use the method getClusterExpansionZoom(clusterId, clusterZoom), this gives you the next zoom for the selected cluster from where markers can be seen (whether that is 1,2,4,n zoomlevels from 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.

We do the a similar thing as above, but instead of using just nextZoomLevel / getClusterExpansionZoom, we can use the getLeaves.

getLeaves返回集群中的所有标记-

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.

From here, you can render the leaves as mapbox.Markers if required, similar to leaflet.markercluster.

第二种解决方案的问题是,只要视图已更改,就需要删除/更新标记,以反映地图视图的当前位置.

The problem with the second solution is that you need to remove/update the markers whenever the view has been changed, in order to reflect the current position of the mapview.

从上到下的角度来看,这是可以的,但是,如果您开始旋转,则视图渲染会有点刺痛,因此从UI的角度来看,我不建议这样做.

From a top-down perspective, this is ok, but if you start pivoting, the view render gets a bit jank, so I wouldn't recommend that from a UI perspective.

这篇关于Mapbox GL群集缩放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆