让 openlayers 从 visible = false 的层加载数据
Having openlayers load data from layer with visible = false
我有一个带有矢量源的矢量层,加载起来非常昂贵,但渲染起来却不那么昂贵。我的 GUI 中有一个按钮来切换图层的可见性。
问题是,第一次将 visibility 设置为 true 时,加载需要很长时间。
我想在加载其余数据(从所有可见层)时提前加载该层的数据,这样当可见性设置为 true 时,它只需要渲染它。
这在 Openlayers 中可能吗?
我尝试了各种方法,比如在 'precompose' 上将可见性设置为 true,然后在发送 HTTP 请求后将其设置为 false(使用自定义 'loadend' 事件),但我做不到不能让它正常工作;我无法再关闭图层。我猜这是因为在第一次加载后,它缓存了数据,所以我的自定义 'loadend' 事件不再触发。
无论如何,我更喜欢更优雅的解决方案。
编辑:
我不能像 Mike 的回答那样预先发送请求,因为没有 请求。该请求取决于范围和投影,因此在矢量源的 loader
函数中进行。
如果数据不会改变,可以在创建图层时预加载。
这是一个没有预加载的例子。打开地图 5 秒后,三个数据层可见。只有这样才能从矢量源中指定的 url 请求数据,然后可以看到它以不同的速度加载,因为其中一层必须下载 40mb KML 文件。
var raster_OSM = new ol.layer.Tile({
source: new ol.source.OSM()
});
var resolutions = ol.tilegrid.createXYZ().getResolutions();
var style_Cnty = new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#3399CC',
width: 1.25
})
});
var vector_Cnty = new ol.layer.Vector({
source: new ol.source.Vector({
url: 'https://raw.githubusercontent.com/tanhe03/kml/master/gz_2010_us_050_00_500k.kml',
format: new ol.format.KML({extractStyles: false})
}),
maxResolution: resolutions[3],
style: function(feature, resolution) {
var styles = [ style_Cnty ];
if (resolution < resolutions[8]) {
var geom = feature.getGeometry();
styles.push(
new ol.style.Style({
geometry: geom.getInteriorPoints ? geom.getInteriorPoints() : geom.getInteriorPoint(),
text: new ol.style.Text({
font: 'bold 16px sans-serif',
fill: new ol.style.Fill({
color: '#3399CC'
}),
backgroundFill: new ol.style.Fill({
color: 'rgba(255,255,255,0.5)'
}),
text: feature.get('Name')
})
})
)
}
return styles;
},
visible: false
});
var vector_State = new ol.layer.Vector({
source: new ol.source.Vector({
url: 'https://raw.githubusercontent.com/tanhe03/kml/master/gz_2010_us_040_00_500k.kml',
format: new ol.format.KML({extractStyles: false})
}),
maxResolution: resolutions[1],
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'purple',
width: 1.25
})
}),
visible: false
});
var vector_US = new ol.layer.Vector({
source: new ol.source.Vector({
url: 'https://raw.githubusercontent.com/tanhe03/kml/master/gz_2010_us_outline_500k.kml',
format: new ol.format.KML({extractStyles: false})
}),
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#3399CC',
width: 1.25
})
}),
visible: false
});
var map = new ol.Map({
layers: [raster_OSM, vector_Cnty, vector_State, vector_US],
target: 'map',
view: new ol.View({
center: ol.proj.transform([-96, 38], 'EPSG:4326', 'EPSG:3857'),
zoom: 4
})
});
setTimeout(function(){
vector_Cnty.setVisible(true);
vector_State.setVisible(true);
vector_US.setVisible(true);
}, 5000);
html, body, .map {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" />
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<div id="map" class="map"></div>
但在此示例中,数据的预加载在创建图层时开始。 XHR 立即请求 url,解析响应并将功能添加到源。当图层在 5 秒后可见时,应该已经加载了所有三个图层。
var raster_OSM = new ol.layer.Tile({
source: new ol.source.OSM()
});
var resolutions = ol.tilegrid.createXYZ().getResolutions();
var style_Cnty = new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#3399CC',
width: 1.25
})
});
var vector_Cnty = new ol.layer.Vector({
source: new ol.source.Vector({
format: new ol.format.KML({extractStyles: false})
}),
maxResolution: resolutions[3],
style: function(feature, resolution) {
var styles = [ style_Cnty ];
if (resolution < resolutions[8]) {
var geom = feature.getGeometry();
styles.push(
new ol.style.Style({
geometry: geom.getInteriorPoints ? geom.getInteriorPoints() : geom.getInteriorPoint(),
text: new ol.style.Text({
font: 'bold 16px sans-serif',
fill: new ol.style.Fill({
color: '#3399CC'
}),
backgroundFill: new ol.style.Fill({
color: 'rgba(255,255,255,0.5)'
}),
text: feature.get('Name')
})
})
)
}
return styles;
},
visible: false
});
var vector_State = new ol.layer.Vector({
source: new ol.source.Vector({
format: new ol.format.KML({extractStyles: false})
}),
maxResolution: resolutions[1],
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'purple',
width: 1.25
})
}),
visible: false
});
var vector_US = new ol.layer.Vector({
source: new ol.source.Vector({
format: new ol.format.KML({extractStyles: false})
}),
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#3399CC',
width: 1.25
})
}),
visible: false
});
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://raw.githubusercontent.com/tanhe03/kml/master/gz_2010_us_050_00_500k.kml');
xhr.onload = function() {
var source = vector_Cnty.getSource();
source.addFeatures(source.getFormat().readFeatures(this.responseText, {featureProjection: 'EPSG:3857'}));
}
xhr.send();
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://raw.githubusercontent.com/tanhe03/kml/master/gz_2010_us_040_00_500k.kml');
xhr.onload = function() {
var source = vector_State.getSource();
source.addFeatures(source.getFormat().readFeatures(this.responseText, {featureProjection: 'EPSG:3857'}));
}
xhr.send();
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://raw.githubusercontent.com/tanhe03/kml/master/gz_2010_us_outline_500k.kml');
xhr.onload = function() {
var source = vector_US.getSource();
source.addFeatures(source.getFormat().readFeatures(this.responseText, {featureProjection: 'EPSG:3857'}));
}
xhr.send();
var map = new ol.Map({
layers: [raster_OSM, vector_Cnty, vector_State, vector_US],
target: 'map',
view: new ol.View({
center: ol.proj.transform([-96, 38], 'EPSG:4326', 'EPSG:3857'),
zoom: 4
})
});
setTimeout(function(){
vector_Cnty.setVisible(true);
vector_State.setVisible(true);
vector_US.setVisible(true);
}, 5000);
html, body, .map {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" />
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<div id="map" class="map"></div>
如果您希望动态加载图层,则必须使其可见,否则不会发送请求。
让它工作的一种方法是使图层可见但阻止绘制要素(return 样式函数中的空样式)
var visible = false; // turn it to true to have the features drawn
var vector = new ol.layer.Vector({
source: new ol.source.Vector({
// your source definition
}),
visible: true,
style: function(feature, resolution) {
if (!visible) {
return [];
} else {
return your_style_for_the_feature;
}
}
});
图层将被加载和绘制,但由于未绘制要素,因此不会显示任何内容。只需在样式函数中将 return 您的样式设置为 visible 为 true 并绘制它们。
您还必须告诉来源它必须使用 changed
函数重绘:
// Draw the layer
visible = true;
vector.getSource().changed();
我有一个带有矢量源的矢量层,加载起来非常昂贵,但渲染起来却不那么昂贵。我的 GUI 中有一个按钮来切换图层的可见性。 问题是,第一次将 visibility 设置为 true 时,加载需要很长时间。 我想在加载其余数据(从所有可见层)时提前加载该层的数据,这样当可见性设置为 true 时,它只需要渲染它。 这在 Openlayers 中可能吗?
我尝试了各种方法,比如在 'precompose' 上将可见性设置为 true,然后在发送 HTTP 请求后将其设置为 false(使用自定义 'loadend' 事件),但我做不到不能让它正常工作;我无法再关闭图层。我猜这是因为在第一次加载后,它缓存了数据,所以我的自定义 'loadend' 事件不再触发。 无论如何,我更喜欢更优雅的解决方案。
编辑:
我不能像 Mike 的回答那样预先发送请求,因为没有 请求。该请求取决于范围和投影,因此在矢量源的 loader
函数中进行。
如果数据不会改变,可以在创建图层时预加载。
这是一个没有预加载的例子。打开地图 5 秒后,三个数据层可见。只有这样才能从矢量源中指定的 url 请求数据,然后可以看到它以不同的速度加载,因为其中一层必须下载 40mb KML 文件。
var raster_OSM = new ol.layer.Tile({
source: new ol.source.OSM()
});
var resolutions = ol.tilegrid.createXYZ().getResolutions();
var style_Cnty = new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#3399CC',
width: 1.25
})
});
var vector_Cnty = new ol.layer.Vector({
source: new ol.source.Vector({
url: 'https://raw.githubusercontent.com/tanhe03/kml/master/gz_2010_us_050_00_500k.kml',
format: new ol.format.KML({extractStyles: false})
}),
maxResolution: resolutions[3],
style: function(feature, resolution) {
var styles = [ style_Cnty ];
if (resolution < resolutions[8]) {
var geom = feature.getGeometry();
styles.push(
new ol.style.Style({
geometry: geom.getInteriorPoints ? geom.getInteriorPoints() : geom.getInteriorPoint(),
text: new ol.style.Text({
font: 'bold 16px sans-serif',
fill: new ol.style.Fill({
color: '#3399CC'
}),
backgroundFill: new ol.style.Fill({
color: 'rgba(255,255,255,0.5)'
}),
text: feature.get('Name')
})
})
)
}
return styles;
},
visible: false
});
var vector_State = new ol.layer.Vector({
source: new ol.source.Vector({
url: 'https://raw.githubusercontent.com/tanhe03/kml/master/gz_2010_us_040_00_500k.kml',
format: new ol.format.KML({extractStyles: false})
}),
maxResolution: resolutions[1],
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'purple',
width: 1.25
})
}),
visible: false
});
var vector_US = new ol.layer.Vector({
source: new ol.source.Vector({
url: 'https://raw.githubusercontent.com/tanhe03/kml/master/gz_2010_us_outline_500k.kml',
format: new ol.format.KML({extractStyles: false})
}),
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#3399CC',
width: 1.25
})
}),
visible: false
});
var map = new ol.Map({
layers: [raster_OSM, vector_Cnty, vector_State, vector_US],
target: 'map',
view: new ol.View({
center: ol.proj.transform([-96, 38], 'EPSG:4326', 'EPSG:3857'),
zoom: 4
})
});
setTimeout(function(){
vector_Cnty.setVisible(true);
vector_State.setVisible(true);
vector_US.setVisible(true);
}, 5000);
html, body, .map {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" />
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<div id="map" class="map"></div>
但在此示例中,数据的预加载在创建图层时开始。 XHR 立即请求 url,解析响应并将功能添加到源。当图层在 5 秒后可见时,应该已经加载了所有三个图层。
var raster_OSM = new ol.layer.Tile({
source: new ol.source.OSM()
});
var resolutions = ol.tilegrid.createXYZ().getResolutions();
var style_Cnty = new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#3399CC',
width: 1.25
})
});
var vector_Cnty = new ol.layer.Vector({
source: new ol.source.Vector({
format: new ol.format.KML({extractStyles: false})
}),
maxResolution: resolutions[3],
style: function(feature, resolution) {
var styles = [ style_Cnty ];
if (resolution < resolutions[8]) {
var geom = feature.getGeometry();
styles.push(
new ol.style.Style({
geometry: geom.getInteriorPoints ? geom.getInteriorPoints() : geom.getInteriorPoint(),
text: new ol.style.Text({
font: 'bold 16px sans-serif',
fill: new ol.style.Fill({
color: '#3399CC'
}),
backgroundFill: new ol.style.Fill({
color: 'rgba(255,255,255,0.5)'
}),
text: feature.get('Name')
})
})
)
}
return styles;
},
visible: false
});
var vector_State = new ol.layer.Vector({
source: new ol.source.Vector({
format: new ol.format.KML({extractStyles: false})
}),
maxResolution: resolutions[1],
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'purple',
width: 1.25
})
}),
visible: false
});
var vector_US = new ol.layer.Vector({
source: new ol.source.Vector({
format: new ol.format.KML({extractStyles: false})
}),
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#3399CC',
width: 1.25
})
}),
visible: false
});
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://raw.githubusercontent.com/tanhe03/kml/master/gz_2010_us_050_00_500k.kml');
xhr.onload = function() {
var source = vector_Cnty.getSource();
source.addFeatures(source.getFormat().readFeatures(this.responseText, {featureProjection: 'EPSG:3857'}));
}
xhr.send();
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://raw.githubusercontent.com/tanhe03/kml/master/gz_2010_us_040_00_500k.kml');
xhr.onload = function() {
var source = vector_State.getSource();
source.addFeatures(source.getFormat().readFeatures(this.responseText, {featureProjection: 'EPSG:3857'}));
}
xhr.send();
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://raw.githubusercontent.com/tanhe03/kml/master/gz_2010_us_outline_500k.kml');
xhr.onload = function() {
var source = vector_US.getSource();
source.addFeatures(source.getFormat().readFeatures(this.responseText, {featureProjection: 'EPSG:3857'}));
}
xhr.send();
var map = new ol.Map({
layers: [raster_OSM, vector_Cnty, vector_State, vector_US],
target: 'map',
view: new ol.View({
center: ol.proj.transform([-96, 38], 'EPSG:4326', 'EPSG:3857'),
zoom: 4
})
});
setTimeout(function(){
vector_Cnty.setVisible(true);
vector_State.setVisible(true);
vector_US.setVisible(true);
}, 5000);
html, body, .map {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" />
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<div id="map" class="map"></div>
如果您希望动态加载图层,则必须使其可见,否则不会发送请求。 让它工作的一种方法是使图层可见但阻止绘制要素(return 样式函数中的空样式)
var visible = false; // turn it to true to have the features drawn
var vector = new ol.layer.Vector({
source: new ol.source.Vector({
// your source definition
}),
visible: true,
style: function(feature, resolution) {
if (!visible) {
return [];
} else {
return your_style_for_the_feature;
}
}
});
图层将被加载和绘制,但由于未绘制要素,因此不会显示任何内容。只需在样式函数中将 return 您的样式设置为 visible 为 true 并绘制它们。
您还必须告诉来源它必须使用 changed
函数重绘:
// Draw the layer
visible = true;
vector.getSource().changed();