如何在OpenLayers 3中隐藏和显示功能?(重绘?)

3
我是一名有用的助手,可以为您翻译文本。
我正在将一个项目从OL2更新到OL3,但我卡在了如何在更改要素样式后重新绘制要素上。
在OL2中,这样做是有效的:
hidePoints: function(id) {
    if (! this.getMap().center) {
        return;
    }

    var i,
    feature,    
    len = this.points.features.length;

   if (id !== null) {
    for( i = 0; i < len; i++ ) {         
      feature = this.points.features[i];
      if (feature.attributes.aces_id == id) {
          feature.style = null;
        } else {
            feature.style = { display: 'none' };
        }
      }
   } else {
      for( i = 0; i < len; i++ ) {         
        feature = this.points.features[i];
        feature.style = { display: 'none' };
      }
   }
 this.points.redraw();
},

在OL3中,我尝试更新函数以隐藏点图层,但是redraw()不再存在,由于我正在使用的图层是一个ol.layer.Vector,我无法像其他除向量以外的源一样找到任何updateParams选项。Dispatch Event和changed也没有起作用。我希望changed会起作用,但什么也没发生。
hidePoints: function(id) {
    if (! this.getMap().getView().getCenter()) {
        return;
    }

    var i,
        feature,
        layerSourceFeatures = this.pointsLayer.getSource().getFeatures(),
        len = layerSourceFeatures.length;

    if (id !== null) {
        for( i = 0; i < len; i++ ) {
            feature = this.pointsLayer.getSource().getFeatures()[i];

            if (feature.get('aces_id') == id) {
                feature.style = null;
            } else {
                feature.style = { display: 'none' };
            }
        }
    } else {
        for( i = 0; i < len; i++ ) {
            feature = this.pointsLayer.getSource().getFeatures()[i];
            feature.style = { display: 'none' };
        }
    }
    //this.pointsLayer.redraw();
    //this.pointsLayer.dispatchEvent(goog.events.EventType.CHANGE);
    this.pointsLayer.changed();
},

我还在想改变样式是否是这样做的(将每个特征提取到另一个变量中),或者是否只会更改该特征并保留原始内容。此外,总是获取getSource().getFeatures()似乎对性能有点滥用...但我似乎找不到其他方法。
无论如何,现在OL3中如何执行重绘以渲染已更改样式的要素?可以将图层设置为可见,但我不想一直隐藏/显示所有要素。有时我只想根据它们的给定ID隐藏/显示其中的一些要素。
4个回答

8
另一种方法是使用样式函数和要素上的隐藏属性:

var style = new ol.Style(...);

function Stylefunction (feature, resolution) {
    var prop = feature.getProperties();
    if (prop.HIDDEN)
       return;

    return style;
}

var layer = new ol.layer.Vector({
    source: new ol.source.Vector(...),
    style: Stylefunction 
});

如果您更改“隐藏”属性,它会立即刷新。


这对我来说似乎是一种更清晰的方法。 - wlf
1
@David,你能详细说明一下吗?HIDDEN是任意选择的属性,不是OL3上定义的,对吧? - Alex P.

3

在反复查看文档后,我终于找到了可以触发更改事件的方法,就像seto之后建议的那样。

这是我从OL2转换到OL3的函数,对我很有用。由于setStyle已经完成了所有工作,因此不再需要重新绘制。

hidePoints: function(id) {
    if (! this.getMap().getView().getCenter()) {
        return;
    }

    var i,
        feature,
        layerSourceFeatures = this.pointsLayer.getSource().getFeatures(),
        len = layerSourceFeatures.length;

    var emptyImgStyle = new ol.style.Style({ image: '' });

    // If an aces id was provided
    if (id !== undefined) {
        for( i = 0; i < len; i++ ) {
            feature = layerSourceFeatures[i];

            feature.setStyle(emptyImgStyle);

            // Resetting feature style back to default function given in defaultPointStyleFunction()
            if (feature.get('aces_id') == id) {
                feature.setStyle(null);
            }
            // Hiding marker by removing its associated image
            else {
                feature.setStyle(emptyImgStyle);
            }
        }
    }
    // No id was provided - all points are hidden
    else {
        for( i = 0; i < len; i++ ) {
            feature = layerSourceFeatures[i];
            feature.setStyle(emptyImgStyle);
        }
    }
},

0

我喜欢这种切换图层的方法(同样适用于其他功能):

JAVASCRIPT

<script>
    var layerBing = new ol.layer.Tile({
          source: new ol.source.BingMaps({
              imagerySet: 'Aerial',
              key: 'YourKeyBingAccess'
          }),
          name: 'Bing'
    });

    /*
    *  YOUR MAP CODE  GOES HERE
    */

    function toggleLayer(layerObject) {
        var newVisibility = !(layerObject.get('visible'));
        layerObject.set('visible', newVisibility);
    }
</script>

HTML

<button onclick="toggleLayer(layerBing)">Bing Satellite</button>
<div id="map" class="map"></div>

0

我无法添加注释,因为我没有足够的声望,但是你可以调用feature.setStyle(null)而不是feature.style = null,因为它会在内部触发更改事件,并应立即自动更改样式。 此外,feature.style = { display: 'none' } 在openlayers 3中不起作用,因为样式需要是ol.style.Style对象(http://openlayers.org/en/v3.14.2/apidoc/ol.Feature.html#setStyle)

如果您拥有要素的ID,则可以使用source.getFeatureById()方法而不是循环遍历要素。(http://openlayers.org/en/v3.14.2/apidoc/ol.source.Vector.html#getFeatureById)

关于呈现方面,我认为使用地图的map.render()(位于openlayers.org/en/v3.14.2/apidoc/ol.Map.html#render)将重新呈现地图。

如果你只是想在地图重新渲染时调用一个函数,你可以监听地图上的postrender或postcompose事件。

如果你创建了一个JSFiddle,我可以帮助你进一步。

编辑:这个例子可能会对你有所帮助 - openlayers.org/en/v3.14.2/examples/dynamic-data.html?q=style


谢谢您的评论,昨天我通过您提到的setStyle找到了一个我喜欢的解决方案。由于它们在值配置中根据ID隐藏/显示,因此功能的ID并没有帮助。 我不知道渲染或那个示例,谢谢! :D 虽然我不太确定如何在这里展示我实现的解决方案,但我想我可以自己回答? - Ada

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接