Открытые слои загружают данные из слоя с visible = false - PullRequest
0 голосов
/ 04 июля 2019

У меня есть векторный слой с векторным источником, который очень дорогой для загрузки, но не настолько дорогой для рендеринга.У меня есть кнопка в моем графическом интерфейсе, чтобы переключать видимость слоя.Проблема в том, что когда видимость установлена ​​на true, загрузка занимает много времени.Я хотел бы загрузить данные для слоя заранее, в то время как остальные данные загружены (из всех видимых слоев), так что, когда видимость установлена ​​в true, он должен только визуализировать его.Возможно ли это в Openlayers?

Я пробовал разные вещи, такие как установка видимости в true для «precompose», а затем в false после отправки HTTP-запроса (с пользовательским событием «loadend»), ноЯ не мог заставить это работать должным образом;Я не мог выключить слой больше.Я полагаю, это произошло потому, что после первой загрузки данные кэшировались, поэтому мое пользовательское событие 'loadend' больше не вызывалось.В любом случае, я бы предпочел более элегантное решение.

Редактировать: я не могу просто отправить запрос заранее, как в ответе Майк s, потому что нет запроса,Запрос зависит от степени, а также от проекции и, следовательно, выполняется в функции loader источника вектора.

Ответы [ 2 ]

1 голос
/ 07 июля 2019

Если вы хотите, чтобы ваш слой загружался на лету, вы должны сделать его видимым, иначе запросы не будут отправлены.Один из способов заставить его работать - сделать слой видимым, но предотвратить рисование объектов (верните пустой стиль в вашей функции стиля)

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, чтобы вернуть ваш стиль в функцию style и сделать их нарисованными.Вы также должны сообщить источнику, что он должен перерисовать, используя функцию changed:

// Draw the layer
visible = true;
vector.getSource().changed();
1 голос
/ 05 июля 2019

Если данные не собираются изменяться, их можно предварительно загрузить при создании слоев.

Это пример без предварительной загрузки. Три слоя данных становятся видимыми через 5 секунд после открытия карты. Только после этого данные, запрашиваемые по URL-адресам, указанным в источниках векторов, могут быть загружены с разной скоростью, поскольку один из слоев должен загрузить файл KML 40 МБ.

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>

Но в этом примере предварительная загрузка данных начинается при создании слоев. URL запрашиваются XHR немедленно, ответы анализируются и функции добавляются в источники. Когда через 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>
...