让openlayers通过visible = false

时间:2019-07-04 15:40:03

标签: openlayers openlayers-5

我有一个带有矢量源的矢量层,其加载非常昂贵,但渲染却不那么昂贵。我的GUI中有一个按钮,用于切换图层的可见性。 问题是,首次将可见性设置为true时,加载会花费很长时间。 我想在加载其余数据(来自所有可见层)的同时预先加载该层的数据,以便当可见性设置为true时,它只需要呈现它即可。 在Openlayers中有可能吗?

我尝试了各种方法,例如在“ precompose”上将可见性设置为true,然后在发送HTTP请求后(使用自定义的“ loadend”事件)将其设置为false,但是我无法使其正常工作;我无法关闭该层了。我猜想发生这种情况是因为在第一次加载之后,它已经缓存了数据,所以我的自定义“ loadend”事件不再触发。 无论如何,我希望有一个更优雅的解决方案。

编辑: 我不能像Mike的答案那样预先发送请求,因为没有 请求。该请求取决于范围以及投影,因此是在向量源的loader函数中做出的。

2 个答案:

答案 0 :(得分:1)

如果数据不会更改,则可以在创建图层时对其进行预加载。

这是一个没有预加载的示例。打开地图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>

答案 1 :(得分:1)

如果要动态加载图层,则必须使其可见,否则将不发送请求。 一种有效的方法是使图层可见,但防止绘制要素(在样式函数中返回空样式)

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;
    }
  }
});

将加载并绘制该图层,但由于未绘制要素,因此将看不到任何内容。只需将visible设置为true即可在样式函数中返回样式并进行绘制。 您还必须使用changed函数告诉源代码必须重绘:

// Draw the layer
visible = true;
vector.getSource().changed();