【问题标题】:Getting Features from Clusters in OpenLayers?从 OpenLayers 中的集群获取功能?
【发布时间】:2014-10-24 09:09:36
【问题描述】:

我有一个包含许多不同位置的数组,其中包含名称和图片,当然还有经度和纬度。如果我直接把这些放到地图上,它就会变得杂乱无章。所以我尝试使用Clusters

从创建features开始:

 for(var i = 0; i < points.length; i++){
     features[i] = new ol.Feature({
     population: 4000,
     name : points[i].name,
     geometry: new ol.geom.Point(
     ol.proj.transform([
     points[i].long,
     points[i].lat],
     'EPSG:4326', oProjection))
     });
 }

然后我用具有特征的向量填充集群:

var vSource = new ol.source.Vector({ features: features});

var vFeatures = vSource.getFeatures();

var clusterSource = new ol.source.Cluster({
                   distance: 20,
                   source: vSource});

然后我用一些图标设置集群的样式

var clusters = new ol.layer.Vector({
          source: clusterSource,
          style : new ol.style.Style({
                image: new ol.style.Icon(({
                src: 'image/image.png'})),
          text: new ol.style.Text({
                font: '18px Helvetica, Arial Bold, sans-serif',
                text: size.toString(),
                fill: new ol.style.Fill({
                color: '#fff'
                })
})
 map.add(clusters)

我后来有一个 onclick 方法应该从特征中获取“名称”,但它唯一可以打印出来的是几何图形,就像对象上的名称从集群中消失一样。例如,执行clusterSource.getFeatures() 会返回一个空向量[]

function addOverlays(points){
    for(var i = 0; i<points.length;i++){
        var element = document.getElementById(points[i].id);
        var popup = new ol.Overlay({
            element: element,
            positioning: 'bottom-center',
            stopEvent: false
        });
        map.addOverlay(popup);
        // display popup on click
    }

    // display popup on click
    map.on('click', function(evt) {
        var feature = map.forEachFeatureAtPixel(evt.pixel,
            function(feature, layer) {
                console.log("feature on click: ",feature);
                return feature;
            });
        if (feature) {
            var geometry = feature.getGeometry();
            var coord = geometry.getCoordinates();
            popup.setPosition(coord);
            console.log(feature.get('name'));
            $(element).popover({
                'placement': 'bottom',
                'html': true,
                'content': feature.get('name') //THIS IS THE TROUBLE
            });
            $(element).popover('show');
        } else {
            $(element).popover('destroy');
        }
    });
}

addOverlay 方法无法获取特征名称,它返回“undefined”,这很奇怪。帮助?请问有什么帮助吗?就像添加到集群中的功能停止存在一样。

【问题讨论】:

    标签: javascript openlayers-3


    【解决方案1】:

    因此,通过聚类,OL3 创建了一个新功能,将所有聚类功能封装在其下。如果您查看集群特征,您会在 values 属性下看到:

    values_: Object
      features: Array[19]
      geometry: ol.geom.Point
    

    这就是为什么getFeatures() 不起作用的原因,在使用集群特征时,它们在创建时只有这两个值。

    function isCluster(feature) {
      if (!feature || !feature.get('features')) { 
            return false; 
      }
      return feature.get('features').length > 1;
    }
    
    map.on('click', function(evt) {
      var feature = map.forEachFeatureAtPixel(evt.pixel, 
                      function(feature) { return feature; });
      if (isCluster(feature)) {
        // is a cluster, so loop through all the underlying features
        var features = feature.get('features');
        for(var i = 0; i < features.length; i++) {
          // here you'll have access to your normal attributes:
          console.log(features[i].get('name'));
        }
      } else {
        // not a cluster
        console.log(feature.get('name'));
      }
    });
    

    【讨论】:

    • 一个非常好的解决方案,我仍然对非集群奇异特性有一些问题,但最终会到达那里。
    • @radhoo 我知道这很旧,但我偶然发现了同样的问题,我通过在 else 中将 feature.get('name') 替换为 feature.get('features').get('name') 来解决它。希望有帮助
    • Tim 的代码已经更正以支持单一特征和集群。您的评论是正确的,并且与发布的代码一致。
    • 当我们在单击事件中循环遍历 forEachFeatureAtPixel 时,我们应该得到我们点击的特定特征。但是当聚类处于活动状态时,我们有一个具有这样的特征数组的特征.. var features = feature.get('features');这里的 features 是一组原始特征。在这种情况下,我将如何找出我点击的确切功能?
    【解决方案2】:

    我还不能添加 cmets(没有足够的声誉),但我想添加我的解决方案,例如弹出窗口将显示在集群和非集群特征上。就像@Timh 的例子一样。

    但是当涉及到较低的缩放级别并且集群被“解散”时,当您单击集群中的(技术上仍然存在的)功能时,弹出窗口将只显示undefined

    所以,你可以用

    if (typeof feature.get('features') === 'undefined') {
      // feature.get('whatever');
    } else {
      var cfeatures = feature.get('features');
      for(var i = 0; i < cfeatures.length; i++) {
        //like in  the example of timh
      }
    }
    

    并从集群、非集群和当前未集群(以视觉方式)的特征中获取例如弹出窗口。

    编辑Example with Popups

    【讨论】:

      【解决方案3】:

      注意你的图层及其来源,我的错误是我应该设置:

      layer.getSource().getSource().getFeatures()
      

      代替:

      layer.getSource().getFeatures()
      

      【讨论】:

        【解决方案4】:

        我无法发表评论,因为我没有代表,但这是对 Timh 解决方案的评论,它很好但有一个缺陷(这就是为什么 radhoo 在他的评论中描述的单一功能存在问题)。

        “isCluster”函数不应该检查是否有一个或多个特征,因为即使它只包含一个特征,它仍然是一个集群

        function isCluster(feature) {
          return !feature || !feature.get('features');
        }
        

        因此最好以相同的方式处理所有集群,并可选择单独处理特征对象。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-07-15
          • 1970-01-01
          • 2019-04-04
          • 1970-01-01
          相关资源
          最近更新 更多