Openlayers 3 无法为向量层中单击的要素设置样式

Openlayers 3 无法为向量层中单击的要素设置样式,openlayers-3,Openlayers 3,因此,在我的Openlayers 3中,我设置了一个默认样式,在第一次加载层时渲染功能 function styleFunction(feature, resolution) { var color = feature.get('color'); var name = feature.get('name'); var fill = new ol.style.Fill({ color: color }); var stroke = new

因此,在我的Openlayers 3中,我设置了一个默认样式,在第一次加载层时渲染功能

function styleFunction(feature, resolution) {
    var color = feature.get('color');
    var name = feature.get('name');

    var fill = new ol.style.Fill({
        color: color
    });

    var stroke = new ol.style.Stroke({
        color: "black",
        lineCap: "butt",
        lineJoin: "bevel",
        width:1         
    });

    var text= new ol.style.Text({
        font: '20px Verdana',
        text: name,
        fill: new ol.style.Fill({
            color: [64, 64, 64, 0.5]
        })
    })

    var cStyle = new ol.style.Style({
        fill: fill,
        stroke: stroke,
        text: text
    });

    return [cStyle];
}
单击某个功能时,我希望该功能更改其样式,其余功能保持上面的默认样式

这是我的尝试

 //add simple click interaction to the map
 var select = new ol.interaction.Select();
 map.addInteraction(select);

//for every clicked feature
 select.on('select', function(e) {
       var name = e.selected[0].get('name');

       //set the clicked style
        var fillClick= new ol.style.Fill({
            color: "black"
         });

        var strokeClick = new ol.style.Stroke({
            color: "white",
            lineCap: "butt",
            lineJoin: "bevel",
            width:3         
        });

        var textClick= new ol.style.Text({
                font: '10px Verdana',
                text: name,
                fill: new ol.style.Fill({
                    color: [64, 64, 64, 1]
                })
            })

        var styleClick = new ol.style.Style({
            stroke: strokeClick,
            fill : fillClick,
            text : textClick
        });



    //set all to default
    for (i in e.selected){
        e.selected[i].setStyle(styleFunction);  
    }

    //reset the first selected to the clicked style
    e.selected[0].setStyle(styleClick);
我在控制台上没有发现任何错误,但这不起作用。单击其他功能时,单击的功能将不会返回默认样式。所有单击的功能都保留了
样式click

那么,我如何解决这个问题,还有,有没有更简单的方法?我认为这类功能需要很多代码

谢谢

编辑

我换了

    for (i in e.selected){
        e.selected[i].setStyle(styleFunction);  
    }

因此,现在所有特性都将获得
styleFunction
函数中定义的样式

这是行不通的。I get
uncaughttypeerror:feature.get不是一个函数
引用函数的第一行,
var color=feature.get('color')这个

我不能只设置一个样式,我需要它是一个函数,这样我就可以在将来检查geomerty类型

所以我的两个问题,

我不知道如何调试和修复这个错误

如果我有500个功能,每次单击都会重新绘制所有功能,这会减慢渲染速度。还有别的解决办法吗


谢谢更新

那么-


图层和要素样式功能不同

使用OpenLayers 3样式函数时,必须注意和之间的区别。它们非常相似,因为它们都应该基于特征和分辨率返回
ol.Style
s数组。但是,他们没有以同样的方式获得这些信息

当使用功能的
setStyle
方法向功能提供样式函数时,该函数应为
ol.FeatureStyleFunction
。调用
ol.FeatureStyleFunction
时,引用该功能的
this
,并将
分辨率
作为唯一参数

向层提供样式函数时,它应该是
ol.style.StyleFunction
。它们由两个参数调用,即
功能
分辨率

这就是你犯错误的原因。您正在使用
ol.style.StyleFunction
作为功能样式。稍后,当调用style函数时,第一个参数是分辨率,而不是期望的特性

解决方案1:setStyle(null)

这个解决方案已经在@jonatas walker的文章中提出。它的工作原理是在选定要素上设置样式,并从未选定要素中删除样式(而不是将样式功能设置为未选定要素)

OpenLayers将使用功能的样式(如果有),否则使用图层的样式。因此,将未选中特征的样式重新设置为null将使它们再次使用图层的样式功能

解决方案2:使用所选交互的
样式
选项
接受样式选项(一个
ol.style.StyleFunction
),该选项用于设置所选要素的样式

优点:对于图层(普通视图)有一个样式函数,对于选择交互有一个样式函数,这使得代码比混合特性和图层样式更可读。此外,您不必跟踪事件或修改功能

可以这样做:

var selectedStyleFunction = function(feature, resolution) {
    return [new ol.style.Style({
        stroke: new ol.style.Stroke({
            color: "white",
            lineCap: "butt",
            lineJoin: "bevel",
            width:3         
        }),
        fill : new ol.style.Fill({
            color: "black"
        }),
        text : new ol.style.Text({
            font: '10px Verdana',
            text: feature.get('name'),
            fill: new ol.style.Fill({
                color: [64, 64, 64, 1]
            })
        })
    })];
};
var select = new ol.interaction.Select({
    style: selectedStyleFunction
});
map.addInteraction(select);

答案解释得很好。让我们来分报酬吧?@JonatasWalker,谢谢。有可能分享奖金吗?开玩笑而已。我不这么认为。@AlvinLindstam所以,要创建
ol.FeatureStyleFunction
我必须做
函数styleFunction3(分辨率){var color=this.p_color;//设置填充、笔划等…
。但是
var color=this.color;
还有
var color=this.get('color'))
抛出一个错误。那么如何从要设置样式的功能中获取数据呢?Thanks@slevin:是的,在
ol.FeatureStyleFunction
中,此
将引用该功能。如果出现这些错误,您可能将
ol.FeatureStyleFunction
设置在层/交互上,而不是在功能上。请参阅Jonatas对wo的回答使用
this
ol.FeatureStyleFunction
中获取功能的示例。这是一个比我更快更简单的黑客攻击。很好!谢谢!这里真正的问题是ol实际如何实现这一点?正如阿尔文指出的,您可以为所选功能设置样式设置交互时。该样式仅访问和更改选定/未选定的功能(=您的解决方案,速度更快)或所有功能(=我的解决方案,速度较慢)?如果第二个是真的,那么您的解决方案比本地OL解决方案更快,值得使用。我认为您应该在gitHub中发表评论,并让社区知道。我不认为有性能差异,但肯定
OL.interaction中的代码样式更少。选择
。这取决于您。我想最好使用@AlvinLindstam的答案。@JonatasWalker谢谢你的时间和努力。回答得很好,很清楚,代码也很好。嘿,@slevin,这是怎么结束的?
var select = new ol.interaction.Select();
map.addInteraction(select);

var styleClick = function() {
    // `this` is ol.Feature
    return [
        new ol.style.Style({
            image: new ol.style.Circle({
                fill: new ol.style.Fill({ color: [245, 121, 0, 0.8] }),
                stroke: new ol.style.Stroke({ color: [0,0,0,1] }),
                radius: 7
            }),
            text: new ol.style.Text({
                font: '24px Verdana',
                text: this.get('name'),
                offsetY: 20,
                fill: new ol.style.Fill({
                    color: [255, 255, 255, 0.8]
                })
            })
        })
    ];
};

select.on('select', function(evt){
    var selected = evt.selected;
    var deselected = evt.deselected;

    selected.forEach(function(feature){
        feature.setStyle(styleClick);
    });

    deselected.forEach(function(feature){
        feature.setStyle(null);
    });
});
var selectedStyleFunction = function(feature, resolution) {
    return [new ol.style.Style({
        stroke: new ol.style.Stroke({
            color: "white",
            lineCap: "butt",
            lineJoin: "bevel",
            width:3         
        }),
        fill : new ol.style.Fill({
            color: "black"
        }),
        text : new ol.style.Text({
            font: '10px Verdana',
            text: feature.get('name'),
            fill: new ol.style.Fill({
                color: [64, 64, 64, 1]
            })
        })
    })];
};
var select = new ol.interaction.Select({
    style: selectedStyleFunction
});
map.addInteraction(select);