UNPKG

adaguc-webmapjs

Version:

Interactive maps library, capable of parsing a OGC WMS getcapabilities and display geographical layers

462 lines (419 loc) 14.7 kB
import I18n from './I18n/lang.en.js'; import { WMSVersion, error, debug } from './WMJSConstants.js'; import { URLEncode, isDefined, toArray, isNull } from './WMJSTools.js'; import WMJSXMLParser from './WMJSXMLParser.js'; import { jquery } from './WMJSExternalDependencies.js'; let config = { xml2jsonrequestURL: 'Check WMJSService line 8' }; let loadGetCapabilitiesViaProxy = (url, succes, fail, xml2jsonrequestURL) => { let getcapreq = xml2jsonrequestURL + 'request='; let errormessage = (message) => { fail(I18n.unable_to_do_getcapabilities.text + ':\n' + getcapreq + '\n' + I18n.result.text + ':\n' + message); }; debug("<a target='_blank' href='" + url + "'>" + url + '</a>', false); getcapreq += URLEncode(url); /* Error message in case the request goes wrong */ if (!jquery) { console.warn('WMJSService: jquery is not defined, assuming unit test is running'); return; } try { jquery.ajax({ url: getcapreq, crossDomain:true, dataType:'jsonp' }).done((d) => { debug('loadGetCapabilitiesViaProxy succesfully finished'); succes(d); }).fail(() => { errormessage({ 'error':'Request failed for ' + getcapreq }); }); } catch (e) { error(e); errormessage({ 'error': 'Request failed for ' + getcapreq }); } }; /** * Global getcapabilities function */ export const WMJSGetCapabilities = (service, forceReload, succes, fail, xml2jsonrequestURL = this.xml2jsonrequestURL, options) => { /* Make the regetCapabilitiesJSONquest */ let headers = {}; if (options && options.headers) headers = options.headers; if (!isDefined(service)) { fail(I18n.no_service_defined.text); return; } if (service.length === 0) { error('Service is empty'); fail(I18n.service_url_empty.text); return; } /* Allow relative URL's */ if (service.startsWith('/') && !service.startsWith('//')) { let splittedHREF = window.location.href.split('/').filter(e => e.length > 0); let hostName = splittedHREF[0] + '//' + splittedHREF[1] + '/'; service = hostName + service; } if (!service.startsWith('http://') && !service.startsWith('https:') && !service.startsWith('//')) { error('Service does not start with HTTPS'); fail(I18n.service_url_empty.text); return; } if (service.indexOf('?') === -1) { service += '?'; } debug('GetCapabilities:'); let url = service + '&service=WMS&request=GetCapabilities&random' + Math.random(); let _xml2jsonrequestURL = xml2jsonrequestURL; WMJSXMLParser(url, headers).then((data) => { try { succes(data); } catch (e) { console.error(e); } }).catch((e) => { loadGetCapabilitiesViaProxy(url, succes, () => { fail('Request failed for ' + url); }, _xml2jsonrequestURL); }); }; /** * WMJSService Class * * options: * service * title (optional) */ export class WMJSService { constructor (options) { this.service = undefined; this.title = undefined; this.onlineresource = undefined; this.abstract = undefined; this.version = WMSVersion.version111; this.getcapabilitiesDoc = undefined; this.busy = false; this._flatLayerObject = undefined; if (options) { this.service = options.service; this.title = options.title; } this.checkVersion111 = this.checkVersion111.bind(this); this.checkVersion130 = this.checkVersion130.bind(this); this.getCapabilityElement = this.getCapabilityElement.bind(this); this.checkVersion = this.checkVersion.bind(this); this.getCapabilities = this.getCapabilities.bind(this); this.checkException = this.checkException.bind(this); this.getNodes = this.getNodes.bind(this); this.getLayerNames = this.getLayerNames.bind(this); this.getLayerObjectsFlat = this.getLayerObjectsFlat.bind(this); this.xml2jsonrequestURL = options.xml2jsonrequestURL ? options.xml2jsonrequestURL : config.xml2jsonrequestURL; this.functionCallbackList = []; console.log('new service for ' + options.service); } checkVersion111 (jsonData) { try { let rootLayer = jsonData.WMT_MS_Capabilities.Capability.Layer; if (!rootLayer) throw new Error('No 111 layer'); } catch (e) { let message = this.checkException(jsonData); if (message !== undefined) { throw (message); } if (!jsonData.WMT_MS_Capabilities.Capability) { throw (I18n.no_wms_capability_element_found.text); } if (!jsonData.WMT_MS_Capabilities.Capability.Layer) { throw (I18n.no_wms_layer_element_found.text); } } }; setXML2JSONProxy (xml2jsonrequestURL) { this.xml2jsonrequestURL = xml2jsonrequestURL; } checkVersion130 (jsonData) { try { let rootLayer = jsonData.WMS_Capabilities.Capability.Layer; if (!rootLayer) throw new Error('No 130 layer'); } catch (e) { let message = this.checkException(jsonData); if (message !== undefined) { throw (message); } if (!jsonData.WMS_Capabilities.Capability) { throw (I18n.no_wms_capability_element_found.text); } if (!jsonData.WMS_Capabilities.Capability.Layer) { throw (I18n.no_wms_layer_element_found.text); } } }; getCapabilityElement (jsonData) { let capabilityObject; try { capabilityObject = jsonData.WMT_MS_Capabilities.Capability; } catch (e) { try { capabilityObject = jsonData.WMS_Capabilities.Capability; } catch (e) { throw (I18n.no_capability_element_found.text); } } if (!isDefined(capabilityObject)) { throw (I18n.no_capability_element_found.text); } return capabilityObject; }; checkVersion (jsonData) { let version = null; try { if (WMSVersion.version100 === jsonData.WMT_MS_Capabilities.attr.version)version = WMSVersion.version100; if (WMSVersion.version111 === jsonData.WMT_MS_Capabilities.attr.version)version = WMSVersion.version111; if (WMSVersion.version130 === jsonData.WMT_MS_Capabilities.attr.version)version = WMSVersion.version130; } catch (e) { try { if (WMSVersion.version100 === jsonData.WMS_Capabilities.attr.version)version = WMSVersion.version100; if (WMSVersion.version111 === jsonData.WMS_Capabilities.attr.version)version = WMSVersion.version111; if (WMSVersion.version130 === jsonData.WMS_Capabilities.attr.version)version = WMSVersion.version130; } catch (e) { let message = this.checkException(jsonData); if (message) { throw (new Error(message)); } else { throw (new Error('Unable to determine WMS version')); } } } if (version === null) { throw (new Error('Unable to determine WMS version')); } if (version === WMSVersion.version111) { this.checkVersion111(jsonData); return version; } if (version === WMSVersion.version130) { this.checkVersion130(jsonData); return version; } return WMSVersion.version111; }; /** * Does getcapabilities for a service. * When multple getCapabilities for the same service are made, * this method makes one get request and fires all callbacks with the same result. * @param succescallback Function called upon succes, cannot be left blank * @param failcallback Function called upon failure, cannot be left blank */ getCapabilities (succescallback, failcallback, forceReload, xml2jsonrequestURL = this.xml2jsonrequestURL, options) { if (options) { this._options = options; } if (this.busy) { let cf = { callback:succescallback, fail:failcallback }; this.functionCallbackList.push(cf); return; } this._flatLayerObject = undefined; if (!this.getcapabilitiesDoc || forceReload === true) { this.busy = true; let cf = { callback:succescallback, fail:failcallback }; this.functionCallbackList.push(cf); /* Fail functions */ let fail = (jsonData) => { this.busy = false; let current; while (current = this.functionCallbackList.pop()) { current.fail(jsonData); } }; /* Success functions */ let succes = (jsonData) => { this.busy = false; this.getcapabilitiesDoc = jsonData; try { this.version = this.checkVersion(jsonData); } catch (e) { fail(e.message); return; } let WMSCapabilities = jsonData.WMS_Capabilities; if (!WMSCapabilities) { WMSCapabilities = jsonData.WMT_MS_Capabilities; } // Get Abstract try { this.abstract = WMSCapabilities.Service.Abstract.value; } catch (e) { this.abstract = I18n.not_available_message.text; } // Get Title try { this.title = WMSCapabilities.Service.Title.value; } catch (e) { this.title = I18n.not_available_message.text; } // Get OnlineResource try { if (WMSCapabilities.Service.OnlineResource.value) { this.onlineresource = WMSCapabilities.Service.OnlineResource.value; } else { this.onlineresource = WMSCapabilities.Service.OnlineResource.attr['xlink:href']; } } catch (e) { this.onlineresource = I18n.not_available_message.text; } // Fill in flatlayer object this.getLayerObjectsFlat(() => {}, () => {}, false, xml2jsonrequestURL, options); let current; while (current = this.functionCallbackList.pop()) { current.callback(jsonData); } }; WMJSGetCapabilities(this.service, false, succes, fail, xml2jsonrequestURL, options); } else { succescallback(this.getcapabilitiesDoc); } }; checkException (jsonData) { try { if (jsonData.ServiceExceptionReport) { let code = 'Undefined'; let value = code; let se = jsonData.ServiceExceptionReport.ServiceException; if (se) { try { if (se.attr.code)code = se.attr.code; } catch (e) {} if (se.value) { value = se.value; return ('Exception: ' + code + '.\n' + value); } } return (I18n.wms_service_exception_code.text + code); } } catch (e) {} return undefined; }; _sortByKey (array, key) { return array.sort((a, b) => { let x = a[key]; let y = b[key]; return ((x < y) ? -1 : ((x > y) ? 1 : 0)); }); }; /** * Calls succes with a hierarchical node structure * Calls failure with a string when someting goes wrong */ getNodes (succes, failure, forceReload, xml2jsonrequestURL = config.xml2jsonrequestURL, options) { /* if(forceReload !== true){ if(isDefined(this.getcapabilitiesDoc)){ if(isDefined(this.nodeCache)){ succes(this.nodeCache); return; } } } */ this.nodeCache = undefined; if (!failure) { failure = (msg) => { error(msg); }; } let parse = (jsonData) => { var nodeStructure = { leaf: false, expanded: true, children: [] }; let rootLayer = this.getCapabilityElement(jsonData).Layer; try { this.version = this.checkVersion(jsonData); } catch (e) { failure(e); return; } let WMSLayers = toArray(rootLayer.Layer); try { nodeStructure.text = rootLayer.Title.value; } catch (e) { nodeStructure.text = I18n.unnamed_service.text; } let recursivelyFindLayer = (WMSLayers, rootNode, path) => { for (let j = 0; j < WMSLayers.length; j++) { let isleaf = false; if (WMSLayers[j].Name)isleaf = true; try { if (WMSLayers[j].Layer)isleaf = false; } catch (e) {} let nodeObject = {}; if (WMSLayers[j].Name) { nodeObject = { name:WMSLayers[j].Name.value, text:WMSLayers[j].Title.value, leaf:isleaf, path:path }; } else { if (isNull(WMSLayers[j].Title)) { WMSLayers[j].Title = []; WMSLayers[j].Title.value = 'Layer'; } nodeObject = { text:WMSLayers[j].Title.value, leaf:isleaf }; } rootNode.push(nodeObject); if (WMSLayers[j].Layer) { nodeObject.children = []; recursivelyFindLayer(toArray(WMSLayers[j].Layer), nodeObject.children, path + WMSLayers[j].Title.value); } } // Sort nodes alphabetically. this._sortByKey(rootNode, 'text'); }; recursivelyFindLayer(WMSLayers, nodeStructure.children, ''); succes(nodeStructure); }; let callback = (jsonData) => { parse(jsonData); }; let fail = (data) => { failure(data); }; this.getCapabilities(callback, fail, forceReload, xml2jsonrequestURL, options); }; /** Calls succes with an array of all layernames * Calls failure when something goes wrong */ getLayerNames (succes, failure, forceReload, xml2jsonrequestURL = this.xml2jsonrequestURL) { let callback = (data) => { let layerNames = []; let getNames = (layers) => { // alert(layers.children); for (let j = 0; j < layers.length; j++) { if (layers[j].name) { layerNames.push(layers[j].name); } if (layers[j].children) { getNames(layers[j].children); } } }; getNames(data.children); succes(layerNames); }; try { this.getNodes(callback, failure, forceReload, xml2jsonrequestURL); } catch (e) { failure(e); } }; /** Calls succes with an array of all layerobjects * Calls failure when something goes wrong */ getLayerObjectsFlat (succes, failure, forceReload, xml2jsonrequestURL = this.xml2jsonrequestURL, options = this._options) { if (!xml2jsonrequestURL) { xml2jsonrequestURL = this.xml2jsonrequestURL; } if (isDefined(this._flatLayerObject) && forceReload !== true) { succes(this._flatLayerObject); return; } let callback = (data) => { this._flatLayerObject = []; let getNames = (layers) => { // alert(layers.children); for (let j = 0; j < layers.length; j++) { if (layers[j].name) { this._flatLayerObject.push(layers[j]); } if (layers[j].children) { getNames(layers[j].children); } } }; getNames(data.children); succes(this._flatLayerObject); }; this.getNodes(callback, failure, forceReload, xml2jsonrequestURL, options); } };