ol-extent
Version:
a JavaScript library for openlayers extent
314 lines (292 loc) • 9.14 kB
JavaScript
/**
* Created by FDD on 2017/7/21.
* @desc 全局地图加载loading
*/
import '../assets/scss/loading.scss'
import ol from 'openlayers'
import {BASE_CLASS_NAME} from '../constants'
import {create, setStyle} from '../utils'
class Loading extends ol.control.Control {
constructor (options = {}) {
const className = (options.className !== undefined ? options.className : 'ole-loading-panel');
const widget = (options['widget'] ? options['widget'] : 'animatedGif');
const elementDom = (widget === 'animatedGif') ? 'span' : 'progress';
const element = create(elementDom, (className + ' ' + BASE_CLASS_NAME.CLASS_UNSELECTABLE));
super({
element: element,
target: options['target']
});
/**
* map listeners
* @type {Array}
*/
this.mapListeners = [];
/**
* tile listeners
* @type {Array}
*/
this.tileListeners = [];
/**
* load status
* @type {boolean}
* @private
*/
this.loadStatus_ = false;
/**
* is first load flag
* @type {boolean}
*/
this.isFirstRander = true;
/**
* progress
* @type {number[]}
* @private
*/
this.loadProgress_ = [0, 1];
/**
* widget
* @type {string}
*/
this.widget = widget;
/**
* 进度条模式
*/
if (options['progressMode']) {
if (['tile', 'layer'].indexOf(options['progressMode']) === -1) {
throw Error('不支持的进度条模式');
}
this.loadProgressByTile_ = ((options['progressMode'] === 'layer') ? !(options['progressMode'] === 'layer') : true);
}
/**
* show widget
* @type {boolean}
*/
this.showPanel = (typeof options['showPanel'] === 'boolean') ? options['showPanel'] : true;
if (this.widget === 'progressBar') {
const div = create('div', 'ole-progress-bar');
create('span', '', div)
}
this.onCustomStart = (options['onStart'] ? options['onStart'] : false);
this.onCustomProgress = (options['onProgress'] ? options['onProgress'] : false);
this.onCustomEnd = (options['onEnd'] ? options['onEnd'] : false);
}
/**
* 设置
*/
setup () {
if (!this.getMap()) return;
this.setDomPosition();
this.getMap().on('change:size', this.setDomPosition, this);
const pointerDown = this.getMap().on('pointerdown', this.hide(), this)
const beforeRander = this.getMap().on('precompose', () => {
if (this.isFirstRander) {
this.isFirstRander = false;
this.registerLayersLoadEvents_();
this.show();
if (this.onCustomStart) {
let args = [];
this.onCustomStart.apply(this, args)
}
}
});
const afterRander = this.getMap().on('postrender', () => {
this.updateLoadStatus_()
if (this.loadStatus_) {
if (this.onCustomEnd) {
let args = [];
this.onCustomEnd.apply(this, args);
}
this.hide();
}
});
this.mapListeners.push(pointerDown);
this.mapListeners.push(beforeRander);
this.mapListeners.push(afterRander);
}
/**
* 设置dom位置
*/
setDomPosition () {
let size = this.getMap().getSize();
if (!size) return;
let domSize = [this.element.clientWidth, this.element.clientHeight];
setStyle(this.element, {
left: String(Math.round((size[0] - domSize[0]) / 2)) + 'px',
bottom: String(Math.round((size[1] - domSize[1]) / 2)) + 'px'
});
}
/**
* 获取进度
* @param source
* @returns {boolean}
* @private
*/
updateSourceLoadStatus_ (source) {
return (Math.round(source.loaded / source.loading * 100) === 100);
}
/**
* 注册图层事件
* @param layer
* @private
*/
registerLayerLoadEvents_ (layer) {
let that = this;
layer.getSource().on('tileloadstart', function (event) {
if (that.loadStatus_) {
that.loadStatus_ = false;
that.loadProgress_ = [0, 1];
if (that.widget === 'progressBar') {
that.element.value = that.loadProgress_[0];
that.element.max = that.loadProgress_[1];
}
that.show();
if (that.onCustomStart) {
let args = [];
that.onCustomStart.apply(that, args);
}
}
this.loading = (this.loading) ? this.loading + 1 : 1;
this.isLoaded = that.updateSourceLoadStatus_(this);
if (that.loadProgressByTile_) {
this.loadProgress_[1] += 1;
if (this.widget === 'progressBar') {
that.element.max = that.loadProgress_[1];
let progressBarDiv = that.element.getElementsByClassName('ole-progress-bar');
if (progressBarDiv.length > 0) progressBarDiv[0].children()[0].width = String(parseInt(100 * that.progress(), 0)) + '%';
}
}
});
layer.getSource().on(['tileloadend', 'tileloaderror'], function (e) {
if (e.tile.getState() === 3) {
console.warn('Loading tile failed for resource \'' + e.tile.src_ + '\'')
}
this.loaded = (this.loaded) ? this.loaded + 1 : 1;
this.isLoaded = that.updateSourceLoadStatus_(this);
if (that.loadProgressByTile_) {
that.loadProgress_[0] += 1;
if (that.widget === 'progressBar') {
that.element.value = that.loadProgress_[0];
let progressBarDiv = this.element.getElementsByClassName('ole-progress-bar');
if (progressBarDiv.length > 0) {
progressBarDiv[0].children()[0].width = String(parseInt(100 * that.progress(), 0)) + '%';
}
}
if (that.onCustomProgress) {
that.onCustomProgress.apply(that, that.loadProgress_);
}
}
});
}
/**
* 注册全局图层事件
* @private
*/
registerLayersLoadEvents_ () {
let groups = this.getMap().getLayers().getArray();
for (let i = 0; i < groups.length; i++) {
let layer = groups[i];
if (layer instanceof ol.layer.Group) {
let layers = layer.getLayers().getArray();
for (let j = 0; j < layers.length; j++) {
let l = layers[j];
if (!(l instanceof ol.layer.Vector)) {
this.tileListeners.push(this.registerLayerLoadEvents_(l));
}
}
} else if (layer instanceof ol.layer.Layer) {
if (!(layer instanceof ol.layer.Vector)) {
this.tileListeners.push(this.registerLayerLoadEvents_(layer));
}
}
}
}
/**
* 更新加载状态
* @private
*/
updateLoadStatus_ () {
let loadStatusArray = [];
let groups = this.getMap().getLayers().getArray();
for (let i = 0; i < groups.length; i++) {
let layer = groups[i];
if (layer) {
if (layer instanceof ol.layer.Group) {
let layers = layer.getLayers().getArray();
for (let j = 0; j < layers.length; j++) {
let l = layers[j];
if (l && l.getSource() && !(l instanceof ol.layer.Vector) && l.getSource().hasOwnProperty('isLoaded')) {
loadStatusArray.push(l.getSource().isLoaded);
}
}
} else if (layer.getSource() && layer.getSource().hasOwnProperty('isLoaded')) {
loadStatusArray.push(layer.getSource().isLoaded);
}
}
}
this.loadStatus_ = (loadStatusArray.indexOf(false) === -1) && (loadStatusArray.indexOf(true) !== -1);
if (!this.loadProgressByTile_) {
// progress
let count = {};
loadStatusArray.forEach(function (i) {
count[i] = (count[i] || 0) + 1
});
let loaded = (count[true]) ? count[true] : 0;
// progress events
if (loaded > this.loadProgress_[0]) {
this.loadProgress_ = [loaded, loadStatusArray.length];
if (this.widget === 'progressBar') {
this.element.max = this.loadProgress_[1];
this.element.value = this.loadProgress_[0];
}
if (this.onCustomProgress) this.onCustomProgress.apply(this, this.loadProgress_);
}
}
}
/**
* show
*/
show () {
if (this.showPanel) {
this.element.style.display = 'block';
}
}
/**
* hide
*/
hide () {
if (this.showPanel) {
this.element.style.display = 'none';
}
}
/**
* 显示进度详情
* @returns {*[]|Array|[*,*]|[number,number]}
*/
progressDetails () {
return this.loadProgress_;
}
/**
* 显示进度条
* @returns {number}
*/
progress () {
return this.loadProgress_[0] / this.loadProgress_[1];
}
/**
* 设置地图
* @param map
*/
setMap (map) {
if (this.mapListeners && this.mapListeners.length > 0) {
this.mapListeners.forEach(listener => {
this.getMap().unByKey(listener)
})
}
this.mapListeners.length = 0;
super.setMap.call(this, map);
if (map) {
this.setup()
}
}
}
export default Loading