adaguc-webmapjs
Version:
Interactive maps library, capable of parsing a OGC WMS getcapabilities and display geographical layers
269 lines (240 loc) • 7.34 kB
JavaScript
import { jquery } from './WMJSExternalDependencies.js';
import { isDefined } from './WMJSTools.js';
var numImagesLoading = 0;
/*
* WMJSImage
* image.this.srcToLoad the source to load
* image._srcLoaded the loaded source
*/
export default class WMJSImage {
constructor (src, callback, __type, options) {
this.randomize = true;
this._srcLoaded = undefined;
this._isLoaded = undefined;
this._isLoading = undefined;
this._hasError = undefined;
this._opacity = undefined;
if (isDefined(options) && isDefined(options.randomizer)) {
if (options.randomizer === false) {
this.randomize = false;
}
}
this.init = this.init.bind(this);
this.isLoaded = this.isLoaded.bind(this);
this.isLoading = this.isLoading.bind(this);
this.checkIfThisSourceIsSet = this.checkIfThisSourceIsSet.bind(this);
this.setSource = this.setSource.bind(this);
this.clear = this.clear.bind(this);
this.getSrc = this.getSrc.bind(this);
this.hasError = this.hasError.bind(this);
this.stopLoading = this.stopLoading.bind(this);
this._load = this._load.bind(this);
this.load = this.load.bind(this);
this.loadEvent = this.loadEvent.bind(this);
this.setOpacity = this.setOpacity.bind(this);
this.getOpacity = this.getOpacity.bind(this);
this.setPosition = this.setPosition.bind(this);
this.setSize = this.setSize.bind(this);
this.setZIndex = this.setZIndex.bind(this);
this.getElement = this.getElement.bind(this);
this._getImageWithHeaders = this._getImageWithHeaders.bind(this);
this.init();
this.srcToLoad = src;
this._type = __type;
this.loadEventCallback = callback;
if (!jquery) { console.warn('WMJSImage: jquery is not defined, assuming unit test is running'); return; }
this.el = jquery(document.createElement('img'));
this.el.on('load', () => {
this.loadEvent(this, false);
});
this.el.on('error', (e) => {
this.loadEvent(this, true);
});
this.el.onselectstart = () => { return false; };
this.el.ondrag = () => { return false; };
this.headers = [];
}
init () {
this._srcLoaded = 'undefined image';
this._isLoaded = false;
this._isLoading = false;
this._hasError = false;
this._opacity = 1;
this._stopLoading = false;
}
isLoaded () {
if (this._isLoading) return false;
return this._isLoaded;
}
isLoading () {
return this._isLoading;
}
checkIfThisSourceIsSet (src) {
if (this._srcLoaded === src || this.srcToLoad === src) {
return true;
}
return false;
}
/**
* Set source of image, does not load yet.
*/
setSource (src, options) {
if (this._isLoading) {
console.error('-------------------------> Source set while still loading!!! ');
return;
}
this.srcToLoad = src;
if (options && options.headers && options.headers.length > 0) {
this.headers = options.headers;
}
if (this._srcLoaded === this.srcToLoad) {
this._isLoaded = true;
return;
}
this._isLoaded = false;
}
clear () {
this.init();
this._stopLoading = true;
}
stopLoading () {
this._stopLoading = true;
}
getSrc () {
return this.srcToLoad;
};
hasError () {
return this._hasError;
};
/**
*
* Load image *
*/
load () {
this._stopLoading = false;
this._load();
}
_getImageWithHeaders (url, headers) {
var fetchHeaders = new Headers();
if (headers && headers.length > 0) {
for (let j = 0; j < headers.length; j++) {
fetchHeaders.append(headers[j].name, headers[j].value);
}
}
var options = {
method: 'GET',
headers: fetchHeaders,
mode: 'cors',
cache: 'default'
};
var request = new Request(url);
const arrayBufferToBase64 = (buffer) => {
var binary = '';
var bytes = [].slice.call(new Uint8Array(buffer));
bytes.forEach((b) => { binary += String.fromCharCode(b); });
return window.btoa(binary);
};
fetch(request, options).then((response) => {
response.arrayBuffer().then((buffer) => {
var base64Flag = 'data:image/png;base64,';
var imageStr = arrayBufferToBase64(buffer);
this.getElement()[0].src = base64Flag + imageStr;
});
}).catch((e) => {
console.error('Unable to fetch image ' + url + ' with headers [' + JSON.stringify(headers) + ']');
if (url.startsWith('http://')) console.error('Note that URL starts with http:// instead of https://');
this.loadEvent(this, true);
});
}
_load () {
this._hasError = false;
if (this._isLoaded === true) {
this.loadEvent(this, false);
return;
}
this._isLoading = true;
if (!this.srcToLoad) {
console.error('Source not set');
this.loadEvent(this, true);
return;
}
/* Allow relative URL's */
if (this.srcToLoad.startsWith('/') && !this.srcToLoad.startsWith('//')) {
let splittedHREF = window.location.href.split('/').filter(e => e.length > 0);
let hostName = splittedHREF[0] + '//' + splittedHREF[1] + '/';
this.srcToLoad = hostName + this.srcToLoad;
}
if (this.srcToLoad.startsWith('http') === false && this.srcToLoad.startsWith('//') === false) {
console.error('Source does not start with http');
this.loadEvent(this, true);
return;
}
if (this.srcToLoad === this._srcLoaded) {
this.loadEvent(this, false);
return;
}
if (this.timerIsRunning === true) return;
if (numImagesLoading >= 4) {
if (this._stopLoading === false) {
this.timerIsRunning = true;
setTimeout(() => {
this.timerIsRunning = false;
this._load();
}, 10);
} else {
/* Cancel loading */
this.init();
}
return;
}
numImagesLoading++;
// console.log("WMJSImage:load "+this.srcToLoad);
if (this.headers && this.headers.length > 0) {
/* Get an image which needs headers */
this._getImageWithHeaders(this.srcToLoad, this.headers);
} else {
/* Do a standard img.src url request */
if (this.randomize) {
this.getElement()[0].src = this.srcToLoad + '&' + Math.random();
// this.el.attr('src', this.srcToLoad + '&' + Math.random());
} else {
this.getElement()[0].src = this.srcToLoad;
// this.el.attr('src', this.srcToLoad);
}
}
};
loadEvent (image, hasError) {
numImagesLoading--;
this._hasError = hasError;
this._isLoading = false;
this._isLoaded = true;
this._srcLoaded = this.srcToLoad;
if (isDefined(this.loadEventCallback)) {
this.loadEventCallback(this);
}
}
setOpacity (__opacity) {
this._opacity = parseFloat(__opacity);
this.el.css('opacity', this._opacity);
};
getOpacity (opacity) {
return this._opacity;
};
setPosition (x, y) {
this.el.css({ top: parseInt(y) + 'px', left: parseInt(x) + 'px', position:'absolute' });
};
setSize (w, h) {
w = parseInt(w);
h = parseInt(h);
if (w === 0 || h === 0) return;
if (isNaN(w) || isNaN(h)) return;
this.el.width(parseInt(w) + 'px');
this.el.height(parseInt(h) + 'px');
};
setZIndex (z) {
this.el.zIndex = z;
}
getElement () {
return this.el;
}
};