有没有办法在 openlayers 中更新功能的样式?

Is there a way to update feature's style in openlayers?

我根据数据库中的一些数字对一些标记进行了着色。我的脚本会定期执行查询,询问我的号码。如果满足某些条件,我希望我的标记改变颜色,例如从绿色到黄色。

一个类似的问题是这些标记的半径在缩放地图时应该增加。我通过更新在更改缩放时唤醒的侦听器中的半径来解决此问题。

var currZoom = map.getView().getZoom();
map.on('moveend', function(e) {
    var newZoom = map.getView().getZoom();
    if (currZoom != newZoom) {
        console.log('zoom end, new zoom: ' + newZoom);
        currZoom = newZoom;
        vectorSource.clear();
        var greenStyle = new ol.style.Style({
            image: new ol.style.Circle({
                radius: Math.pow(33,newZoom/5)/15000,
                fill: new ol.style.Fill({color: 'rgba(0,255,0,0.5)'}),
                stroke: new ol.style.Stroke({
                    color: 'green', width: 1})
            })
         });
         var yellowStyle = new ol.style.Style({
             image: new ol.style.Circle({
                 radius: Math.pow(33,newZoom/5)/15000,
                 fill: new ol.style.Fill({color: 'rgba(255,255,0,0.5)'}),
                 stroke: new ol.style.Stroke({
                     color: 'yellow', width: 1})
              })
          });
         var redStyle = new ol.style.Style({
             image: new ol.style.Circle({
                 radius: Math.pow(33,newZoom/5)/15000,
                 fill: new ol.style.Fill({color: 'rgba(255,0,0,0.5)'}),
                 stroke: new ol.style.Stroke({
                     color: 'red', width: 1})
              })
          });

         for(var i=0;i<Features.length;i++){
             var oldcolor = Features[i]["g"]["e"]["a"]["a"];
             if(oldcolor=="green" || oldcolor=="yellow" || oldcolor=="red"){
                 if(oldcolor=="green"){
                     Features[i].setStyle(greenStyle);
                 }
                 else if(oldcolor=="yellow"){
                     Features[i].setStyle(yellowStyle);
                 }
                 else{
                     Features[i].setStyle(redStyle);
                  }
              }
          }
          vectorSource.addFeatures(Features);
     }
}); 

这行得通。当我缩放半径时改变它的值并且圆改变尺寸。

问题出在这个函数中,当我提到的那些情况发生时它会被调用。

                    function stampaMappa(r){
                        vectorSource.clear();
                        /*for(var j=0;j<Features.length;j++){
                            Features.pop();
                        }*/
                        Features = [];

                        for(var i=0;i<r.length;i++){

                            var id = r[i]["Sensor_id"];
                            var people = r[i]["tot"];
                            var index_color = r[i]["color"];
                            var sniffer_name = r[i]["Sniffer_name"];
                            var lon = parseFloat(r[i]["Sensor_longitude"]);
                            var lat = parseFloat(r[i]["Sensor_latitude"]);

                            var d = new Date();
                            var h = d.getHours();
                            var m = d.getMinutes();
                            var hrs = h+":"+m;

                            var areaFeature = new ol.Feature({
                                geometry: new ol.geom.Point(ol.proj.transform([lon,lat], 'EPSG:4326', 'EPSG:3857')),
                                  name: sniffer_name,
                                    tourists: people,
                                    hour: hrs
                            });
                            var iconFeature = new ol.Feature({
                                 geometry: new ol.geom.Point(ol.proj.transform([lon,lat], 'EPSG:4326', 'EPSG:3857')),
                                  name: sniffer_name,
                                    tourists: people,
                                    hour: hrs
                            });

                            iconFeature.setStyle(iconStyle);
                            areaFeature.setStyle(colors[index_color])

                            Features.push(areaFeature);
                            Features.push(iconFeature);


                        }
                        if(first_time){
                            vectorSource = new ol.source.Vector({
                                features: Features //add an array of features
                            });

                            vectorLayer = new ol.layer.Vector({
                                name:"test",
                                source: vectorSource
                            });

                            map.addLayer(vectorLayer);
                            // Set the view for the map
                            map.setView(view);

                        }
                        else{
                            vectorSource.addFeatures(Features);
                        }
                    }

我原以为它会起作用,但它只会删除我的标记。如果我放大或缩小它们会再次出现(因为缩放侦听器有效)。

您可以使用样式函数代替样式。每当地图呈现时调用该函数(每次更改分辨率都会发生)

    var greenStyle = function(feature, resolution) {
      return new ol.style.Style({
        image: new ol.style.Circle({
            radius: Math.pow(33,map.getView().getZoom()/5)/15000,
            fill: new ol.style.Fill({color: 'rgba(0,255,0,0.5)'}),
            stroke: new ol.style.Stroke({
                color: 'green', width: 1})
        })
      });
    }

在函数外定义一次基本样式并为每次调用设置半径更节省内存

    var greenBase = new ol.style.Style({
        image: new ol.style.Circle({
            radius: 1,
            fill: new ol.style.Fill({color: 'rgba(0,255,0,0.5)'}),
            stroke: new ol.style.Stroke({
                color: 'green', width: 1})
        })
      });

    var greenStyle = function(feature, resolution) {
      greenBase.getImage().setRadius(Math.pow(33,map.getView().getZoom()/5)/15000);
      return greenBase;
    }