如何在 OpenLayers 3 中隐藏和显示功能? (重绘?)
How to hide and show features in OpenLayers 3? (Redraw?)
我正在更新 OL2 to 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 也没有用。我希望改变,但没有任何反应。
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是怎么重绘来渲染样式改变的地物的?可以将图层设置为可见,但我不想一直 hide/show 所有功能。有时我只想hide/show根据他们给定的id.
几个
我无法添加评论,因为我没有足够的声誉,但是您可能想调用 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
所以在一遍又一遍地查看文档时,我终于找到了触发更改事件的内容,就像 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);
}
}
},
另一种方法是在特征上使用样式函数和隐藏属性:
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
});
如果您更改功能 "HIDDEN" 属性,它会立即刷新
我喜欢这种图层切换方法(也适用于其他功能):
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>
我正在更新 OL2 to 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 也没有用。我希望改变,但没有任何反应。
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是怎么重绘来渲染样式改变的地物的?可以将图层设置为可见,但我不想一直 hide/show 所有功能。有时我只想hide/show根据他们给定的id.
几个我无法添加评论,因为我没有足够的声誉,但是您可能想调用 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
所以在一遍又一遍地查看文档时,我终于找到了触发更改事件的内容,就像 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);
}
}
},
另一种方法是在特征上使用样式函数和隐藏属性:
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
});
如果您更改功能 "HIDDEN" 属性,它会立即刷新
我喜欢这种图层切换方法(也适用于其他功能):
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>