@terrestris/ol-util
Version:
A set of helper classes for working with openLayers
122 lines • 6 kB
JavaScript
import { XMLParser } from 'fast-xml-parser';
import _get from 'lodash/get';
import _isFunction from 'lodash/isFunction';
import OlLayerImage from 'ol/layer/Image';
import OlSourceImageWMS from 'ol/source/ImageWMS';
import UrlUtil from '@terrestris/base-util/dist/UrlUtil/UrlUtil';
import LayerUtil from '../LayerUtil/LayerUtil';
/**
* Helper class to parse capabilities of WMS layers
*
* @class CapabilitiesUtil
*/
class CapabilitiesUtil {
/**
* Fetches and parses the WMS Capabilities document for the given URL.
*
* @param {string} capabilitiesUrl Url to WMS capabilities document.
* @param {RequestInit} fetchOpts Optional fetch options to make use of
* while requesting the Capabilities.
* @return {Promise<any>} An object representing the WMS capabilities.
*/
static async getWmsCapabilities(capabilitiesUrl, fetchOpts = {}) {
const capabilitiesResponse = await fetch(capabilitiesUrl, fetchOpts);
if (!capabilitiesResponse.ok) {
throw new Error('Could not get capabilities.');
}
const url = new URL(capabilitiesUrl);
const version = url.searchParams.get('VERSION');
const capabilitiesText = await capabilitiesResponse.text();
const parser = new XMLParser({
ignoreDeclaration: true,
removeNSPrefix: true,
ignoreAttributes: false,
attributeNamePrefix: '',
trimValues: true
});
const parsed = parser.parse(capabilitiesText);
return version === '1.3.0' ? parsed?.WMS_Capabilities : parsed?.WMT_MS_Capabilities;
}
/**
* Fetches and parses the WMS Capabilities document for the given layer.
*
* @param {WmsLayer} layer The layer to the get the Capabilites for.
* @param {RequestInit} fetchOpts Optional fetch options to make use of
* while requesting the Capabilities.
* @return {Promise<any>} An object representing the WMS capabilities.
*/
static async getWmsCapabilitiesByLayer(layer, fetchOpts = {}) {
const capabilitiesUrl = this.getCapabilitiesUrl(layer);
return await this.getWmsCapabilities(capabilitiesUrl, fetchOpts);
}
/**
* Returns the Capabilities URL for the given layer.
*
* @param {import("../types").WMSLayer} layer The layer to the get the Capabilities URL for.
* @return {string} The Capabilities URL.
*/
static getCapabilitiesUrl(layer) {
const layerSource = layer.getSource();
const layerBaseUrl = LayerUtil.getLayerUrl(layer);
const wmsVersion = layerSource?.getParams()?.VERSION || '1.3.0';
return UrlUtil.createValidGetCapabilitiesRequest(layerBaseUrl, 'WMS', wmsVersion);
}
/**
* Returns the layers from a parsed WMS GetCapabilities object.
*
* @param {Object} capabilities A capabilities object.
* @param {string} nameField Configure the field which should be set as the
* 'name' property in the openlayers layer.
* @param {(url: string) => string} [proxyFn] Optional proxy function which can be applied to
* `GetMap`, `GetFeatureInfo` and `GetLegendGraphic`
* requests to avoid CORS issues.
* @return {import("ol/layer/Image").default<any>[]} Array of OlLayerImage
*/
static getLayersFromWmsCapabilities(capabilities, nameField = 'Name', proxyFn) {
const wmsVersion = _get(capabilities, 'version');
let layersInCapabilities = _get(capabilities, 'Capability.Layer.Layer');
const wmsGetMapConfig = _get(capabilities, 'Capability.Request.GetMap');
const wmsGetFeatureInfoConfig = _get(capabilities, 'Capability.Request.GetFeatureInfo');
let getMapUrl;
let getFeatureInfoUrl;
if (Array.isArray(wmsGetMapConfig.DCPType) && Array.isArray(wmsGetFeatureInfoConfig.DCPType)) {
getMapUrl = _get(wmsGetMapConfig, 'DCPType[0].HTTP.Get.OnlineResource');
getFeatureInfoUrl = _get(wmsGetFeatureInfoConfig, 'DCPType[0].HTTP.Get.OnlineResource');
}
else {
getMapUrl = _get(wmsGetMapConfig, 'DCPType.HTTP.Get.OnlineResource.href');
getFeatureInfoUrl = _get(wmsGetFeatureInfoConfig, 'DCPType.HTTP.Get.OnlineResource.href');
}
if (!(layersInCapabilities instanceof Array)) {
layersInCapabilities = [layersInCapabilities];
}
return layersInCapabilities.map((layerObj) => {
const title = _get(layerObj, 'Attribution.Title');
const onlineResource = _get(layerObj, 'Attribution.OnlineResource');
const attributions = [onlineResource ? `<a target="_blank" href="${onlineResource}">${title}</a>` : title];
const legendUrl = _get(layerObj, 'Style[0].LegendURL[0].OnlineResource');
return new OlLayerImage({
opacity: 1,
properties: {
title: _get(layerObj, 'Title'),
name: _get(layerObj, nameField),
abstract: _get(layerObj, 'Abstract'),
getFeatureInfoUrl: _isFunction(proxyFn) ? proxyFn(getFeatureInfoUrl) : getFeatureInfoUrl,
getFeatureInfoFormats: _get(wmsGetFeatureInfoConfig, 'Format'),
legendUrl: _isFunction(proxyFn) ? proxyFn(legendUrl) : legendUrl,
queryable: _get(layerObj, 'queryable')
},
source: new OlSourceImageWMS({
url: _isFunction(proxyFn) ? proxyFn(getMapUrl) : getMapUrl,
attributions: attributions,
params: {
LAYERS: _get(layerObj, 'Name'),
VERSION: wmsVersion
}
})
});
});
}
}
export default CapabilitiesUtil;
//# sourceMappingURL=CapabilitiesUtil.js.map