MapBox - 群集缩放

问题描述 投票:2回答:2

是否可以重新创建单击以放大聚类,就像Craigslist Mapview对MapBox一样?单击时,它会缩放到包含位置点的区域。

这是我的聚类代码:

map.on('load', function() {
map.addSource("location", {
    type: "geojson",
    data: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/73873/test.geojson",
    cluster: true,
    clusterMaxZoom: 14,
    clusterRadius: 100
});

    map.addLayer({
    id: "clusters",
    type: "circle",
    source: "location",
    filter: ["has", "point_count"],
    paint: {
        "circle-color": {
            property: "point_count",
            type: "interval",
            stops: [
                [0, "#71AAC6"],
                [100, "#71AAC6"],
                [750, "#71AAC6"],
            ]
        },
        "circle-radius": {
            property: "point_count",
            type: "interval",
            stops: [
                [0, 20],
                [100, 30],
                [750, 40]
            ]
        }
    }
});

这是我的演示

Codepen Demo

javascript mapbox mapbox-gl
2个回答
1
投票

正如@MeltedPenguin所说。没有SuperCluster你可以做到。我搜索了几个答案,最后使用coffeescript做了我自己的解决方案(你可以使用像http://js2.coffee/这样的工具将它转换回JS):

    @clusterRadius = 30
    @map.on 'click', (e) =>
          features = @map.queryRenderedFeatures(e.point, { layers: ['markers_layer'] });
          if features && features.length > 0
            if features[0].properties.cluster
              cluster = features[0].properties

              allMarkers = @map.queryRenderedFeatures(layers:['markers_layer_dot']);
              self = @ #just a way to use 'this' un a function, its more verbose then =>    

              #Get all Points of a Specific Cluster
              pointsInCluster = allMarkers.filter((mk) ->
                pointPixels = self.map.project(mk.geometry.coordinates) #get the point pixel
                #Get the distance between the Click Point and the Point we are evaluating from the Matrix of All point
                pixelDistance = Math.sqrt((e.point.x - (pointPixels.x)) ** 2 + (e.point.y - (pointPixels.y)) ** 2)

                #If the distant is greater then the disance that define a cluster,  then the point si in the cluster
                # add it to the boundaries
                Math.abs(pixelDistance) <= self.clusterRadius
              )

              #build the bounding box with the selected points coordinates
              bounds = new (mapboxgl.LngLatBounds)
              pointsInCluster.forEach (feature) ->
                bounds.extend feature.geometry.coordinates
                return

              #Move the map to fit the Bounding Box (BBox)
              @map.fitBounds bounds, {padding:45, maxZoom: 16}

            else
              window.open('/en/ad/' + features[0].properties.propertyId)

在我的页面上,我有2层基于相同的数据源但具有不同的属性。一个定义所有点(没有簇),另一个定义点和簇。对于我的显示器,我使用带有簇的“markers_layer”,并且为了计算距离和东西,我使用另一个,作为点的DB。

资源:

  @map.addSource "markers_source_wo_cluster",
    type: "geojson"
    data:
      type: "FeatureCollection"
      features: []
    cluster: false
    clusterMaxZoom: 10
    clusterRadius: @clusterRadius

  @map.addSource "markers_source",
    type: "geojson"
    data:
      type: "FeatureCollection"
      features: []
    cluster: true
    clusterMaxZoom: 60
    clusterRadius: @clusterRadius

层:

##============================================================##
## Add marker layer (Layer for QueryRender all dot without cluster)
##============================================================##
@map.addLayer
  id: 'markers_layer_dot'
  source: 'markers_source_wo_cluster'
  type: "circle"
  paint:
    "circle-radius": 0 #This are 1 pixel dot for ref only

##============================================================##
## Add marker layer
##============================================================##
@map.addLayer
  id: 'markers_layer'
  source: 'markers_source'
  type: 'symbol'
  layout:
    'icon-allow-overlap': true
    'icon-image':'pin_map'
    'icon-size':
      stops: [[0,0.4], [40,0.4]]

1
投票

我不认为你可以在纯Mapbox中做到这一点,至少不容易。

但是对于那些特定于群集的用法,有Supercluster(官方Mapbox地理空间点聚类库),它具有您想要的内容:

getClusterExpansionZoom(clusterId)

给定群集的cluster_id,返回群集扩展为多个子节点的缩放(对于“单击缩放”功能很有用)。

编辑:实际上你可以在没有Supercluster的情况下做到:

  1. 使用此JsFiddle example,您可以检索单击的群集的点。 map.on('click', function(e) { const cluster = map.queryRenderedFeatures(e.point, { layers: ["cluster"] }); if (cluster[0]) { // features: from the added source that are clustered const pointsInCluster = features.filter(f => { const pointPixels = map.project(f.geometry.coordinates) const pixelDistance = Math.sqrt( Math.pow(e.point.x - pointPixels.x, 2) + Math.pow(e.point.y - pointPixels.y, 2) ); return Math.abs(pixelDistance) <= clusterRadius; }); console.log(cluster, pointsInCluster); } });
  2. 然后你可以用所有这些点创建一个mapboxgl.LngLatBoundsextend
  3. 你将获得包含所有积分的LngLatBounds,这样你就可以在它上面调用fitBounds,你就可以了。
© www.soinside.com 2019 - 2024. All rights reserved.