UNPKG

terriajs

Version:

Geospatial data visualization platform.

682 lines 29.9 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import i18next from "i18next"; import { computed, makeObservable, override, runInAction } from "mobx"; import Cartesian3 from "terriajs-cesium/Source/Core/Cartesian3"; import Cartographic from "terriajs-cesium/Source/Core/Cartographic"; import GeographicProjection from "terriajs-cesium/Source/Core/GeographicProjection"; import GeographicTilingScheme from "terriajs-cesium/Source/Core/GeographicTilingScheme"; import WebMercatorTilingScheme from "terriajs-cesium/Source/Core/WebMercatorTilingScheme"; import combine from "terriajs-cesium/Source/Core/combine"; import GetFeatureInfoFormat from "terriajs-cesium/Source/Scene/GetFeatureInfoFormat"; import ImageryLayerFeatureInfo from "terriajs-cesium/Source/Scene/ImageryLayerFeatureInfo"; import WebMapServiceImageryProvider from "terriajs-cesium/Source/Scene/WebMapServiceImageryProvider"; import URI from "urijs"; import TerriaError from "../../../Core/TerriaError"; import createTransformerAllowUndefined from "../../../Core/createTransformerAllowUndefined"; import filterOutUndefined from "../../../Core/filterOutUndefined"; import isDefined from "../../../Core/isDefined"; import CatalogMemberMixin, { getName } from "../../../ModelMixins/CatalogMemberMixin"; import DiffableMixin, { DiffStratum } from "../../../ModelMixins/DiffableMixin"; import ExportWebCoverageServiceMixin from "../../../ModelMixins/ExportWebCoverageServiceMixin"; import GetCapabilitiesMixin from "../../../ModelMixins/GetCapabilitiesMixin"; import MappableMixin from "../../../ModelMixins/MappableMixin"; import MinMaxLevelMixin from "../../../ModelMixins/MinMaxLevelMixin"; import TileErrorHandlerMixin from "../../../ModelMixins/TileErrorHandlerMixin"; import UrlMixin from "../../../ModelMixins/UrlMixin"; import { csvFeatureInfoContext } from "../../../Table/tableFeatureInfoContext"; import WebMapServiceCatalogItemTraits, { SUPPORTED_CRS_3857, SUPPORTED_CRS_4326 } from "../../../Traits/TraitsClasses/WebMapServiceCatalogItemTraits"; import CommonStrata from "../../Definition/CommonStrata"; import CreateModel from "../../Definition/CreateModel"; import LoadableStratum from "../../Definition/LoadableStratum"; import StratumOrder from "../../Definition/StratumOrder"; import proxyCatalogItemUrl from "../proxyCatalogItemUrl"; import WebMapServiceCapabilitiesStratum from "./WebMapServiceCapabilitiesStratum"; // Remove problematic query parameters from URLs (GetCapabilities, GetMap, ...) - these are handled separately const QUERY_PARAMETERS_TO_REMOVE = [ "request", "service", "x", "y", "width", "height", "bbox", "layers", "styles", "version", "format", "srs", "crs" ]; /** This LoadableStratum is responsible for setting WMS version based on CatalogItem.url */ export class WebMapServiceUrlStratum extends LoadableStratum(WebMapServiceCatalogItemTraits) { catalogItem; static stratumName = "wms-url-stratum"; constructor(catalogItem) { super(); this.catalogItem = catalogItem; makeObservable(this); } duplicateLoadableStratum(model) { return new WebMapServiceUrlStratum(model); } get useWmsVersion130() { if (this.catalogItem.url?.toLowerCase().includes("version=1.1.0") || this.catalogItem.url?.toLowerCase().includes("version=1.1.1")) { return false; } } } __decorate([ computed ], WebMapServiceUrlStratum.prototype, "useWmsVersion130", null); // Order is important so that the traits are overridden correctly StratumOrder.addLoadStratum(WebMapServiceUrlStratum.stratumName); StratumOrder.addLoadStratum(DiffStratum.stratumName); class WebMapServiceCatalogItem extends TileErrorHandlerMixin(ExportWebCoverageServiceMixin(DiffableMixin(MinMaxLevelMixin(GetCapabilitiesMixin(UrlMixin(MappableMixin(CatalogMemberMixin(CreateModel(WebMapServiceCatalogItemTraits))))))))) { /** * The collection of strings that indicate an Abstract property should be ignored. If these strings occur anywhere * in the Abstract, the Abstract will not be used. This makes it easy to filter out placeholder data like * Geoserver's "A compliant implementation of WMS..." stock abstract. */ static abstractsToIgnore = ["A compliant implementation of WMS"]; // hide elements in the info section which might show information about the datasource _sourceInfoItemNames = [ i18next.t("models.webMapServiceCatalogItem.getCapabilitiesUrl") ]; _webMapServiceCatalogGroup = undefined; /** Default WMS parameters for version=1.3.0 */ static defaultParameters130 = { transparent: true, format: "image/png", exceptions: "XML", styles: "", version: "1.3.0" }; static defaultGetFeatureParameters130 = { exceptions: "XML", version: "1.3.0" }; /** Default WMS parameters for version=1.1.1 */ static defaultParameters111 = { transparent: true, format: "image/png", exceptions: "application/vnd.ogc.se_xml", styles: "", tiled: true, version: "1.1.1" }; static defaultGetFeatureParameters111 = { exceptions: "application/vnd.ogc.se_xml", version: "1.1.1" }; static type = "wms"; constructor(id, terria, sourceReference) { super(id, terria, sourceReference); makeObservable(this); this.strata.set(WebMapServiceUrlStratum.stratumName, new WebMapServiceUrlStratum(this)); } get type() { return WebMapServiceCatalogItem.type; } get shortReport() { if (this.tilingScheme instanceof GeographicTilingScheme && this.terria.currentViewer.type === "Leaflet") { return i18next.t("map.cesium.notWebMercatorTilingScheme", this); } return super.shortReport; } get colorScaleRange() { if (this.supportsColorScaleRange) { return `${this.colorScaleMinimum},${this.colorScaleMaximum}`; } return undefined; } async createGetCapabilitiesStratumFromParent(capabilities) { const stratum = await WebMapServiceCapabilitiesStratum.load(this, capabilities); runInAction(() => { this.strata.set(GetCapabilitiesMixin.getCapabilitiesStratumName, stratum); }); } async forceLoadMapItems() { if (this.invalidLayers.length > 0) throw new TerriaError({ sender: this, title: i18next.t("models.webMapServiceCatalogItem.noLayerFoundTitle"), message: i18next.t("models.webMapServiceCatalogItem.noLayerFoundMessage", { name: getName(this), layers: this.invalidLayers.join(", ") }) }); } async forceLoadMetadata() { if (this.strata.get(GetCapabilitiesMixin.getCapabilitiesStratumName) !== undefined) return; const stratum = await WebMapServiceCapabilitiesStratum.load(this); runInAction(() => { this.strata.set(GetCapabilitiesMixin.getCapabilitiesStratumName, stratum); }); } get cacheDuration() { if (isDefined(super.cacheDuration)) { return super.cacheDuration; } return "0d"; } get layersArray() { if (Array.isArray(this.layers)) { return this.layers; } else if (this.layers) { return this.layers.split(","); } else { return []; } } /** LAYERS which are valid (i.e. exist in GetCapabilities). * These can be fetched from the server (eg GetMap request) */ get validLayers() { const gcStratum = this.strata.get(GetCapabilitiesMixin.getCapabilitiesStratumName); if (gcStratum) return this.layersArray .map((layer) => gcStratum.capabilities.findLayer(layer)?.Name) .filter(isDefined); return []; } /** LAYERS which are **INVALID** - they do **not** exist in GetCapabilities * These layers can **not** be fetched the server (eg GetMap request) */ get invalidLayers() { const gcStratum = this.strata.get(GetCapabilitiesMixin.getCapabilitiesStratumName); if (gcStratum) return this.layersArray.filter((layer) => !isDefined(gcStratum.capabilities.findLayer(layer)?.Name)); return []; } get stylesArray() { return this.styles?.split(",") ?? []; } get discreteTimes() { const getCapabilitiesStratum = this.strata.get(GetCapabilitiesMixin.getCapabilitiesStratumName); return getCapabilitiesStratum?.discreteTimes; } get defaultGetCapabilitiesUrl() { if (this.uri) { const baseUrl = QUERY_PARAMETERS_TO_REMOVE.reduce((url, parameter) => url .removeQuery(parameter) .removeQuery(parameter.toUpperCase()) .removeQuery(parameter.toLowerCase()), this.uri.clone()); return baseUrl .setSearch({ service: "WMS", version: this.useWmsVersion130 ? "1.3.0" : "1.1.1", request: "GetCapabilities" }) .toString(); } else { return undefined; } } get canDiffImages() { const hasValidDiffStyles = this.availableDiffStyles.some((diffStyle) => this.styleSelectableDimensions?.[0]?.options?.find((style) => style.id === diffStyle)); return hasValidDiffStyles === true; } showDiffImage(firstDate, secondDate, diffStyleId) { if (this.canDiffImages === false) { return; } // A helper to get the diff tag given a date string const firstDateStr = this.getTagForTime(firstDate); const secondDateStr = this.getTagForTime(secondDate); this.setTrait(CommonStrata.user, "firstDiffDate", firstDateStr); this.setTrait(CommonStrata.user, "secondDiffDate", secondDateStr); this.setTrait(CommonStrata.user, "diffStyleId", diffStyleId); this.setTrait(CommonStrata.user, "isShowingDiff", true); } clearDiffImage() { this.setTrait(CommonStrata.user, "firstDiffDate", undefined); this.setTrait(CommonStrata.user, "secondDiffDate", undefined); this.setTrait(CommonStrata.user, "diffStyleId", undefined); this.setTrait(CommonStrata.user, "isShowingDiff", false); } getLegendBaseUrl() { // Remove problematic query parameters from URL const baseUrl = QUERY_PARAMETERS_TO_REMOVE.reduce((url, parameter) => url .removeQuery(parameter) .removeQuery(parameter.toUpperCase()) .removeQuery(parameter.toLowerCase()), new URI(this.url)); return baseUrl.toString(); } getLegendUrlForStyle(styleId, firstDate, secondDate) { const firstTag = firstDate && this.getTagForTime(firstDate); const secondTag = secondDate && this.getTagForTime(secondDate); const time = filterOutUndefined([firstTag, secondTag]).join(","); const layerName = this.availableStyles.find((style) => style.styles.some((s) => s.name === styleId))?.layerName; const uri = URI(`${this.url}?service=WMS&version=1.1.0&request=GetLegendGraphic&format=image/png&transparent=True`) .addQuery("layer", encodeURIComponent(layerName || "")) .addQuery("styles", encodeURIComponent(styleId)); if (time) { uri.addQuery("time", time); } return uri.toString(); } get mapItems() { // Don't return anything if there are invalid layers // See forceLoadMapItems for error message if (this.invalidLayers.length > 0) return []; if (this.isShowingDiff === true) { return this._diffImageryParts ? [this._diffImageryParts] : []; } const result = []; const current = this._currentImageryParts; if (current) { result.push(current); } const next = this._nextImageryParts; if (next) { result.push(next); } return result; } get tilingScheme() { if (this.crs) { if (SUPPORTED_CRS_3857.includes(this.crs)) return new WebMercatorTilingScheme(); if (SUPPORTED_CRS_4326.includes(this.crs)) return new GeographicTilingScheme(); } return new WebMercatorTilingScheme(); } get _currentImageryParts() { const imageryProvider = this._createImageryProvider(this.currentDiscreteTimeTag); if (imageryProvider === undefined) { return undefined; } // Reset feature picking for the current imagery layer. // We disable feature picking for the next imagery layer. imageryProvider.enablePickFeatures = this.allowFeaturePicking; return { imageryProvider, alpha: this.opacity, show: this.show, clippingRectangle: this.clipToRectangle ? this.cesiumRectangle : undefined }; } get _nextImageryParts() { if (this.terria.timelineStack.contains(this) && !this.isPaused && this.nextDiscreteTimeTag) { const imageryProvider = this._createImageryProvider(this.nextDiscreteTimeTag); if (imageryProvider === undefined) { return undefined; } // Disable feature picking for the next imagery layer. imageryProvider.enablePickFeatures = false; return { imageryProvider, alpha: 0.0, show: true, clippingRectangle: this.clipToRectangle ? this.cesiumRectangle : undefined }; } else { return undefined; } } get _diffImageryParts() { const diffStyleId = this.diffStyleId; if (this.firstDiffDate === undefined || this.secondDiffDate === undefined || diffStyleId === undefined) { return; } const time = `${this.firstDiffDate},${this.secondDiffDate}`; const imageryProvider = this._createImageryProvider(time); if (imageryProvider) { return { imageryProvider, alpha: this.opacity, show: this.show, clippingRectangle: this.clipToRectangle ? this.cesiumRectangle : undefined }; } return undefined; } get diffModeParameters() { return this.isShowingDiff ? { styles: this.diffStyleId } : {}; } get diffModeGetFeatureInfoParameters() { return this.isShowingDiff ? { styles: this.diffStyleId } : {}; } getTagForTime(date) { const index = this.getDiscreteTimeIndex(date); return index !== undefined ? this.discreteTimesAsSortedJulianDates?.[index].tag : undefined; } _createImageryProvider = createTransformerAllowUndefined((time) => { // Don't show anything on the map until GetCapabilities finishes loading. if (this.isLoadingMetadata) { return undefined; } if (this.url === undefined) { return undefined; } console.log(`Creating new ImageryProvider for time ${time}`); // Set dimensionParameters const dimensionParameters = formatDimensionsForOws(this.dimensions); if (time !== undefined) { dimensionParameters.time = time; } // Construct parameters objects // We use slightly different parameters for GetMap and GetFeatureInfo requests const parameters = { ...(this.useWmsVersion130 ? WebMapServiceCatalogItem.defaultParameters130 : WebMapServiceCatalogItem.defaultParameters111), ...this.parameters, ...dimensionParameters }; const getFeatureInfoParameters = { ...(this.useWmsVersion130 ? WebMapServiceCatalogItem.defaultGetFeatureParameters130 : WebMapServiceCatalogItem.defaultGetFeatureParameters111), feature_count: 1 + (this.maximumShownFeatureInfos ?? this.terria.configParameters.defaultMaximumShownFeatureInfos), ...this.parameters, // Note order is important here, as getFeatureInfoParameters may override `time` dimension value ...dimensionParameters, ...this.getFeatureInfoParameters }; if (this.supportsColorScaleRange) { parameters.COLORSCALERANGE = this.colorScaleRange; } // Styles parameter is mandatory (for GetMap and GetFeatureInfo requests), but can be empty string to use default style parameters.styles = this.styles ?? ""; getFeatureInfoParameters.styles = this.styles ?? ""; Object.assign(parameters, this.diffModeParameters); Object.assign(getFeatureInfoParameters, this.diffModeGetFeatureInfoParameters); // Remove problematic query parameters from URL - these are handled by the parameters objects const baseUrl = QUERY_PARAMETERS_TO_REMOVE.reduce((url, parameter) => url .removeQuery(parameter) .removeQuery(parameter.toUpperCase()) .removeQuery(parameter.toLowerCase()), new URI(this.url)); // Set CRS for WMS 1.3.0 // Set SRS for WMS 1.1.1 const crs = this.useWmsVersion130 ? this.crs : undefined; const srs = this.useWmsVersion130 ? undefined : this.crs; const imageryOptions = { url: proxyCatalogItemUrl(this, baseUrl.toString()), layers: this.validLayers.length > 0 ? this.validLayers.join(",") : "", parameters, crs, srs, getFeatureInfoParameters, getFeatureInfoUrl: this.getFeatureInfoUrl, tileWidth: this.tileWidth, tileHeight: this.tileHeight, tilingScheme: this.tilingScheme, maximumLevel: this.getMaximumLevel(true) ?? this.maximumLevel, minimumLevel: this.minimumLevel, credit: this.attribution // Note: we set enablePickFeatures in _currentImageryParts and _nextImageryParts }; imageryOptions.getFeatureInfoFormats = this.getFeatureInfoFormats; if (imageryOptions.maximumLevel !== undefined && this.hideLayerAfterMinScaleDenominator) { // Make Cesium request one extra level so we can tell the user what's happening and return a blank image. ++imageryOptions.maximumLevel; } const imageryProvider = new WebMapServiceImageryProvider(imageryOptions); return this.updateRequestImage(imageryProvider); }); get styleSelectableDimensions() { return this.availableStyles.map((layer, layerIndex) => { let name = "Styles"; // If multiple layers -> prepend layer name to name if (this.availableStyles.length > 1) { // Attempt to get layer title from GetCapabilitiesStratum const layerTitle = layer.layerName && this.strata.get(GetCapabilitiesMixin.getCapabilitiesStratumName).capabilitiesLayers.get(layer.layerName)?.Title; name = `${layerTitle || layer.layerName || `Layer ${layerIndex + 1}`} styles`; } const options = filterOutUndefined(layer.styles.map(function (s) { if (isDefined(s.name)) { return { name: s.title || s.name || "", id: s.name }; } })); // Try to set selectedId to value stored in `styles` trait for this `layerIndex` // The `styles` parameter is CSV, a style for each layer const selectedId = this.styles?.split(",")?.[layerIndex]; return { name, id: `${this.uniqueId}-${layer.layerName}-styles`, options, selectedId, setDimensionValue: (stratumId, newStyle) => { if (!newStyle) return; runInAction(() => { const styles = this.styleSelectableDimensions.map((style) => style.selectedId || ""); styles[layerIndex] = newStyle; this.setTrait(stratumId, "styles", styles.join(",")); }); }, // There is no way of finding out default style if no style has been selected :( // To use the default style, we just send empty "styles" to WMS server // But if the server doesn't support GetLegendGraphic, then we can't request the default legend // Therefore - we only add the "Default style" / undefined option if supportsGetLegendGraphic is true allowUndefined: this.supportsGetLegendGraphic && options.length > 1, undefinedLabel: i18next.t("models.webMapServiceCatalogItem.defaultStyleLabel"), disable: this.isShowingDiff }; }); } get wmsDimensionSelectableDimensions() { const dimensions = []; // For each layer -> For each dimension this.availableDimensions.forEach((layer) => { layer.dimensions.forEach((dim) => { // Only add dimensions if hasn't already been added (multiple layers may have the same dimension) if (!isDefined(dim.name) || dim.values.length < 2 || dimensions.findIndex((findDim) => findDim.name === dim.name) !== -1) { return; } dimensions.push({ name: dim.name, id: `${this.uniqueId}-${dim.name}`, options: dim.values.map((value) => { let name = value; // Add units and unitSybol if defined if (typeof dim.units === "string" && dim.units !== "") { if (typeof dim.unitSymbol === "string" && dim.unitSymbol !== "") { name = `${value} (${dim.units} ${dim.unitSymbol})`; } else { name = `${value} (${dim.units})`; } } return { name, id: value }; }), // Set selectedId to value stored in `dimensions` trait, the default value, or the first available value selectedId: this.dimensions?.[dim.name]?.toString() || dim.default || dim.values[0], setDimensionValue: (stratumId, newDimension) => { let newDimensions = {}; newDimensions[dim.name] = newDimension; if (isDefined(this.dimensions)) { newDimensions = combine(newDimensions, this.dimensions); } runInAction(() => { this.setTrait(stratumId, "dimensions", newDimensions); }); } }); }); }); return dimensions; } get selectableDimensions() { if (this.disableDimensionSelectors) { return super.selectableDimensions; } return filterOutUndefined([ ...super.selectableDimensions, ...this.wmsDimensionSelectableDimensions, ...this.styleSelectableDimensions ]); } /** If GetFeatureInfo/GetTimeseries request is returning CSV, we need to parse it into TimeSeriesFeatureInfoContext. */ get featureInfoContext() { if (this.getFeatureInfoFormat.format !== "text/csv") return () => ({}); return csvFeatureInfoContext(this); } get getFeatureInfoFormats() { const customFormat = this.getFeatureInfoFormat; if (customFormat) { if (customFormat.type === "json") { return [ new GetFeatureInfoFormat("json", "application/json", (json) => geoJsonToFeatureInfoWithProject(json, this.tilingScheme.projection)) ]; } else { return [ new GetFeatureInfoFormat(customFormat.type, customFormat.format) ]; } } return [ new GetFeatureInfoFormat("json", "application/json", (json) => geoJsonToFeatureInfoWithProject(json, this.tilingScheme.projection)), new GetFeatureInfoFormat("xml", "text/xml"), new GetFeatureInfoFormat("csv", "text/csv") ]; } } __decorate([ override ], WebMapServiceCatalogItem.prototype, "shortReport", null); __decorate([ computed ], WebMapServiceCatalogItem.prototype, "colorScaleRange", null); __decorate([ override ], WebMapServiceCatalogItem.prototype, "cacheDuration", null); __decorate([ computed ], WebMapServiceCatalogItem.prototype, "layersArray", null); __decorate([ computed ], WebMapServiceCatalogItem.prototype, "validLayers", null); __decorate([ computed ], WebMapServiceCatalogItem.prototype, "invalidLayers", null); __decorate([ computed ], WebMapServiceCatalogItem.prototype, "stylesArray", null); __decorate([ computed ], WebMapServiceCatalogItem.prototype, "discreteTimes", null); __decorate([ computed ], WebMapServiceCatalogItem.prototype, "canDiffImages", null); __decorate([ computed ], WebMapServiceCatalogItem.prototype, "mapItems", null); __decorate([ computed ], WebMapServiceCatalogItem.prototype, "tilingScheme", null); __decorate([ computed ], WebMapServiceCatalogItem.prototype, "_currentImageryParts", null); __decorate([ computed ], WebMapServiceCatalogItem.prototype, "_nextImageryParts", null); __decorate([ computed ], WebMapServiceCatalogItem.prototype, "_diffImageryParts", null); __decorate([ computed ], WebMapServiceCatalogItem.prototype, "diffModeParameters", null); __decorate([ computed ], WebMapServiceCatalogItem.prototype, "diffModeGetFeatureInfoParameters", null); __decorate([ computed ], WebMapServiceCatalogItem.prototype, "styleSelectableDimensions", null); __decorate([ computed ], WebMapServiceCatalogItem.prototype, "wmsDimensionSelectableDimensions", null); __decorate([ override ], WebMapServiceCatalogItem.prototype, "selectableDimensions", null); __decorate([ computed ], WebMapServiceCatalogItem.prototype, "featureInfoContext", null); __decorate([ computed ], WebMapServiceCatalogItem.prototype, "getFeatureInfoFormats", null); /** * Add `_dim` prefix to dimensions for OWS (WMS, WCS...) excluding time, styles and elevation */ export function formatDimensionsForOws(dimensions) { if (!isDefined(dimensions)) { return {}; } return Object.entries(dimensions).reduce((formattedDimensions, [key, value]) => { formattedDimensions[["time", "styles", "elevation"].includes(key?.toLowerCase()) ? key : `dim_${key}`] = value; return formattedDimensions; }, {}); } // Take the GetFeatureInfo response and reproject the feature coordinates to geographic if necessary, so the position is correct when displayed on the map. // Cesium [GetFeatureInfoFormat](https://github.com/CesiumGS/cesium/blob/5754031f65646bee5f9d0e9a56dec7d3677a8b08/packages/engine/Source/Scene/GetFeatureInfoFormat.js#L74) assumes picked features is returned in geographic projection, so we need to convert them when tile scheme is not geographic. function geoJsonToFeatureInfoWithProject(json, projection) { const result = []; const features = json.features; for (let i = 0; i < features.length; ++i) { const feature = features[i]; const featureInfo = new ImageryLayerFeatureInfo(); featureInfo.data = feature; featureInfo.properties = feature.properties; featureInfo.configureNameFromProperties(feature.properties); featureInfo.configureDescriptionFromProperties(feature.properties); // If this is a point feature, use the coordinates of the point. if (!!feature.geometry && feature.geometry.type === "Point") { const x = feature.geometry.coordinates[0]; const y = feature.geometry.coordinates[1]; if (!projection || projection instanceof GeographicProjection) { featureInfo.position = Cartographic.fromDegrees(x, y); } else { const positionInMeters = new Cartesian3(x, y, 0); const cartographic = projection.unproject(positionInMeters); featureInfo.position = cartographic; } } result.push(featureInfo); } return result; } export default WebMapServiceCatalogItem; //# sourceMappingURL=WebMapServiceCatalogItem.js.map