// loaders.gl, MIT license import {XMLLoader} from '@loaders.gl/xml'; /** All capabilities of a WMTS service - response to a WMTS `GetCapabilities` data structure extracted from XML */ export type WMTSCapabilities = { serviceIdentification: { title: string; serviceTypeVersion: string; serviceType: string; }; serviceProvider: { providerName: string; providerSite: string; serviceContact: { individualName: string; positionName: string; contactInfo: { address: { administrativeArea: string; city: string; country: string; deliveryPoint: string; electronicMailAddress: string; postalCode: string; }; phone: { voice: string; }; }; }; }; operationsMetadata: { GetCapabilities: any; GetFeatureInfo: any; GetTile: any; }; contents: { layers: WMTSLayer[]; }; }; /** A layer in WMTS */ export type WMTSLayer = { abstract: string; identifier: string; title: string; formats: string[]; styles: { identifier: string; isDefault: string; title: string; abstract?: string; }[]; bounds: { left: number; right: number; bottom: number; top: number; }; tileMatrixSetLinks: { tileMatrixSet: string; }[]; tileMatrixSets: WMTSTileMatrixSet[]; }; /** A zoom level in WMTS */ export type WMTSTileMatrixSet = { identifier: string; matrixIds: { identifier: string; matrixHeight: number; matrixWidth: number; scaleDenominator: number; tileWidth: number; tileHeight: number; topLeftCorner: { lon: number; lat: number; }; }; } /** * Parses a typed data structure from raw XML for `GetCapabilities` response * @note Error handlings is fairly weak */ export function parseWMTSCapabilities(text: string, options): WMTSCapabilities { const parsedXML = XMLLoader.parseTextSync?.(text, {...options, xml: { ...options?.xml, removeNSPrefix: true, uncapitalizeKeys: true }}); const xmlCapabilities: any = parsedXML.Capabilities || parsedXML; return xmlCapabilities; } /** * Parses a typed data structure from raw XML for `GetCapabilities` response * @note Error handlings is fairly weak */ // export function parseWMTSCapabilities(text: string, options): WMTSCapabilities { // const parsedXML = XMLLoader.parseTextSync(text, options); // const xmlCapabilities: any = // parsedXML.WMT_MS_Capabilities || parsedXML.WMS_Capabilities || parsedXML; // return extractCapabilities(xmlCapabilities); // } /** Extract typed capability data from XML */ // function extractCapabilities(xml: any): WMTSCapabilities { // const capabilities: WMTSCapabilities = { // name: xml.Service?.Name || 'unnamed', // title: xml.Service?.Title, // keywords: [], // requests: {}, // layer: extractLayer(xml.Capability?.Layer), // raw: xml // }; // for (const keyword of xml.Service?.KeywordList?.Keyword || []) { // capabilities.keywords.push(keyword); // } // for (const [name, xmlRequest] of Object.entries(xml.Capability?.Request || {})) { // capabilities.requests[name] = extractRequest(name, xmlRequest); // } // return capabilities; // } // /** Extract typed request data from XML */ // function extractRequest(name: string, xmlRequest: any): WMSRequest { // const format: string | string[] = xmlRequest?.Format; // const mimeTypes: string[] = Array.isArray(format) ? format : [format]; // return {name, mimeTypes}; // } // /** Extract request data */ // function extractLayer(xmlLayer: any): WMSLayer { // const layer: WMSLayer = { // name: xmlLayer?.Name, // title: xmlLayer?.Title, // srs: xmlLayer?.SRS || [], // layers: [] // }; // // Single layer is not represented as array in XML // const xmlLayers = getXMLArray(xmlLayer?.Layer); // for (const xmlSubLayer of xmlLayers) { // layer.layers?.push(extractLayer(xmlSubLayer)); // } // return layer; // } // function getXMLArray(xmlValue: any) { // if (Array.isArray(xmlValue)) { // return xmlValue; // } // if (xmlValue) { // return [xmlValue]; // } // return []; // }