UNPKG

@itwin/core-frontend

Version:
200 lines • 10.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WmtsMapLayerImageryProvider = void 0; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module Tiles */ const core_bentley_1 = require("@itwin/core-bentley"); const core_common_1 = require("@itwin/core-common"); const internal_1 = require("../../../../tile/internal"); const tileMatrixSetToken = "{TileMatrixSet}"; const tileMatrixToken = "{TileMatrix}"; const tileColToken = "{TileCol}"; const tileRowToken = "{TileRow}"; class WmtsMapLayerImageryProvider extends internal_1.MapLayerImageryProvider { _baseUrl; _capabilities; _preferredLayerTileMatrixSet = new Map(); _preferredLayerStyle = new Map(); displayedLayerName = ""; _resourceUrlTemplate; _maximumZoomLevel; get mutualExclusiveSubLayer() { return true; } constructor(settings) { super(settings, true); this._maximumZoomLevel = this.defaultMaximumZoomLevel; this._baseUrl = internal_1.WmsUtilities.getBaseUrl(this._settings.url); } async initialize() { try { this._capabilities = await internal_1.WmtsCapabilities.create(this._baseUrl); this.initPreferredTileMatrixSet(); this.initPreferredStyle(); this.initDisplayedLayer(); this.initCartoRange(); this.initResourceUrl(); if (this._preferredLayerTileMatrixSet.size === 0 || this._preferredLayerStyle.size === 0) throw new core_common_1.ServerError(core_bentley_1.IModelStatus.ValidationFailed, ""); } catch (error) { // Don't throw error if unauthorized status: // We want the tile tree to be created, so that end-user can get feedback on which layer is missing credentials. // When credentials will be provided, a new provider will be created, and initialization should be fine. if (error?.status === 401) { this.setStatus(internal_1.MapLayerImageryProviderStatus.RequireAuth); } else { throw new core_common_1.ServerError(core_bentley_1.IModelStatus.ValidationFailed, ""); } } } get maximumZoomLevel() { return this._maximumZoomLevel; } initDisplayedLayer() { const layers = this._capabilities?.contents?.layers; if (0 === this._settings.subLayers.length && layers && layers.length > 0) { // No sub-layers defined in settings, pick first layer from capabilities. this.displayedLayerName = layers[0].identifier; return; } // If sub-layers are defined in settings, pick the first one that is visible. const firstDisplayedLayer = this._settings.subLayers.find((subLayer) => subLayer.visible); this.displayedLayerName = firstDisplayedLayer ? firstDisplayedLayer.name : this._settings.subLayers[0].name; } initResourceUrl() { const layersCapabilities = this._capabilities?.contents?.layers; if (undefined === layersCapabilities) { return; } const layerCapability = layersCapabilities.find((layer) => layer.identifier === this.displayedLayerName); if (undefined === layerCapability) { return; } let resourceUrl = layerCapability.resourceUrls.find((url) => url.format.includes("png")); if (undefined === resourceUrl) { // If no PNG resource URL is found, try to find a JPEG one. resourceUrl = layerCapability.resourceUrls.find((url) => url.format.includes("jpeg") || url.format.includes("jpg")); } if (undefined !== resourceUrl && (resourceUrl.template.indexOf(tileMatrixToken) > 0 && resourceUrl.template.indexOf(tileColToken) > 0 && resourceUrl.template.indexOf(tileRowToken) > 0)) { this._resourceUrlTemplate = resourceUrl.template; } } // Each layer can be served in multiple tile matrix set (i.e. TileTree). // We have to pick one for each layer: for now we look for a Google Maps compatible tile tree. initPreferredTileMatrixSet() { const googleMapsTms = this._capabilities?.contents?.getGoogleMapsCompatibleTileMatrixSet(); const wellGoogleKnownTms = googleMapsTms?.find((tms) => tms.wellKnownScaleSet?.toLowerCase().includes(internal_1.WmtsConstants.GOOGLEMAPS_COMPATIBLE_WELLKNOWNNAME)); this._capabilities?.contents?.layers.forEach((layer) => { let preferredTms; if (wellGoogleKnownTms && layer.tileMatrixSetLinks.some((tmsl) => tmsl.tileMatrixSet === wellGoogleKnownTms.identifier)) { // Favor tile matrix set that was explicitly marked as GoogleMaps compatible preferredTms = wellGoogleKnownTms; } else { // Search all compatible tile set matrix if previous attempt didn't work. // If more than one candidate is found, pick the tile set with the most LODs. let tileMatrixSets = googleMapsTms?.filter((tms) => { return layer.tileMatrixSetLinks.some((tmsl) => tmsl.tileMatrixSet === tms.identifier); }); if (!tileMatrixSets || tileMatrixSets.length === 0) { const eps4326CompatibleTms = this._capabilities?.contents?.getEpsg4326CompatibleTileMatrixSet(); tileMatrixSets = eps4326CompatibleTms?.filter((tms) => { return layer.tileMatrixSetLinks.some((tmsl) => tmsl.tileMatrixSet === tms.identifier); }); } if (tileMatrixSets && tileMatrixSets.length === 1) preferredTms = tileMatrixSets[0]; else if (tileMatrixSets && tileMatrixSets?.length > 1) preferredTms = tileMatrixSets.reduce((prev, current) => (prev.tileMatrix.length > current.tileMatrix.length) ? prev : current); } if (preferredTms !== undefined) { const tmsLink = layer.tileMatrixSetLinks.find((tmsl) => tmsl.tileMatrixSet === preferredTms.identifier); this._preferredLayerTileMatrixSet.set(layer.identifier, { tileMatrixSet: preferredTms, limits: tmsLink?.tileMatrixSetLimits }); this._maximumZoomLevel = Math.max(this._maximumZoomLevel, preferredTms.tileMatrix.length - 1); } }); } // Each layer can be published different style. We look for a style flagged as 'Default'. initPreferredStyle() { this._capabilities?.contents?.layers.forEach((layer) => { let preferredStyle; if (layer.styles.length === 1) preferredStyle = layer.styles[0]; else if (layer.styles.length > 1) { // If more than style is available, takes the default one, otherwise the first one. const defaultStyle = layer.styles.find((style) => style.isDefault); if (defaultStyle) preferredStyle = defaultStyle; else preferredStyle = layer.styles[0]; } if (preferredStyle) this._preferredLayerStyle.set(layer.identifier, preferredStyle); }); } initCartoRange() { const activeLayer = this._capabilities?.contents?.layers.find((layer) => layer.identifier === this.displayedLayerName); if (activeLayer?.wsg84BoundingBox) { if (this.cartoRange) this.cartoRange.extendRange(activeLayer.wsg84BoundingBox); else this.cartoRange = activeLayer.wsg84BoundingBox.clone(); } } getDisplayedTileMatrixSetAndLimits() { return this._preferredLayerTileMatrixSet.get(this.displayedLayerName); } _generateChildIds(quadId, resolveChildren) { const childIds = this.getPotentialChildIds(quadId); const matrixSetAndLimits = this.getDisplayedTileMatrixSetAndLimits(); if (!matrixSetAndLimits) { (0, core_bentley_1.assert)(false); // Must always hava a matrix set. return; } const limits = matrixSetAndLimits.limits?.[quadId.level + 1]?.limits; if (!limits) { resolveChildren(childIds); return; } const availableChildIds = []; for (const childId of childIds) if (limits.containsXY(childId.column, childId.row)) availableChildIds.push(childId); resolveChildren(availableChildIds); } get useGeographicTilingScheme() { const matrixSetAndLimits = this.getDisplayedTileMatrixSetAndLimits(); return matrixSetAndLimits ? (matrixSetAndLimits?.tileMatrixSet.identifier?.includes("4326") || matrixSetAndLimits?.tileMatrixSet.supportedCrs?.includes("4326")) : false; } async constructUrl(row, column, zoomLevel) { const matrixSetAndLimits = this.getDisplayedTileMatrixSetAndLimits(); const style = this._preferredLayerStyle.get(this.displayedLayerName); // Matrix identifier might be something other than standard 0..n zoom level, // so lookup the matrix identifier just in case. let tileMatrix; if (matrixSetAndLimits && matrixSetAndLimits.tileMatrixSet.tileMatrix.length > zoomLevel) tileMatrix = matrixSetAndLimits.tileMatrixSet.tileMatrix[zoomLevel].identifier; if (this._resourceUrlTemplate) { const tmpUrl = this._resourceUrlTemplate .replace(tileMatrixSetToken, matrixSetAndLimits?.tileMatrixSet.identifier ?? "") .replace(tileMatrixToken, tileMatrix ?? zoomLevel.toString()) .replace(tileColToken, column.toString()) .replace(tileRowToken, row.toString()); return this.appendCustomParams(tmpUrl); } const styleParam = (style?.identifier === undefined ? "" : `&style=${style.identifier}`); if (tileMatrix !== undefined && matrixSetAndLimits !== undefined) { const tmpUrl = `${this._baseUrl}?Service=WMTS&Version=1.0.0&Request=GetTile&Format=image%2Fpng&layer=${this.displayedLayerName}${styleParam}&TileMatrixSet=${matrixSetAndLimits.tileMatrixSet.identifier}&TileMatrix=${tileMatrix}&TileCol=${column}&TileRow=${row}`; return this.appendCustomParams(tmpUrl); } return ""; } } exports.WmtsMapLayerImageryProvider = WmtsMapLayerImageryProvider; //# sourceMappingURL=WmtsMapLayerImageryProvider.js.map