无法为矢量图层中的单击要素设置样式
Cannot set a style for clicked features in vector layer
所以在我的 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);
我在控制台上没有收到任何错误,但这行不通。当我单击另一个时,单击的功能不会 return 为默认样式。所有点击的功能都保留 styleClick
.
那么,我该如何解决这个问题,还有更简单的方法吗?我认为这种功能有很多代码
谢谢
编辑
我替换了
for (i in e.selected){
e.selected[i].setStyle(styleFunction);
}
和
var allfe = sourceVector.getFeatures();
for (i in allfe){
allfe[i].setStyle(styleFunction);
}
所以现在所有功能都将获得 styleFunction
函数中定义的样式。
这不起作用。我得到 Uncaught TypeError: feature.get is not a function
指的是函数的第一行,var color = feature.get('color');
这一行。
我不能只设置一个样式,我需要它是一个函数,这样我以后可以检查几何类型。
所以我的两个问题,
我不知道如何调试和修复这个错误
如果我有大约 500 个特征,每次点击都重新绘制所有特征,会减慢渲染速度。还有其他解决方案吗?
谢谢
更新 - fiddle styling with ol.interaction.Select
怎么样 - http://jsfiddle.net/jonataswalker/zz6d4z7d/
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);
});
});
图层和特征样式函数不同
使用OpenLayers 3风格的函数时,你要注意ol.FeatureStyleFunction
and a ol.style.StyleFunction
之间的区别。它们非常相似,因为它们都应该 return 一个基于特征和分辨率的 ol.Style
数组。然而,他们并没有以同样的方式获得这些信息。
当使用它的 setStyle
方法为特征提供样式函数时,该函数应该是 ol.FeatureStyleFunction
。 ol.FeatureStyleFunction
被调用,this
引用该特征,resolution
作为唯一参数。
为图层提供样式功能时,应该是ol.style.StyleFunction
。它们使用两个参数调用,feature
和 resolution
.
这就是您出错的原因。您正在使用 ol.style.StyleFunction
作为特征样式。稍后,当您的样式函数被调用时,第一个参数是分辨率而不是您期望的功能。
方案一:setStyle(null)
这个解决方案已经在@jonatas-walker 的 中提出。它的工作原理是在 selected 特征上设置样式并从未selected 特征中删除样式(而不是将样式函数设置为未selected 特征)。
OpenLayers 将使用要素的样式(如果有),否则使用图层的样式。因此,将未selected 功能的样式重新设置为 null 将使它们再次使用图层的样式功能。
解决方案 2:使用 select 交互的 style
选项
ol.interaction.Select
接受样式选项(ol.style.StyleFunction
),用于设置 selected 特征的样式。
优点:图层(普通视图)有一个样式函数,select 交互有一个样式函数,这使得代码比混合特征和图层样式更具可读性。此外,您不必跟踪事件或修改功能。
可以这样做:
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);
所以在我的 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);
我在控制台上没有收到任何错误,但这行不通。当我单击另一个时,单击的功能不会 return 为默认样式。所有点击的功能都保留 styleClick
.
那么,我该如何解决这个问题,还有更简单的方法吗?我认为这种功能有很多代码
谢谢
编辑
我替换了
for (i in e.selected){
e.selected[i].setStyle(styleFunction);
}
和
var allfe = sourceVector.getFeatures();
for (i in allfe){
allfe[i].setStyle(styleFunction);
}
所以现在所有功能都将获得 styleFunction
函数中定义的样式。
这不起作用。我得到 Uncaught TypeError: feature.get is not a function
指的是函数的第一行,var color = feature.get('color');
这一行。
我不能只设置一个样式,我需要它是一个函数,这样我以后可以检查几何类型。
所以我的两个问题,
我不知道如何调试和修复这个错误
如果我有大约 500 个特征,每次点击都重新绘制所有特征,会减慢渲染速度。还有其他解决方案吗?
谢谢
更新 - fiddle styling with ol.interaction.Select
怎么样 - http://jsfiddle.net/jonataswalker/zz6d4z7d/
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);
});
});
图层和特征样式函数不同
使用OpenLayers 3风格的函数时,你要注意ol.FeatureStyleFunction
and a ol.style.StyleFunction
之间的区别。它们非常相似,因为它们都应该 return 一个基于特征和分辨率的 ol.Style
数组。然而,他们并没有以同样的方式获得这些信息。
当使用它的 setStyle
方法为特征提供样式函数时,该函数应该是 ol.FeatureStyleFunction
。 ol.FeatureStyleFunction
被调用,this
引用该特征,resolution
作为唯一参数。
为图层提供样式功能时,应该是ol.style.StyleFunction
。它们使用两个参数调用,feature
和 resolution
.
这就是您出错的原因。您正在使用 ol.style.StyleFunction
作为特征样式。稍后,当您的样式函数被调用时,第一个参数是分辨率而不是您期望的功能。
方案一:setStyle(null)
这个解决方案已经在@jonatas-walker 的
OpenLayers 将使用要素的样式(如果有),否则使用图层的样式。因此,将未selected 功能的样式重新设置为 null 将使它们再次使用图层的样式功能。
解决方案 2:使用 select 交互的 style
选项
ol.interaction.Select
接受样式选项(ol.style.StyleFunction
),用于设置 selected 特征的样式。
优点:图层(普通视图)有一个样式函数,select 交互有一个样式函数,这使得代码比混合特征和图层样式更具可读性。此外,您不必跟踪事件或修改功能。
可以这样做:
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);