【问题标题】:How to hide and show features in OpenLayers 3? (Redraw?)如何在 OpenLayers 3 中隐藏和显示功能? (重画?)
【发布时间】:2016-03-21 18:45:02
【问题描述】:

我正在将一个项目从 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 选项像其他除了向量之外的来源。调度事件和更改也不起作用。我希望改变会,但没有任何反应。

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

我还想知道是否以这种方式更改样式(将每个功能获取到另一个 var),或者这是否不会仅更改该功能并保持原始不变。再加上总是获取getSource().getFeatures() 似乎对性能有辱骂......但我似乎找不到其他方法。

无论如何,现在如何在 OL3 中执行重绘以渲染样式已更改的特征?可以将图层设置为可见,但我不想一直隐藏/显示所有功能。有时我只想根据给定的 id 隐藏/显示一些。

【问题讨论】:

    标签: javascript openlayers openlayers-3


    【解决方案1】:

    另一种方法是在特征上使用样式函数和隐藏属性:

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

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

    【讨论】:

    • 这对我来说似乎是一种更清洁的方法。
    • @David 你能扩展一下吗? HIDDEN 是任意选择的属性,不是在 OL3 上定义的,对吧?
    【解决方案2】:

    因此,在一遍又一遍地查看文档时,我终于找到了触发更改事件的原因,就像 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);
            }
        }
    },
    

    【讨论】:

      【解决方案3】:

      我无法添加 cmets,因为我没有足够的声誉,但您可能想调用 feature.setStyle(null) 而不是 feature.style = null,因为这会在内部触发 changed 事件,并且应该会立即自动更改样式。 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 虽然我不太确定如何展示我在这里实现的解决方案,但我想我可以自己回答吗?
      【解决方案4】:

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

      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>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-29
        • 1970-01-01
        • 1970-01-01
        • 2013-03-20
        • 1970-01-01
        相关资源
        最近更新 更多