@honua/react 0.0.20-alpha.0 → 0.1.1-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/contract/discovery.d.ts +231 -0
- package/contract/discovery.d.ts.map +1 -0
- package/contract/discovery.js +554 -0
- package/contract/edit-sketch.d.ts +8 -0
- package/contract/edit-sketch.d.ts.map +1 -1
- package/contract/edit-sketch.js +15 -0
- package/contract/edit-snapping.d.ts +160 -0
- package/contract/edit-snapping.d.ts.map +1 -0
- package/contract/edit-snapping.js +675 -0
- package/contract/generated/projjson-v0.7-crs-validator.d.ts +35 -0
- package/contract/generated/projjson-v0.7-crs-validator.d.ts.map +1 -0
- package/contract/generated/projjson-v0.7-crs-validator.js +3941 -0
- package/contract/index.d.ts +12 -1
- package/contract/index.d.ts.map +1 -1
- package/contract/index.js +4 -0
- package/contract/pmtiles.d.ts +193 -0
- package/contract/pmtiles.d.ts.map +1 -0
- package/contract/pmtiles.js +195 -0
- package/contract/protocol-module.d.ts +70 -0
- package/contract/protocol-module.d.ts.map +1 -0
- package/contract/protocol-module.js +1 -0
- package/contract/schema-envelope.d.ts +26 -0
- package/contract/schema-envelope.d.ts.map +1 -0
- package/contract/schema-envelope.js +25 -0
- package/contract/schema.d.ts +582 -0
- package/contract/schema.d.ts.map +1 -0
- package/contract/schema.js +2483 -0
- package/contract/source-capability-support.d.ts +6 -0
- package/contract/source-capability-support.d.ts.map +1 -0
- package/contract/source-capability-support.js +154 -0
- package/contract/source.d.ts +57 -15
- package/contract/source.d.ts.map +1 -1
- package/contract/source.js +368 -65
- package/contract/types.d.ts +171 -6
- package/contract/types.d.ts.map +1 -1
- package/contract/types.js +14 -14
- package/core/auth/client-credentials-provider.d.ts +51 -0
- package/core/auth/client-credentials-provider.d.ts.map +1 -0
- package/core/auth/client-credentials-provider.js +115 -0
- package/core/auth/credential-store.d.ts +52 -0
- package/core/auth/credential-store.d.ts.map +1 -0
- package/core/auth/credential-store.js +82 -0
- package/core/auth/index.d.ts +23 -0
- package/core/auth/index.d.ts.map +1 -0
- package/core/auth/index.js +20 -0
- package/core/auth/oauth2-provider.d.ts +114 -0
- package/core/auth/oauth2-provider.d.ts.map +1 -0
- package/core/auth/oauth2-provider.js +408 -0
- package/core/auth/pkce.d.ts +25 -0
- package/core/auth/pkce.d.ts.map +1 -0
- package/core/auth/pkce.js +46 -0
- package/core/auth/static-providers.d.ts +20 -0
- package/core/auth/static-providers.d.ts.map +1 -0
- package/core/auth/static-providers.js +26 -0
- package/core/auth/token-endpoint.d.ts +40 -0
- package/core/auth/token-endpoint.d.ts.map +1 -0
- package/core/auth/token-endpoint.js +133 -0
- package/core/auth/types.d.ts +144 -0
- package/core/auth/types.d.ts.map +1 -0
- package/core/auth/types.js +8 -0
- package/core/bounded-json.d.ts +4 -0
- package/core/bounded-json.d.ts.map +1 -0
- package/core/bounded-json.js +38 -0
- package/core/cache-state.d.ts +9 -0
- package/core/cache-state.d.ts.map +1 -1
- package/core/cache-state.js +10 -0
- package/core/capabilities-xml.d.ts +33 -0
- package/core/capabilities-xml.d.ts.map +1 -0
- package/core/capabilities-xml.js +331 -0
- package/core/client.d.ts +35 -2
- package/core/client.d.ts.map +1 -1
- package/core/client.js +167 -29
- package/core/error-classifications.d.ts +153 -0
- package/core/error-classifications.d.ts.map +1 -0
- package/core/error-classifications.js +140 -0
- package/core/error-code-registry.d.ts +158 -0
- package/core/error-code-registry.d.ts.map +1 -0
- package/core/error-code-registry.js +143 -0
- package/core/error-envelope.d.ts +68 -0
- package/core/error-envelope.d.ts.map +1 -0
- package/core/error-envelope.js +357 -0
- package/core/errors.d.ts +73 -25
- package/core/errors.d.ts.map +1 -1
- package/core/errors.js +113 -46
- package/core/geoparquet-sql.d.ts +190 -0
- package/core/geoparquet-sql.d.ts.map +1 -0
- package/core/geoparquet-sql.js +368 -0
- package/core/odata-key-path.d.ts +12 -0
- package/core/odata-key-path.d.ts.map +1 -0
- package/core/odata-key-path.js +28 -0
- package/core/odata-write-codec.d.ts +66 -0
- package/core/odata-write-codec.d.ts.map +1 -0
- package/core/odata-write-codec.js +1083 -0
- package/core/odata.d.ts +59 -7
- package/core/odata.d.ts.map +1 -1
- package/core/odata.js +431 -99
- package/core/ogc-endpoint-layout.d.ts +70 -0
- package/core/ogc-endpoint-layout.d.ts.map +1 -0
- package/core/ogc-endpoint-layout.js +173 -0
- package/core/ogc-features.d.ts.map +1 -1
- package/core/ogc-features.js +35 -17
- package/core/ogc-maps.d.ts +7 -0
- package/core/ogc-maps.d.ts.map +1 -1
- package/core/ogc-maps.js +46 -7
- package/core/ogc-processes.d.ts +2 -1
- package/core/ogc-processes.d.ts.map +1 -1
- package/core/ogc-processes.js +33 -5
- package/core/ogc-records.d.ts +9 -0
- package/core/ogc-records.d.ts.map +1 -1
- package/core/ogc-records.js +78 -29
- package/core/ogc-tiles.d.ts +10 -1
- package/core/ogc-tiles.d.ts.map +1 -1
- package/core/ogc-tiles.js +56 -17
- package/core/path-utils.d.ts +9 -0
- package/core/path-utils.d.ts.map +1 -1
- package/core/path-utils.js +19 -0
- package/core/protocol-transport.d.ts +1 -0
- package/core/protocol-transport.d.ts.map +1 -1
- package/core/request-pipeline.d.ts.map +1 -1
- package/core/request-pipeline.js +1 -1
- package/core/spatial-filter.d.ts +8 -4
- package/core/spatial-filter.d.ts.map +1 -1
- package/core/spatial-filter.js +206 -16
- package/core/stac-static.d.ts +55 -0
- package/core/stac-static.d.ts.map +1 -0
- package/core/stac-static.js +386 -0
- package/core/stac.d.ts +12 -0
- package/core/stac.d.ts.map +1 -1
- package/core/stac.js +45 -15
- package/core/surfaces.d.ts +13 -0
- package/core/surfaces.d.ts.map +1 -1
- package/core/surfaces.js +127 -16
- package/core/types.d.ts +174 -7
- package/core/types.d.ts.map +1 -1
- package/core/wfs-capabilities.d.ts +12 -0
- package/core/wfs-capabilities.d.ts.map +1 -1
- package/core/wfs-capabilities.js +22 -3
- package/core/wfs.d.ts +13 -0
- package/core/wfs.d.ts.map +1 -1
- package/core/wfs.js +35 -5
- package/core/wms-capabilities.d.ts +56 -84
- package/core/wms-capabilities.d.ts.map +1 -1
- package/core/wms-capabilities.js +212 -509
- package/core/wmts-capabilities.d.ts +62 -62
- package/core/wmts-capabilities.d.ts.map +1 -1
- package/core/wmts-capabilities.js +224 -371
- package/esri-compat/editor.d.ts +8 -0
- package/esri-compat/editor.d.ts.map +1 -1
- package/esri-compat/editor.js +13 -0
- package/esri-compat/feature-layer.d.ts +2 -0
- package/esri-compat/feature-layer.d.ts.map +1 -1
- package/esri-compat/feature-layer.js +1 -0
- package/esri-compat/identity-manager.d.ts +43 -0
- package/esri-compat/identity-manager.d.ts.map +1 -1
- package/esri-compat/identity-manager.js +131 -1
- package/esri-compat/layer-list.d.ts +11 -0
- package/esri-compat/layer-list.d.ts.map +1 -1
- package/esri-compat/layer-list.js +49 -0
- package/esri-compat/legend.d.ts +10 -0
- package/esri-compat/legend.d.ts.map +1 -1
- package/esri-compat/legend.js +27 -0
- package/esri-compat/oauth-info.d.ts +15 -0
- package/esri-compat/oauth-info.d.ts.map +1 -1
- package/esri-compat/oauth-info.js +27 -0
- package/esri-compat/portal.d.ts +197 -0
- package/esri-compat/portal.d.ts.map +1 -0
- package/esri-compat/portal.js +251 -0
- package/esri-compat/renderer-objects.d.ts +40 -0
- package/esri-compat/renderer-objects.d.ts.map +1 -0
- package/esri-compat/renderer-objects.js +62 -0
- package/esri-compat/sketch.d.ts +43 -0
- package/esri-compat/sketch.d.ts.map +1 -1
- package/esri-compat/sketch.js +46 -0
- package/esri-compat/snapping.d.ts +43 -0
- package/esri-compat/snapping.d.ts.map +1 -0
- package/esri-compat/snapping.js +45 -0
- package/esri-compat/url.d.ts.map +1 -1
- package/esri-compat/url.js +1 -1
- package/esri-compat/widget-host.d.ts +84 -0
- package/esri-compat/widget-host.d.ts.map +1 -0
- package/esri-compat/widget-host.js +159 -0
- package/filter-registry/index.d.ts +145 -0
- package/filter-registry/index.d.ts.map +1 -0
- package/filter-registry/index.js +531 -0
- package/generated-app/errors.d.ts +18 -2
- package/generated-app/errors.d.ts.map +1 -1
- package/generated-app/errors.js +44 -11
- package/map/automatic-mount-integration.d.ts +134 -0
- package/map/automatic-mount-integration.d.ts.map +1 -0
- package/map/automatic-mount-integration.js +305 -0
- package/map/automatic-source-strategy.d.ts +125 -0
- package/map/automatic-source-strategy.d.ts.map +1 -0
- package/map/automatic-source-strategy.js +494 -0
- package/map/data-to-map-bridge.d.ts +293 -0
- package/map/data-to-map-bridge.d.ts.map +1 -0
- package/map/data-to-map-bridge.js +817 -0
- package/map/geojson-projection.d.ts +33 -0
- package/map/geojson-projection.d.ts.map +1 -0
- package/map/geojson-projection.js +118 -0
- package/map/index.d.ts +14 -0
- package/map/index.d.ts.map +1 -1
- package/map/index.js +8 -0
- package/map/raster-source-spec.d.ts +30 -0
- package/map/raster-source-spec.d.ts.map +1 -0
- package/map/raster-source-spec.js +190 -0
- package/map/raster-source-strategy.d.ts +65 -0
- package/map/raster-source-strategy.d.ts.map +1 -0
- package/map/raster-source-strategy.js +232 -0
- package/map/source-to-maplibre.d.ts +91 -0
- package/map/source-to-maplibre.d.ts.map +1 -0
- package/map/source-to-maplibre.js +454 -0
- package/map/temporal-playback.d.ts +139 -0
- package/map/temporal-playback.d.ts.map +1 -0
- package/map/temporal-playback.js +247 -0
- package/package.json +19 -1
- package/query-planner/canonical.d.ts +7 -0
- package/query-planner/canonical.d.ts.map +1 -0
- package/query-planner/canonical.js +145 -0
- package/query-planner/cql2-json.d.ts +17 -0
- package/query-planner/cql2-json.d.ts.map +1 -0
- package/query-planner/cql2-json.js +646 -0
- package/query-planner/diagnostics.d.ts +35 -0
- package/query-planner/diagnostics.d.ts.map +1 -0
- package/query-planner/diagnostics.js +373 -0
- package/query-planner/duckdb.d.ts +79 -0
- package/query-planner/duckdb.d.ts.map +1 -0
- package/query-planner/duckdb.js +758 -0
- package/query-planner/execution-context.d.ts +5 -0
- package/query-planner/execution-context.d.ts.map +1 -0
- package/query-planner/execution-context.js +50 -0
- package/query-planner/executor.d.ts +5 -0
- package/query-planner/executor.d.ts.map +1 -0
- package/query-planner/executor.js +223 -0
- package/query-planner/geoservices.d.ts +91 -0
- package/query-planner/geoservices.d.ts.map +1 -0
- package/query-planner/geoservices.js +667 -0
- package/query-planner/grpc.d.ts +100 -0
- package/query-planner/grpc.d.ts.map +1 -0
- package/query-planner/grpc.js +736 -0
- package/query-planner/index.d.ts +44 -0
- package/query-planner/index.d.ts.map +1 -0
- package/query-planner/index.js +30 -0
- package/query-planner/ir.d.ts +20 -0
- package/query-planner/ir.d.ts.map +1 -0
- package/query-planner/ir.js +417 -0
- package/query-planner/local-aggregate.d.ts +5 -0
- package/query-planner/local-aggregate.d.ts.map +1 -0
- package/query-planner/local-aggregate.js +126 -0
- package/query-planner/odata.d.ts +48 -0
- package/query-planner/odata.d.ts.map +1 -0
- package/query-planner/odata.js +662 -0
- package/query-planner/ogc-compiler.d.ts +55 -0
- package/query-planner/ogc-compiler.d.ts.map +1 -0
- package/query-planner/ogc-compiler.js +480 -0
- package/query-planner/ogc-features.d.ts +53 -0
- package/query-planner/ogc-features.d.ts.map +1 -0
- package/query-planner/ogc-features.js +617 -0
- package/query-planner/planner.d.ts +17 -0
- package/query-planner/planner.d.ts.map +1 -0
- package/query-planner/planner.js +818 -0
- package/query-planner/resource.d.ts +94 -0
- package/query-planner/resource.d.ts.map +1 -0
- package/query-planner/resource.js +526 -0
- package/query-planner/semantic-canonical.d.ts +15 -0
- package/query-planner/semantic-canonical.d.ts.map +1 -0
- package/query-planner/semantic-canonical.js +62 -0
- package/query-planner/semantic-compat.d.ts +10 -0
- package/query-planner/semantic-compat.d.ts.map +1 -0
- package/query-planner/semantic-compat.js +35 -0
- package/query-planner/semantic-compiler.d.ts +64 -0
- package/query-planner/semantic-compiler.d.ts.map +1 -0
- package/query-planner/semantic-compiler.js +81 -0
- package/query-planner/semantic-literals.d.ts +30 -0
- package/query-planner/semantic-literals.d.ts.map +1 -0
- package/query-planner/semantic-literals.js +133 -0
- package/query-planner/semantic-types.d.ts +265 -0
- package/query-planner/semantic-types.d.ts.map +1 -0
- package/query-planner/semantic-types.js +1 -0
- package/query-planner/semantic.d.ts +54 -0
- package/query-planner/semantic.d.ts.map +1 -0
- package/query-planner/semantic.js +1421 -0
- package/query-planner/types.d.ts +560 -0
- package/query-planner/types.d.ts.map +1 -0
- package/query-planner/types.js +49 -0
- package/query-planner/wfs-semantic.d.ts +58 -0
- package/query-planner/wfs-semantic.d.ts.map +1 -0
- package/query-planner/wfs-semantic.js +547 -0
- package/query-planner/wfs.d.ts +6 -0
- package/query-planner/wfs.d.ts.map +1 -0
- package/query-planner/wfs.js +71 -0
- package/react/external-map.d.ts +67 -0
- package/react/external-map.d.ts.map +1 -0
- package/react/external-map.js +63 -0
- package/react/honua-map.d.ts.map +1 -1
- package/react/honua-map.js +3 -2
- package/react/honua-source-layer.d.ts +110 -0
- package/react/honua-source-layer.d.ts.map +1 -0
- package/react/honua-source-layer.js +101 -0
- package/react/hooks.d.ts +28 -0
- package/react/hooks.d.ts.map +1 -1
- package/react/hooks.js +26 -4
- package/react/index.d.ts +8 -0
- package/react/index.d.ts.map +1 -1
- package/react/index.js +5 -0
- package/react/query-cache.d.ts +26 -4
- package/react/query-cache.d.ts.map +1 -1
- package/react/query-cache.js +51 -8
- package/react/selection.d.ts +177 -0
- package/react/selection.d.ts.map +1 -0
- package/react/selection.js +0 -0
- package/react/use-mounted-source.d.ts +69 -0
- package/react/use-mounted-source.d.ts.map +1 -0
- package/react/use-mounted-source.js +346 -0
- package/runtime/edit-snapping.d.ts +107 -0
- package/runtime/edit-snapping.d.ts.map +1 -0
- package/runtime/edit-snapping.js +190 -0
- package/runtime/errors.d.ts +3 -2
- package/runtime/errors.d.ts.map +1 -1
- package/runtime/errors.js +19 -2
- package/runtime/index.d.ts +8 -2
- package/runtime/index.d.ts.map +1 -1
- package/runtime/index.js +4 -4
- package/runtime/load-package.d.ts.map +1 -1
- package/runtime/load-package.js +8 -0
- package/runtime/map-package-validation.d.ts +0 -13
- package/runtime/map-package-validation.d.ts.map +1 -1
- package/runtime/map-package-validation.js +0 -12
- package/runtime/map-package.d.ts +1 -1
- package/runtime/map-package.d.ts.map +1 -1
- package/runtime/maplibre-renderer.d.ts +41 -0
- package/runtime/maplibre-renderer.d.ts.map +1 -0
- package/runtime/maplibre-renderer.js +322 -0
- package/runtime/pmtiles-protocol.d.ts +77 -0
- package/runtime/pmtiles-protocol.d.ts.map +1 -0
- package/runtime/pmtiles-protocol.js +120 -0
- package/runtime/query-tiles.d.ts +2 -1
- package/runtime/query-tiles.d.ts.map +1 -1
- package/runtime/query-tiles.js +6 -2
- package/runtime/source-bridge.d.ts +4 -4
- package/runtime/source-bridge.d.ts.map +1 -1
- package/runtime/source-bridge.js +36 -56
- package/runtime/style-interactions.d.ts +3 -2
- package/runtime/style-interactions.d.ts.map +1 -1
- package/runtime/style-interactions.js +11 -3
- package/runtime/terra-draw-sketch.d.ts +275 -0
- package/runtime/terra-draw-sketch.d.ts.map +1 -0
- package/runtime/terra-draw-sketch.js +404 -0
- package/source-capability-registry.d.ts +1 -0
- package/source-capability-registry.js +1 -0
- package/source-capability-types.d.ts +186 -0
- package/source-capability-types.js +7 -0
- package/style/index.d.ts +2 -0
- package/style/index.d.ts.map +1 -1
- package/style/index.js +2 -0
- package/style/renderers.d.ts +326 -0
- package/style/renderers.d.ts.map +1 -0
- package/style/renderers.js +517 -0
- package/webmap/convert-renderer.d.ts +24 -3
- package/webmap/convert-renderer.d.ts.map +1 -1
- package/webmap/convert-renderer.js +93 -112
- package/webmap/index.d.ts +1 -1
- package/webmap/index.d.ts.map +1 -1
- package/webmap/index.js +1 -1
|
@@ -1,402 +1,255 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
* @module
|
|
9
|
-
*/
|
|
10
|
-
import { decodeXmlText as decodeXmlEntities } from "./xml-text.js";
|
|
11
|
-
export class HonuaWmtsCapabilitiesParseError extends Error {
|
|
12
|
-
constructor(message) {
|
|
13
|
-
super(message);
|
|
1
|
+
/** Bounded WMTS 1.0 capabilities projection. @module */
|
|
2
|
+
import { parseCapabilitiesXml, xmlAttribute, xmlChild, xmlChildren, xmlText, } from "./capabilities-xml.js";
|
|
3
|
+
import { HonuaSdkError } from "./error-envelope.js";
|
|
4
|
+
const incompleteTileMatrixSets = new WeakSet();
|
|
5
|
+
export class HonuaWmtsCapabilitiesParseError extends HonuaSdkError {
|
|
6
|
+
constructor(message, options = {}) {
|
|
7
|
+
super("core.wmts-capabilities-parse", message, options);
|
|
14
8
|
this.name = "HonuaWmtsCapabilitiesParseError";
|
|
15
9
|
}
|
|
16
10
|
}
|
|
17
|
-
/**
|
|
18
|
-
* Parse a `Capabilities` text body for WMTS 1.0 into the typed
|
|
19
|
-
* `WmtsCapabilities` shape.
|
|
20
|
-
*/
|
|
21
11
|
export function parseWmtsCapabilities(xml) {
|
|
22
|
-
|
|
23
|
-
|
|
12
|
+
try {
|
|
13
|
+
const root = parseCapabilitiesXml(xml, "WMTS");
|
|
14
|
+
if (root.localName !== "Capabilities")
|
|
15
|
+
throw new Error("missing <Capabilities> root element");
|
|
16
|
+
const warnings = [];
|
|
17
|
+
const serviceNode = xmlChild(root, "ServiceIdentification");
|
|
18
|
+
const contents = xmlChild(root, "Contents");
|
|
19
|
+
const service = compactObject({
|
|
20
|
+
title: xmlText(xmlChild(serviceNode, "Title")),
|
|
21
|
+
abstract: xmlText(xmlChild(serviceNode, "Abstract")),
|
|
22
|
+
});
|
|
23
|
+
const layers = Object.freeze(xmlChildren(contents, "Layer").flatMap((layer) => parseLayer(layer, warnings)));
|
|
24
|
+
const tileMatrixSets = Object.freeze(xmlChildren(contents, "TileMatrixSet").flatMap((matrixSet) => parseTileMatrixSet(matrixSet, warnings)));
|
|
25
|
+
const operations = Object.freeze(parseOperations(xmlChild(root, "OperationsMetadata")));
|
|
26
|
+
return Object.freeze({
|
|
27
|
+
version: xmlAttribute(root, "version") ?? "",
|
|
28
|
+
service,
|
|
29
|
+
layers,
|
|
30
|
+
tileMatrixSets,
|
|
31
|
+
operations,
|
|
32
|
+
warnings: Object.freeze(unique(warnings)),
|
|
33
|
+
});
|
|
24
34
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
35
|
+
catch (cause) {
|
|
36
|
+
if (cause instanceof HonuaWmtsCapabilitiesParseError)
|
|
37
|
+
throw cause;
|
|
38
|
+
const message = cause instanceof Error ? cause.message : "WMTS Capabilities XML is malformed";
|
|
39
|
+
throw new HonuaWmtsCapabilitiesParseError(message, { cause });
|
|
28
40
|
}
|
|
29
|
-
const version = readAttribute(root.openTag, "version") ?? "1.0.0";
|
|
30
|
-
const service = parseServiceMetadata(root.inner);
|
|
31
|
-
const contents = findElement(root.inner, 0, "Contents");
|
|
32
|
-
const layers = contents ? collectLayers(contents.inner) : [];
|
|
33
|
-
const tileMatrixSets = contents ? collectTileMatrixSets(contents.inner) : [];
|
|
34
|
-
return { version, service, layers, tileMatrixSets };
|
|
35
41
|
}
|
|
36
|
-
function
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const formats = collectChildText(node.inner, "Format");
|
|
61
|
-
const styles = collectStyles(node.inner);
|
|
62
|
-
const tileMatrixSetIds = collectTileMatrixSetLinks(node.inner);
|
|
63
|
-
const resources = collectResources(node.inner, "tile");
|
|
64
|
-
const featureInfoResources = collectResources(node.inner, "FeatureInfo");
|
|
65
|
-
const bbox = readWgs84BoundingBox(node.inner);
|
|
66
|
-
const layer = {
|
|
67
|
-
identifier,
|
|
68
|
-
formats,
|
|
69
|
-
styles,
|
|
70
|
-
tileMatrixSetIds,
|
|
71
|
-
resourceTemplates: resources,
|
|
72
|
-
featureInfoTemplates: featureInfoResources,
|
|
73
|
-
};
|
|
74
|
-
if (title !== undefined)
|
|
75
|
-
layer.title = title;
|
|
76
|
-
if (abstract !== undefined)
|
|
77
|
-
layer.abstract = abstract;
|
|
78
|
-
if (bbox !== undefined)
|
|
79
|
-
layer.bbox = bbox;
|
|
80
|
-
out.push(layer);
|
|
42
|
+
function parseOperations(node) {
|
|
43
|
+
const seen = new Set();
|
|
44
|
+
return xmlChildren(node, "Operation").flatMap((operation) => {
|
|
45
|
+
const name = xmlAttribute(operation, "name");
|
|
46
|
+
if (!name)
|
|
47
|
+
return [];
|
|
48
|
+
if (seen.has(name))
|
|
49
|
+
throw new Error(`WMTS repeats ${name} operation metadata.`);
|
|
50
|
+
seen.add(name);
|
|
51
|
+
const methods = [];
|
|
52
|
+
const getUrls = [];
|
|
53
|
+
const postUrls = [];
|
|
54
|
+
for (const dcp of xmlChildren(operation, "DCP")) {
|
|
55
|
+
const http = xmlChild(dcp, "HTTP");
|
|
56
|
+
for (const method of http?.children ?? []) {
|
|
57
|
+
if (method.localName !== "Get" && method.localName !== "Post")
|
|
58
|
+
continue;
|
|
59
|
+
const normalized = method.localName === "Get" ? "GET" : "POST";
|
|
60
|
+
if (!methods.includes(normalized))
|
|
61
|
+
methods.push(normalized);
|
|
62
|
+
const href = xmlAttribute(method, "href");
|
|
63
|
+
if (href)
|
|
64
|
+
(normalized === "GET" ? getUrls : postUrls).push(href);
|
|
65
|
+
}
|
|
81
66
|
}
|
|
82
|
-
|
|
67
|
+
return [
|
|
68
|
+
Object.freeze({
|
|
69
|
+
name,
|
|
70
|
+
methods: Object.freeze(methods),
|
|
71
|
+
getUrls: Object.freeze(unique(getUrls)),
|
|
72
|
+
postUrls: Object.freeze(unique(postUrls)),
|
|
73
|
+
}),
|
|
74
|
+
];
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function parseLayer(node, warnings) {
|
|
78
|
+
const identifier = xmlText(xmlChild(node, "Identifier"));
|
|
79
|
+
if (!identifier) {
|
|
80
|
+
warnings.push("WMTS Layer metadata without an identifier was ignored.");
|
|
81
|
+
return [];
|
|
83
82
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
cursor = node.endIndex;
|
|
83
|
+
const bbox = parseWgs84BoundingBox(xmlChild(node, "WGS84BoundingBox"), warnings);
|
|
84
|
+
return [
|
|
85
|
+
Object.freeze({
|
|
86
|
+
identifier,
|
|
87
|
+
...optional("title", xmlText(xmlChild(node, "Title"))),
|
|
88
|
+
...optional("abstract", xmlText(xmlChild(node, "Abstract"))),
|
|
89
|
+
formats: Object.freeze(unique(xmlChildren(node, "Format").flatMap((entry) => xmlText(entry) ?? []))),
|
|
90
|
+
infoFormats: Object.freeze(unique(xmlChildren(node, "InfoFormat").flatMap((entry) => xmlText(entry) ?? []))),
|
|
91
|
+
styles: Object.freeze(xmlChildren(node, "Style").flatMap((style) => parseStyle(style, warnings))),
|
|
92
|
+
dimensions: Object.freeze(xmlChildren(node, "Dimension").flatMap((dimension) => parseDimension(dimension, warnings))),
|
|
93
|
+
tileMatrixSetIds: Object.freeze(unique(xmlChildren(node, "TileMatrixSetLink").flatMap((link) => xmlText(xmlChild(link, "TileMatrixSet")) ?? []))),
|
|
94
|
+
resourceTemplates: Object.freeze(parseResources(node, "tile", warnings)),
|
|
95
|
+
featureInfoTemplates: Object.freeze(parseResources(node, "FeatureInfo", warnings)),
|
|
96
|
+
...(bbox ? { bbox } : {}),
|
|
97
|
+
}),
|
|
98
|
+
];
|
|
99
|
+
}
|
|
100
|
+
function parseStyle(node, warnings) {
|
|
101
|
+
const identifier = xmlText(xmlChild(node, "Identifier"));
|
|
102
|
+
if (!identifier) {
|
|
103
|
+
warnings.push("WMTS Style metadata without an identifier was ignored.");
|
|
104
|
+
return [];
|
|
107
105
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
let cursor = 0;
|
|
113
|
-
while (cursor < layerInner.length) {
|
|
114
|
-
const node = findElement(layerInner, cursor, "TileMatrixSetLink");
|
|
115
|
-
if (!node)
|
|
116
|
-
break;
|
|
117
|
-
const tms = readTextElement(node.inner, "TileMatrixSet") ?? readTextElement(node.inner, "ows:TileMatrixSet");
|
|
118
|
-
if (tms !== undefined && tms.length > 0)
|
|
119
|
-
out.push(tms);
|
|
120
|
-
cursor = node.endIndex;
|
|
106
|
+
const legend = xmlChild(node, "LegendURL");
|
|
107
|
+
const isDefault = xmlAttribute(node, "isDefault")?.toLowerCase();
|
|
108
|
+
if (isDefault !== undefined && !["0", "1", "false", "true"].includes(isDefault)) {
|
|
109
|
+
warnings.push("WMTS Style isDefault metadata was malformed and treated as false.");
|
|
121
110
|
}
|
|
122
|
-
return
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
111
|
+
return [
|
|
112
|
+
Object.freeze({
|
|
113
|
+
identifier,
|
|
114
|
+
...optional("title", xmlText(xmlChild(node, "Title"))),
|
|
115
|
+
isDefault: isDefault === "true" || isDefault === "1",
|
|
116
|
+
...optional("legendUrl", legend ? xmlAttribute(legend, "href") : undefined),
|
|
117
|
+
...optional("legendFormat", legend ? xmlAttribute(legend, "format") : undefined),
|
|
118
|
+
}),
|
|
119
|
+
];
|
|
120
|
+
}
|
|
121
|
+
function parseDimension(node, warnings) {
|
|
122
|
+
const identifier = xmlText(xmlChild(node, "Identifier"));
|
|
123
|
+
if (!identifier) {
|
|
124
|
+
warnings.push("WMTS Dimension metadata without an identifier was ignored.");
|
|
125
|
+
return [];
|
|
126
|
+
}
|
|
127
|
+
const current = xmlText(xmlChild(node, "Current"))?.toLowerCase();
|
|
128
|
+
if (current !== undefined && !["0", "1", "false", "true"].includes(current)) {
|
|
129
|
+
warnings.push("WMTS Dimension Current metadata was malformed and treated as false.");
|
|
140
130
|
}
|
|
141
|
-
return
|
|
131
|
+
return [
|
|
132
|
+
Object.freeze({
|
|
133
|
+
identifier,
|
|
134
|
+
...optional("default", xmlText(xmlChild(node, "Default"))),
|
|
135
|
+
current: current === "true" || current === "1",
|
|
136
|
+
values: Object.freeze(unique(xmlChildren(node, "Value").flatMap((entry) => xmlText(entry) ?? []))),
|
|
137
|
+
}),
|
|
138
|
+
];
|
|
139
|
+
}
|
|
140
|
+
function parseResources(node, resourceType, warnings) {
|
|
141
|
+
return xmlChildren(node, "ResourceURL").flatMap((resource) => {
|
|
142
|
+
if (xmlAttribute(resource, "resourceType")?.toLowerCase() !== resourceType.toLowerCase())
|
|
143
|
+
return [];
|
|
144
|
+
const template = xmlAttribute(resource, "template");
|
|
145
|
+
const format = xmlAttribute(resource, "format");
|
|
146
|
+
if (!template || !format) {
|
|
147
|
+
warnings.push(`WMTS ${resourceType} ResourceURL metadata without a format or template was ignored.`);
|
|
148
|
+
return [];
|
|
149
|
+
}
|
|
150
|
+
return [Object.freeze({ format, template })];
|
|
151
|
+
});
|
|
142
152
|
}
|
|
143
|
-
function
|
|
144
|
-
const node = findElement(layerInner, 0, "WGS84BoundingBox") ?? findElement(layerInner, 0, "ows:WGS84BoundingBox");
|
|
153
|
+
function parseWgs84BoundingBox(node, warnings) {
|
|
145
154
|
if (!node)
|
|
146
155
|
return undefined;
|
|
147
|
-
const lower =
|
|
148
|
-
const upper =
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
156
|
+
const lower = coordinatePair(xmlText(xmlChild(node, "LowerCorner")));
|
|
157
|
+
const upper = coordinatePair(xmlText(xmlChild(node, "UpperCorner")));
|
|
158
|
+
if (!lower ||
|
|
159
|
+
!upper ||
|
|
160
|
+
lower[0] > upper[0] ||
|
|
161
|
+
lower[1] > upper[1] ||
|
|
162
|
+
lower[0] < -180 ||
|
|
163
|
+
upper[0] > 180 ||
|
|
164
|
+
lower[1] < -90 ||
|
|
165
|
+
upper[1] > 90) {
|
|
166
|
+
warnings.push("WMTS WGS84BoundingBox metadata was malformed and ignored.");
|
|
157
167
|
return undefined;
|
|
158
168
|
}
|
|
159
|
-
return {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
let cursor = 0;
|
|
169
|
-
while (cursor < contentsInner.length) {
|
|
170
|
-
const node = findElement(contentsInner, cursor, "TileMatrixSet");
|
|
171
|
-
if (!node)
|
|
172
|
-
break;
|
|
173
|
-
const identifier = readTextElement(node.inner, "Identifier") ?? readTextElement(node.inner, "ows:Identifier");
|
|
174
|
-
// Skip the per-layer `TileMatrixSet` reference inside `TileMatrixSetLink`
|
|
175
|
-
// (those carry only an identifier and no nested `TileMatrix` children).
|
|
176
|
-
const matrices = collectTileMatrices(node.inner);
|
|
177
|
-
if (identifier !== undefined && identifier.length > 0 && matrices.length > 0) {
|
|
178
|
-
const supportedCrs = readTextElement(node.inner, "SupportedCRS") ?? readTextElement(node.inner, "ows:SupportedCRS");
|
|
179
|
-
const wellKnown = readTextElement(node.inner, "WellKnownScaleSet") ?? readTextElement(node.inner, "ows:WellKnownScaleSet");
|
|
180
|
-
const tms = {
|
|
181
|
-
identifier,
|
|
182
|
-
matrices,
|
|
183
|
-
};
|
|
184
|
-
if (supportedCrs !== undefined)
|
|
185
|
-
tms.supportedCrs = supportedCrs;
|
|
186
|
-
if (wellKnown !== undefined)
|
|
187
|
-
tms.wellKnownScaleSet = wellKnown;
|
|
188
|
-
out.push(tms);
|
|
189
|
-
}
|
|
190
|
-
cursor = node.endIndex;
|
|
169
|
+
return Object.freeze({ west: lower[0], south: lower[1], east: upper[0], north: upper[1] });
|
|
170
|
+
}
|
|
171
|
+
function parseTileMatrixSet(node, warnings) {
|
|
172
|
+
const identifier = xmlText(xmlChild(node, "Identifier"));
|
|
173
|
+
const matrixNodes = xmlChildren(node, "TileMatrix");
|
|
174
|
+
const matrices = Object.freeze(matrixNodes.flatMap((matrix) => parseTileMatrix(matrix, warnings)));
|
|
175
|
+
if (!identifier || matrices.length === 0) {
|
|
176
|
+
warnings.push("WMTS TileMatrixSet metadata without an identifier or valid matrices was ignored.");
|
|
177
|
+
return [];
|
|
191
178
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
matrixHeight,
|
|
224
|
-
topLeftCorner: [topLeft[0], topLeft[1]],
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
cursor = node.endIndex;
|
|
179
|
+
const matrixSet = Object.freeze({
|
|
180
|
+
identifier,
|
|
181
|
+
...optional("supportedCrs", xmlText(xmlChild(node, "SupportedCRS"))),
|
|
182
|
+
...optional("wellKnownScaleSet", xmlText(xmlChild(node, "WellKnownScaleSet"))),
|
|
183
|
+
matrices,
|
|
184
|
+
});
|
|
185
|
+
if (matrices.length !== matrixNodes.length)
|
|
186
|
+
incompleteTileMatrixSets.add(matrixSet);
|
|
187
|
+
return [matrixSet];
|
|
188
|
+
}
|
|
189
|
+
/** @internal Whether every matrix advertised by this parsed set was structurally valid. */
|
|
190
|
+
export function isWmtsCapabilityTileMatrixSetComplete(matrixSet) {
|
|
191
|
+
return !incompleteTileMatrixSets.has(matrixSet);
|
|
192
|
+
}
|
|
193
|
+
function parseTileMatrix(node, warnings) {
|
|
194
|
+
const identifier = xmlText(xmlChild(node, "Identifier"));
|
|
195
|
+
const scaleDenominator = positiveNumber(xmlText(xmlChild(node, "ScaleDenominator")));
|
|
196
|
+
const tileWidth = positiveSafeInteger(xmlText(xmlChild(node, "TileWidth")));
|
|
197
|
+
const tileHeight = positiveSafeInteger(xmlText(xmlChild(node, "TileHeight")));
|
|
198
|
+
const matrixWidth = positiveSafeInteger(xmlText(xmlChild(node, "MatrixWidth")));
|
|
199
|
+
const matrixHeight = positiveSafeInteger(xmlText(xmlChild(node, "MatrixHeight")));
|
|
200
|
+
const topLeftCorner = coordinatePair(xmlText(xmlChild(node, "TopLeftCorner")));
|
|
201
|
+
if (!identifier ||
|
|
202
|
+
scaleDenominator === undefined ||
|
|
203
|
+
tileWidth === undefined ||
|
|
204
|
+
tileHeight === undefined ||
|
|
205
|
+
matrixWidth === undefined ||
|
|
206
|
+
matrixHeight === undefined ||
|
|
207
|
+
!topLeftCorner) {
|
|
208
|
+
warnings.push("WMTS TileMatrix metadata with invalid numeric fields was ignored.");
|
|
209
|
+
return [];
|
|
228
210
|
}
|
|
229
|
-
return
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
return out;
|
|
244
|
-
}
|
|
245
|
-
function findElement(xml, from, tag) {
|
|
246
|
-
let i = from;
|
|
247
|
-
while (i < xml.length) {
|
|
248
|
-
if (xml[i] !== "<") {
|
|
249
|
-
i += 1;
|
|
250
|
-
continue;
|
|
251
|
-
}
|
|
252
|
-
const next = xml[i + 1];
|
|
253
|
-
if (next === "!" && xml.startsWith("<!--", i)) {
|
|
254
|
-
const end = xml.indexOf("-->", i + 4);
|
|
255
|
-
if (end < 0)
|
|
256
|
-
return undefined;
|
|
257
|
-
i = end + 3;
|
|
258
|
-
continue;
|
|
259
|
-
}
|
|
260
|
-
if (next === "!" && xml.startsWith("<![CDATA[", i)) {
|
|
261
|
-
const end = xml.indexOf("]]>", i + 9);
|
|
262
|
-
if (end < 0)
|
|
263
|
-
return undefined;
|
|
264
|
-
i = end + 3;
|
|
265
|
-
continue;
|
|
266
|
-
}
|
|
267
|
-
if (next === "?" || next === "!") {
|
|
268
|
-
const end = xml.indexOf(">", i);
|
|
269
|
-
if (end < 0)
|
|
270
|
-
return undefined;
|
|
271
|
-
i = end + 1;
|
|
272
|
-
continue;
|
|
273
|
-
}
|
|
274
|
-
const isClosing = next === "/";
|
|
275
|
-
const nameStart = isClosing ? i + 2 : i + 1;
|
|
276
|
-
const matchesTag = xml.startsWith(tag, nameStart) && isTagBoundary(xml.charCodeAt(nameStart + tag.length));
|
|
277
|
-
if (!matchesTag) {
|
|
278
|
-
const close = xml.indexOf(">", i);
|
|
279
|
-
if (close < 0)
|
|
280
|
-
return undefined;
|
|
281
|
-
i = close + 1;
|
|
282
|
-
continue;
|
|
283
|
-
}
|
|
284
|
-
const close = xml.indexOf(">", i);
|
|
285
|
-
if (close < 0)
|
|
286
|
-
return undefined;
|
|
287
|
-
const openTag = xml.slice(i, close + 1);
|
|
288
|
-
const selfClosing = !isClosing && xml.charCodeAt(close - 1) === 47;
|
|
289
|
-
if (selfClosing)
|
|
290
|
-
return { openTag, inner: "", endIndex: close + 1 };
|
|
291
|
-
if (isClosing) {
|
|
292
|
-
i = close + 1;
|
|
293
|
-
continue;
|
|
294
|
-
}
|
|
295
|
-
let depth = 1;
|
|
296
|
-
let cursor = close + 1;
|
|
297
|
-
while (cursor < xml.length && depth > 0) {
|
|
298
|
-
const angle = xml.indexOf("<", cursor);
|
|
299
|
-
if (angle < 0)
|
|
300
|
-
break;
|
|
301
|
-
const next2 = xml[angle + 1];
|
|
302
|
-
if (next2 === "!" && xml.startsWith("<!--", angle)) {
|
|
303
|
-
const end = xml.indexOf("-->", angle + 4);
|
|
304
|
-
if (end < 0)
|
|
305
|
-
return undefined;
|
|
306
|
-
cursor = end + 3;
|
|
307
|
-
continue;
|
|
308
|
-
}
|
|
309
|
-
if (next2 === "!" && xml.startsWith("<![CDATA[", angle)) {
|
|
310
|
-
const end = xml.indexOf("]]>", angle + 9);
|
|
311
|
-
if (end < 0)
|
|
312
|
-
return undefined;
|
|
313
|
-
cursor = end + 3;
|
|
314
|
-
continue;
|
|
315
|
-
}
|
|
316
|
-
const isCloser = next2 === "/";
|
|
317
|
-
const inspectStart = isCloser ? angle + 2 : angle + 1;
|
|
318
|
-
const matchesSame = xml.startsWith(tag, inspectStart) && isTagBoundary(xml.charCodeAt(inspectStart + tag.length));
|
|
319
|
-
const angleClose = xml.indexOf(">", angle);
|
|
320
|
-
if (angleClose < 0)
|
|
321
|
-
return undefined;
|
|
322
|
-
if (matchesSame) {
|
|
323
|
-
if (isCloser) {
|
|
324
|
-
depth -= 1;
|
|
325
|
-
if (depth === 0) {
|
|
326
|
-
return {
|
|
327
|
-
openTag,
|
|
328
|
-
inner: xml.slice(close + 1, angle),
|
|
329
|
-
endIndex: angleClose + 1,
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
else {
|
|
334
|
-
const innerSelfClose = xml.charCodeAt(angleClose - 1) === 47;
|
|
335
|
-
if (!innerSelfClose)
|
|
336
|
-
depth += 1;
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
cursor = angleClose + 1;
|
|
340
|
-
}
|
|
211
|
+
return [
|
|
212
|
+
Object.freeze({
|
|
213
|
+
identifier,
|
|
214
|
+
scaleDenominator,
|
|
215
|
+
tileWidth,
|
|
216
|
+
tileHeight,
|
|
217
|
+
matrixWidth,
|
|
218
|
+
matrixHeight,
|
|
219
|
+
topLeftCorner: Object.freeze(topLeftCorner),
|
|
220
|
+
}),
|
|
221
|
+
];
|
|
222
|
+
}
|
|
223
|
+
function coordinatePair(value) {
|
|
224
|
+
if (!value)
|
|
341
225
|
return undefined;
|
|
342
|
-
|
|
343
|
-
return undefined;
|
|
344
|
-
}
|
|
345
|
-
function isTagBoundary(code) {
|
|
346
|
-
return code === 32 || code === 9 || code === 10 || code === 13 || code === 47 || code === 62;
|
|
226
|
+
const values = value.trim().split(/\s+/).map(Number);
|
|
227
|
+
return values.length === 2 && values.every(Number.isFinite) ? [values[0], values[1]] : undefined;
|
|
347
228
|
}
|
|
348
|
-
function
|
|
349
|
-
|
|
350
|
-
if (idx < 0)
|
|
351
|
-
return undefined;
|
|
352
|
-
const after = openTag.slice(idx + name.length);
|
|
353
|
-
const eq = after.indexOf("=");
|
|
354
|
-
if (eq < 0)
|
|
229
|
+
function positiveNumber(value) {
|
|
230
|
+
if (!value)
|
|
355
231
|
return undefined;
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
if (
|
|
361
|
-
return undefined;
|
|
362
|
-
const end = after.indexOf(quote, cursor + 1);
|
|
363
|
-
if (end < 0)
|
|
232
|
+
const parsed = Number(value);
|
|
233
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;
|
|
234
|
+
}
|
|
235
|
+
function positiveSafeInteger(value) {
|
|
236
|
+
if (!value)
|
|
364
237
|
return undefined;
|
|
365
|
-
|
|
238
|
+
const parsed = Number(value);
|
|
239
|
+
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : undefined;
|
|
366
240
|
}
|
|
367
|
-
function
|
|
368
|
-
|
|
369
|
-
while (i < openTag.length) {
|
|
370
|
-
const found = openTag.indexOf(name, i);
|
|
371
|
-
if (found < 0)
|
|
372
|
-
return -1;
|
|
373
|
-
const before = openTag.charCodeAt(found - 1);
|
|
374
|
-
const isBoundaryStart = found === 0 || before === 32 || before === 9 || before === 10 || before === 13;
|
|
375
|
-
const after = openTag.charCodeAt(found + name.length);
|
|
376
|
-
const isBoundaryEnd = after === 61 || after === 32 || after === 9 || after === 10 || after === 13;
|
|
377
|
-
if (isBoundaryStart && isBoundaryEnd) {
|
|
378
|
-
return found;
|
|
379
|
-
}
|
|
380
|
-
i = found + 1;
|
|
381
|
-
}
|
|
382
|
-
return -1;
|
|
241
|
+
function unique(values) {
|
|
242
|
+
return [...new Set(values)];
|
|
383
243
|
}
|
|
384
|
-
function
|
|
385
|
-
|
|
386
|
-
if (!node)
|
|
387
|
-
return undefined;
|
|
388
|
-
return decodeXmlText(node.inner.trim());
|
|
244
|
+
function optional(key, value) {
|
|
245
|
+
return value === undefined ? {} : { [key]: value };
|
|
389
246
|
}
|
|
390
|
-
function
|
|
391
|
-
|
|
392
|
-
return text;
|
|
393
|
-
return decodeXmlEntities(text);
|
|
247
|
+
function compactObject(value) {
|
|
248
|
+
return Object.freeze(Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined)));
|
|
394
249
|
}
|
|
395
|
-
/** Find a layer by identifier in a parsed `WmtsCapabilities`. */
|
|
396
250
|
export function findWmtsLayer(capabilities, identifier) {
|
|
397
|
-
return capabilities.layers.find((
|
|
251
|
+
return capabilities.layers.find((layer) => layer.identifier === identifier);
|
|
398
252
|
}
|
|
399
|
-
/** Find a tile-matrix-set by identifier. */
|
|
400
253
|
export function findWmtsTileMatrixSet(capabilities, identifier) {
|
|
401
|
-
return capabilities.tileMatrixSets.find((
|
|
254
|
+
return capabilities.tileMatrixSets.find((tileMatrixSet) => tileMatrixSet.identifier === identifier);
|
|
402
255
|
}
|