UNPKG

@itwin/core-frontend

Version:
196 lines • 10.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.internalMapLayerImageryFormats = exports.ImageryMapLayerFormat = void 0; const internal_1 = require("../internal"); /** Base class imagery map layer formats. * Subclasses should override formatId and [[MapLayerFormat.createImageryProvider]]. * @see [[MapLayerFormat]] * @beta */ class ImageryMapLayerFormat extends internal_1.MapLayerFormat { /** @internal */ static createMapLayerTree(layerSettings, layerIndex, iModel) { return new internal_1.ImageryMapLayerTreeReference({ layerSettings, layerIndex, iModel }); } } exports.ImageryMapLayerFormat = ImageryMapLayerFormat; class WmsMapLayerFormat extends ImageryMapLayerFormat { static formatId = "WMS"; static createImageryProvider(settings) { return new internal_1.WmsMapLayerImageryProvider(settings); } static async validateSource(url, userName, password, ignoreCache) { const source = internal_1.MapLayerSource.fromJSON({ name: "", formatId: WmsMapLayerFormat.formatId, url }); if (source === undefined) return { status: internal_1.MapLayerSourceStatus.InvalidFormat }; source.userName = userName; source.password = password; return WmsMapLayerFormat.validate({ source, ignoreCache }); } static async validate(args) { const { source, ignoreCache } = args; const { url, userName, password } = source; try { let subLayers; const maxVisibleSubLayers = 50; const capabilities = await internal_1.WmsCapabilities.create(url, (userName && password ? { user: userName, password } : undefined), ignoreCache, source.collectQueryParams()); if (capabilities !== undefined) { subLayers = capabilities.getSubLayers(false); const rootsSubLayer = subLayers?.find((sublayer) => sublayer.parent === undefined); const hasTooManyLayers = subLayers && subLayers.length > maxVisibleSubLayers; if (!Array.isArray(subLayers)) return { status: internal_1.MapLayerSourceStatus.Valid, subLayers }; for (const subLayer of subLayers) { // In general for WMS, we prefer to have the children of root node visible, but not the root itself. // Thats simply to give more flexibility in the UI. // Two exceptions to this rule: If there are too many layers or the root node is not named. if (subLayer.id && subLayer.id === rootsSubLayer?.id && (!(subLayer.name && subLayer.name.length > 0) || hasTooManyLayers)) { subLayer.visible = true; break; // if root node is visible, don't bother turning ON any other layers } // Make children of the root node visible. if (subLayer.parent && subLayer.parent === rootsSubLayer?.id && !hasTooManyLayers) { const isUnnamedGroup = (layer) => { return layer.children && layer.children.length > 0 && (!layer.name || layer.name.length === 0); }; const makeChildrenVisible = (layers, layer) => { layer?.children?.forEach((childId) => { const childSubLayer = subLayers?.find((child) => child?.id === childId); if (childSubLayer) { childSubLayer.visible = true; if (isUnnamedGroup(childSubLayer)) makeChildrenVisible(layers, childSubLayer); } }); }; subLayer.visible = true; // If we got a unnamed group, make children visible recursively until we have a leaf or named group if (isUnnamedGroup(subLayer)) makeChildrenVisible(subLayers, subLayer); } } } return { status: internal_1.MapLayerSourceStatus.Valid, subLayers }; } catch (err) { let status = internal_1.MapLayerSourceStatus.InvalidUrl; if (err?.status === 401) { status = ((userName && password) ? internal_1.MapLayerSourceStatus.InvalidCredentials : internal_1.MapLayerSourceStatus.RequireAuth); } return { status }; } } } class WmtsMapLayerFormat extends ImageryMapLayerFormat { static formatId = "WMTS"; static createImageryProvider(settings) { return new internal_1.WmtsMapLayerImageryProvider(settings); } static async validateSource(url, userName, password, ignoreCache) { const source = internal_1.MapLayerSource.fromJSON({ name: "", formatId: WmtsMapLayerFormat.formatId, url }); if (source === undefined) return { status: internal_1.MapLayerSourceStatus.InvalidFormat }; source.userName = userName; source.password = password; return WmtsMapLayerFormat.validate({ source, ignoreCache }); } static async validate(args) { const { source, ignoreCache } = args; const { url, userName, password } = source; try { const subLayers = []; const capabilities = await internal_1.WmtsCapabilities.create(url, (userName && password ? { user: userName, password } : undefined), ignoreCache, source.collectQueryParams()); if (!capabilities) return { status: internal_1.MapLayerSourceStatus.InvalidUrl }; // Only returns layer that can be published in the Google maps or WGS84 aligned tile trees. let supportedTms = []; const googleMapsTms = capabilities?.contents?.getGoogleMapsCompatibleTileMatrixSet(); if (googleMapsTms) { supportedTms = googleMapsTms; } const wsg84Tms = capabilities?.contents?.getEpsg4326CompatibleTileMatrixSet(); if (wsg84Tms) { supportedTms = supportedTms.concat(wsg84Tms); } if (supportedTms.length === 0) { // This WMTS server doesn't support either GoogleMaps or WSG84 return { status: internal_1.MapLayerSourceStatus.InvalidCoordinateSystem }; } let subLayerId = 0; capabilities?.contents?.layers.forEach((layer) => { const hasSupportedTms = supportedTms?.some((tms) => { return layer.tileMatrixSetLinks.some((tmls) => tmls.tileMatrixSet === tms.identifier); }); if (hasSupportedTms) { subLayers.push({ name: layer.identifier, title: layer.title ?? layer.identifier, visible: (subLayers.length === 0), // Make the first layer visible. parent: undefined, children: undefined, id: subLayerId++, }); } }); // Return error if we could find a single compatible layer. if (subLayers.length === 0) return { status: internal_1.MapLayerSourceStatus.InvalidTileTree }; return { status: internal_1.MapLayerSourceStatus.Valid, subLayers }; } catch (err) { let status = internal_1.MapLayerSourceStatus.InvalidUrl; if (err?.status === 401) { status = ((userName && password) ? internal_1.MapLayerSourceStatus.InvalidCredentials : internal_1.MapLayerSourceStatus.RequireAuth); } return { status }; } } } class ArcGISMapLayerFormat extends ImageryMapLayerFormat { static formatId = "ArcGIS"; static async validateSource(url, userName, password, ignoreCache) { const source = internal_1.MapLayerSource.fromJSON({ name: "", formatId: WmtsMapLayerFormat.formatId, url }); if (source === undefined) return { status: internal_1.MapLayerSourceStatus.InvalidFormat }; source.userName = userName; source.password = password; return WmtsMapLayerFormat.validate({ source, ignoreCache }); } static async validate(args) { const urlValidation = internal_1.ArcGisUtilities.validateUrl(args.source.url, "MapServer"); if (urlValidation !== internal_1.MapLayerSourceStatus.Valid) return { status: urlValidation }; // Some Map service supporting only tiles don't include the 'Map' capabilities, thus we can't make it mandatory. return internal_1.ArcGisUtilities.validateSource({ ...args, capabilitiesFilter: [] }); } static createImageryProvider(settings) { return new internal_1.ArcGISMapLayerImageryProvider(settings); } } // eslint-disable-next-line @typescript-eslint/no-unused-vars class AzureMapsMapLayerFormat extends ImageryMapLayerFormat { static formatId = "AzureMaps"; static createImageryProvider(settings) { return new internal_1.AzureMapsLayerImageryProvider(settings); } } class BingMapsMapLayerFormat extends ImageryMapLayerFormat { static formatId = "BingMaps"; static createImageryProvider(settings) { return new internal_1.BingMapsImageryLayerProvider(settings); } } class MapBoxImageryMapLayerFormat extends ImageryMapLayerFormat { static formatId = "MapboxImagery"; static createImageryProvider(settings) { return new internal_1.MapBoxLayerImageryProvider(settings); } } class TileUrlMapLayerFormat extends ImageryMapLayerFormat { static formatId = "TileURL"; static createImageryProvider(settings) { return new internal_1.TileUrlImageryProvider(settings); } } /** @internal */ exports.internalMapLayerImageryFormats = [WmsMapLayerFormat, WmtsMapLayerFormat, ArcGISMapLayerFormat, /* AzureMapsMapLayerFormat, */ BingMapsMapLayerFormat, MapBoxImageryMapLayerFormat, TileUrlMapLayerFormat]; //# sourceMappingURL=MapLayerImageryFormats.js.map