@prushforth/map 1.0.0-preview.1
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/LICENSE +21 -0
- package/README.md +89 -0
- package/demo/index.html +78 -0
- package/dist/cjs/AttributionButton-DgbgLHy4.js +106 -0
- package/dist/cjs/MapTileLayer-D4vp8bR4.js +454 -0
- package/dist/cjs/app-globals-DY--Q2Nl.js +775 -0
- package/dist/cjs/calculatePosition-CDcdNl7C.js +92 -0
- package/dist/cjs/gcds-ext-map.cjs.js +47 -0
- package/dist/cjs/gcds-ext-map_2.cjs.entry.js +8081 -0
- package/dist/cjs/index-CW_WOSnc.js +32697 -0
- package/dist/cjs/index.cjs.js +2 -0
- package/dist/cjs/loader.cjs.js +14 -0
- package/dist/cjs/locale-_4nEyxeO.js +153 -0
- package/dist/cjs/map-a.cjs.entry.js +16 -0
- package/dist/cjs/map-caption.cjs.entry.js +55 -0
- package/dist/cjs/map-extent.cjs.entry.js +993 -0
- package/dist/cjs/map-feature.cjs.entry.js +636 -0
- package/dist/cjs/map-featurecaption.cjs.entry.js +14 -0
- package/dist/cjs/map-geometry.cjs.entry.js +36 -0
- package/dist/cjs/map-input.cjs.entry.js +348 -0
- package/dist/cjs/map-link.cjs.entry.js +6055 -0
- package/dist/cjs/map-meta.cjs.entry.js +40 -0
- package/dist/cjs/map-properties.cjs.entry.js +14 -0
- package/dist/cjs/map-select.cjs.entry.js +100 -0
- package/dist/cjs/map-span.cjs.entry.js +14 -0
- package/dist/cjs/map-style.cjs.entry.js +127 -0
- package/dist/cjs/map-tile.cjs.entry.js +274 -0
- package/dist/cjs/renderStyles-yOMXvf12.js +59 -0
- package/dist/collection/assets/canada.json +1 -0
- package/dist/collection/assets/images/w3community.ico +0 -0
- package/dist/collection/assets/mapml/en/apstile/arctic +18 -0
- package/dist/collection/assets/mapml/en/cbmtile/canvec +22 -0
- package/dist/collection/assets/mapml/en/cbmtile/cbmt +24 -0
- package/dist/collection/assets/mapml/en/cbmtile/cbmtgeom +20 -0
- package/dist/collection/assets/mapml/en/cbmtile/cbmtsimple +20 -0
- package/dist/collection/assets/mapml/en/cbmtile/current_conditions +33 -0
- package/dist/collection/assets/mapml/en/cbmtile/toporama +25 -0
- package/dist/collection/assets/mapml/en/custom/arcticsdi.mapml +18 -0
- package/dist/collection/assets/mapml/en/osmtile/cbmt +24 -0
- package/dist/collection/assets/mapml/en/osmtile/current_conditions +32 -0
- package/dist/collection/assets/mapml/en/osmtile/dark.mapml +19 -0
- package/dist/collection/assets/mapml/en/osmtile/light.mapml +19 -0
- package/dist/collection/assets/mapml/en/osmtile/osm +19 -0
- package/dist/collection/assets/mapml/en/osmtile/toporama +25 -0
- package/dist/collection/assets/mapml/fr/apstile/arctic +19 -0
- package/dist/collection/assets/mapml/fr/cbmtile/canvec +22 -0
- package/dist/collection/assets/mapml/fr/cbmtile/cbmt +24 -0
- package/dist/collection/assets/mapml/fr/cbmtile/cbmtgeom +20 -0
- package/dist/collection/assets/mapml/fr/cbmtile/cbmtsimple +20 -0
- package/dist/collection/assets/mapml/fr/cbmtile/current_conditions +25 -0
- package/dist/collection/assets/mapml/fr/cbmtile/toporama +25 -0
- package/dist/collection/assets/mapml/fr/osmtile/cbmt +24 -0
- package/dist/collection/assets/mapml/fr/osmtile/current_conditions +24 -0
- package/dist/collection/assets/mapml/fr/osmtile/dark.mapml +19 -0
- package/dist/collection/assets/mapml/fr/osmtile/light.mapml +19 -0
- package/dist/collection/assets/mapml/fr/osmtile/osm +19 -0
- package/dist/collection/assets/mapml/fr/osmtile/toporama +25 -0
- package/dist/collection/assets/pmtiles/darkTheme.js +19 -0
- package/dist/collection/assets/pmtiles/lightTheme.js +19 -0
- package/dist/collection/collection-manifest.json +28 -0
- package/dist/collection/components/gcds-ext-map/assets/pmtiles/darkTheme.js +19 -0
- package/dist/collection/components/gcds-ext-map/assets/pmtiles/lightTheme.js +19 -0
- package/dist/collection/components/gcds-ext-map/gcds-ext-map.css +2138 -0
- package/dist/collection/components/gcds-ext-map/gcds-ext-map.js +1517 -0
- package/dist/collection/components/gcds-ext-map/stories/gcds-ext-map.stories.js +367 -0
- package/dist/collection/components/map-a/map-a.js +89 -0
- package/dist/collection/components/map-caption/map-caption.js +52 -0
- package/dist/collection/components/map-extent/map-extent.js +809 -0
- package/dist/collection/components/map-feature/map-feature.js +724 -0
- package/dist/collection/components/map-featurecaption/map-featurecaption.js +6 -0
- package/dist/collection/components/map-geometry/map-geometry.js +57 -0
- package/dist/collection/components/map-input/map-input.js +355 -0
- package/dist/collection/components/map-layer/map-layer.js +1245 -0
- package/dist/collection/components/map-layer/stories/map-layer.stories.js +101 -0
- package/dist/collection/components/map-link/map-link.js +1149 -0
- package/dist/collection/components/map-meta/map-meta.js +82 -0
- package/dist/collection/components/map-properties/map-properties.js +7 -0
- package/dist/collection/components/map-select/map-select.js +145 -0
- package/dist/collection/components/map-span/map-span.js +7 -0
- package/dist/collection/components/map-style/map-style.js +144 -0
- package/dist/collection/components/map-tile/map-tile.js +370 -0
- package/dist/collection/components/utils/mapml/DOMTokenList.js +123 -0
- package/dist/collection/components/utils/mapml/DefaultMapOptions.js +11 -0
- package/dist/collection/components/utils/mapml/Util.js +1601 -0
- package/dist/collection/components/utils/mapml/control/AttributionButton.js +101 -0
- package/dist/collection/components/utils/mapml/control/FullscreenButton.js +181 -0
- package/dist/collection/components/utils/mapml/control/GeolocationButton.js +70 -0
- package/dist/collection/components/utils/mapml/control/LayerControl.js +212 -0
- package/dist/collection/components/utils/mapml/control/ReloadButton.js +75 -0
- package/dist/collection/components/utils/mapml/control/ScaleBar.js +108 -0
- package/dist/collection/components/utils/mapml/control/SearchButton.js +565 -0
- package/dist/collection/components/utils/mapml/elementSupport/extents/createLayerControlForExtent.js +259 -0
- package/dist/collection/components/utils/mapml/elementSupport/inputs/heightInput.js +18 -0
- package/dist/collection/components/utils/mapml/elementSupport/inputs/hiddenInput.js +19 -0
- package/dist/collection/components/utils/mapml/elementSupport/inputs/locationInput.js +127 -0
- package/dist/collection/components/utils/mapml/elementSupport/inputs/widthInput.js +18 -0
- package/dist/collection/components/utils/mapml/elementSupport/inputs/zoomInput.js +30 -0
- package/dist/collection/components/utils/mapml/elementSupport/layers/calculatePosition.js +88 -0
- package/dist/collection/components/utils/mapml/elementSupport/layers/createLayerControlForLayer.js +326 -0
- package/dist/collection/components/utils/mapml/elementSupport/layers/renderStyles.js +55 -0
- package/dist/collection/components/utils/mapml/elementSupport/viewers/matchMedia.js +251 -0
- package/dist/collection/components/utils/mapml/features/featureRenderer.js +342 -0
- package/dist/collection/components/utils/mapml/features/geometry.js +268 -0
- package/dist/collection/components/utils/mapml/features/path.js +485 -0
- package/dist/collection/components/utils/mapml/handlers/AnnounceMovement.js +154 -0
- package/dist/collection/components/utils/mapml/handlers/ContextMenu.js +1436 -0
- package/dist/collection/components/utils/mapml/handlers/FeatureIndex.js +116 -0
- package/dist/collection/components/utils/mapml/handlers/QueryHandler.js +476 -0
- package/dist/collection/components/utils/mapml/handlers/keyboard.js +60 -0
- package/dist/collection/components/utils/mapml/layers/Crosshair.js +108 -0
- package/dist/collection/components/utils/mapml/layers/DebugOverlay.js +357 -0
- package/dist/collection/components/utils/mapml/layers/FeatureIndexOverlay.js +239 -0
- package/dist/collection/components/utils/mapml/layers/ImageLayer.js +136 -0
- package/dist/collection/components/utils/mapml/layers/MapExtentLayer.js +114 -0
- package/dist/collection/components/utils/mapml/layers/MapFeatureLayer.js +623 -0
- package/dist/collection/components/utils/mapml/layers/MapLayer.js +640 -0
- package/dist/collection/components/utils/mapml/layers/MapTileLayer.js +450 -0
- package/dist/collection/components/utils/mapml/layers/TemplatedFeaturesOrTilesLayer.js +346 -0
- package/dist/collection/components/utils/mapml/layers/TemplatedImageLayer.js +276 -0
- package/dist/collection/components/utils/mapml/layers/TemplatedPMTilesLayer.js +135 -0
- package/dist/collection/components/utils/mapml/layers/TemplatedTileLayer.js +664 -0
- package/dist/collection/components/utils/utils.js +26 -0
- package/dist/collection/fonts/icons/LICENSE.txt +92 -0
- package/dist/collection/fonts/icons/README.md +543 -0
- package/dist/collection/fonts/icons/gcds-icons.css +110 -0
- package/dist/collection/fonts/icons/gcds-icons.eot +0 -0
- package/dist/collection/fonts/icons/gcds-icons.svg +82 -0
- package/dist/collection/fonts/icons/gcds-icons.ttf +0 -0
- package/dist/collection/fonts/icons/gcds-icons.woff +0 -0
- package/dist/collection/fonts/lato/LICENSE.txt +48 -0
- package/dist/collection/fonts/lato/README.md +195 -0
- package/dist/collection/fonts/lato/gcds-lato-italic.woff +0 -0
- package/dist/collection/fonts/lato/gcds-lato-italic.woff2 +0 -0
- package/dist/collection/fonts/lato/gcds-lato.css +30 -0
- package/dist/collection/fonts/lato/gcds-lato.woff +0 -0
- package/dist/collection/fonts/lato/gcds-lato.woff2 +0 -0
- package/dist/collection/fonts/noto-sans/LICENSE.txt +43 -0
- package/dist/collection/fonts/noto-sans/README.md +423 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-bold-italic.woff +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-bold-italic.woff2 +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-bold.woff +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-bold.woff2 +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-light-italic.woff +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-light-italic.woff2 +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-light.woff +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-light.woff2 +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-medium-italic.woff +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-medium-italic.woff2 +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-medium.woff +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-medium.woff2 +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-regular-italic.woff +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-regular-italic.woff2 +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-regular.woff +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-regular.woff2 +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-semibold-italic.woff +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-semibold-italic.woff2 +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-semibold.woff +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans-semibold.woff2 +0 -0
- package/dist/collection/fonts/noto-sans/gcds-noto-sans.css +89 -0
- package/dist/collection/fonts/noto-sans-mono/LICENSE.txt +93 -0
- package/dist/collection/fonts/noto-sans-mono/README.md +135 -0
- package/dist/collection/fonts/noto-sans-mono/gcds-noto-sans-mono.css +17 -0
- package/dist/collection/fonts/noto-sans-mono/gcds-noto-sans-mono.woff +0 -0
- package/dist/collection/fonts/noto-sans-mono/gcds-noto-sans-mono.woff2 +0 -0
- package/dist/collection/generated/locale.js +148 -0
- package/dist/collection/global/mapml-globals.js +916 -0
- package/dist/collection/index.js +1 -0
- package/dist/collection/leaflet-src.esm.js +14419 -0
- package/dist/components/gcds-ext-map.d.ts +11 -0
- package/dist/components/gcds-ext-map.js +10 -0
- package/dist/components/index.d.ts +35 -0
- package/dist/components/index.js +1 -0
- package/dist/components/map-a.d.ts +11 -0
- package/dist/components/map-a.js +1 -0
- package/dist/components/map-caption.d.ts +11 -0
- package/dist/components/map-caption.js +1 -0
- package/dist/components/map-extent.d.ts +11 -0
- package/dist/components/map-extent.js +1 -0
- package/dist/components/map-feature.d.ts +11 -0
- package/dist/components/map-feature.js +1 -0
- package/dist/components/map-featurecaption.d.ts +11 -0
- package/dist/components/map-featurecaption.js +1 -0
- package/dist/components/map-geometry.d.ts +11 -0
- package/dist/components/map-geometry.js +1 -0
- package/dist/components/map-input.d.ts +11 -0
- package/dist/components/map-input.js +1 -0
- package/dist/components/map-layer.d.ts +11 -0
- package/dist/components/map-layer.js +1 -0
- package/dist/components/map-link.d.ts +11 -0
- package/dist/components/map-link.js +1 -0
- package/dist/components/map-meta.d.ts +11 -0
- package/dist/components/map-meta.js +1 -0
- package/dist/components/map-properties.d.ts +11 -0
- package/dist/components/map-properties.js +1 -0
- package/dist/components/map-select.d.ts +11 -0
- package/dist/components/map-select.js +1 -0
- package/dist/components/map-span.d.ts +11 -0
- package/dist/components/map-span.js +1 -0
- package/dist/components/map-style.d.ts +11 -0
- package/dist/components/map-style.js +1 -0
- package/dist/components/map-tile.d.ts +11 -0
- package/dist/components/map-tile.js +1 -0
- package/dist/components/p-B4YLD_Og.js +1 -0
- package/dist/components/p-BE41zrui.js +1 -0
- package/dist/components/p-Bpv_U_Lb.js +1 -0
- package/dist/components/p-CwRxGZga.js +5 -0
- package/dist/components/p-EYVT9Efh.js +1 -0
- package/dist/components/p-gwC_yeRa.js +1 -0
- package/dist/esm/AttributionButton-CfaoSLCu.js +103 -0
- package/dist/esm/MapTileLayer-DvC_iOIS.js +451 -0
- package/dist/esm/app-globals-De5ze2BD.js +773 -0
- package/dist/esm/calculatePosition-B4YLD_Og.js +90 -0
- package/dist/esm/gcds-ext-map.js +43 -0
- package/dist/esm/gcds-ext-map_2.entry.js +8078 -0
- package/dist/esm/index-BUsJ7i5g.js +32656 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/loader.js +12 -0
- package/dist/esm/locale-Bpv_U_Lb.js +150 -0
- package/dist/esm/map-a.entry.js +14 -0
- package/dist/esm/map-caption.entry.js +53 -0
- package/dist/esm/map-extent.entry.js +991 -0
- package/dist/esm/map-feature.entry.js +634 -0
- package/dist/esm/map-featurecaption.entry.js +12 -0
- package/dist/esm/map-geometry.entry.js +34 -0
- package/dist/esm/map-input.entry.js +346 -0
- package/dist/esm/map-link.entry.js +6035 -0
- package/dist/esm/map-meta.entry.js +38 -0
- package/dist/esm/map-properties.entry.js +12 -0
- package/dist/esm/map-select.entry.js +98 -0
- package/dist/esm/map-span.entry.js +12 -0
- package/dist/esm/map-style.entry.js +125 -0
- package/dist/esm/map-tile.entry.js +272 -0
- package/dist/esm/renderStyles-EYVT9Efh.js +57 -0
- package/dist/gcds-ext-map/assets/canada.json +1 -0
- package/dist/gcds-ext-map/assets/images/w3community.ico +0 -0
- package/dist/gcds-ext-map/assets/mapml/en/apstile/arctic +18 -0
- package/dist/gcds-ext-map/assets/mapml/en/cbmtile/canvec +22 -0
- package/dist/gcds-ext-map/assets/mapml/en/cbmtile/cbmt +24 -0
- package/dist/gcds-ext-map/assets/mapml/en/cbmtile/cbmtgeom +20 -0
- package/dist/gcds-ext-map/assets/mapml/en/cbmtile/cbmtsimple +20 -0
- package/dist/gcds-ext-map/assets/mapml/en/cbmtile/current_conditions +33 -0
- package/dist/gcds-ext-map/assets/mapml/en/cbmtile/toporama +25 -0
- package/dist/gcds-ext-map/assets/mapml/en/custom/arcticsdi.mapml +18 -0
- package/dist/gcds-ext-map/assets/mapml/en/osmtile/cbmt +24 -0
- package/dist/gcds-ext-map/assets/mapml/en/osmtile/current_conditions +32 -0
- package/dist/gcds-ext-map/assets/mapml/en/osmtile/dark.mapml +19 -0
- package/dist/gcds-ext-map/assets/mapml/en/osmtile/light.mapml +19 -0
- package/dist/gcds-ext-map/assets/mapml/en/osmtile/osm +19 -0
- package/dist/gcds-ext-map/assets/mapml/en/osmtile/toporama +25 -0
- package/dist/gcds-ext-map/assets/mapml/fr/apstile/arctic +19 -0
- package/dist/gcds-ext-map/assets/mapml/fr/cbmtile/canvec +22 -0
- package/dist/gcds-ext-map/assets/mapml/fr/cbmtile/cbmt +24 -0
- package/dist/gcds-ext-map/assets/mapml/fr/cbmtile/cbmtgeom +20 -0
- package/dist/gcds-ext-map/assets/mapml/fr/cbmtile/cbmtsimple +20 -0
- package/dist/gcds-ext-map/assets/mapml/fr/cbmtile/current_conditions +25 -0
- package/dist/gcds-ext-map/assets/mapml/fr/cbmtile/toporama +25 -0
- package/dist/gcds-ext-map/assets/mapml/fr/osmtile/cbmt +24 -0
- package/dist/gcds-ext-map/assets/mapml/fr/osmtile/current_conditions +24 -0
- package/dist/gcds-ext-map/assets/mapml/fr/osmtile/dark.mapml +19 -0
- package/dist/gcds-ext-map/assets/mapml/fr/osmtile/light.mapml +19 -0
- package/dist/gcds-ext-map/assets/mapml/fr/osmtile/osm +19 -0
- package/dist/gcds-ext-map/assets/mapml/fr/osmtile/toporama +25 -0
- package/dist/gcds-ext-map/assets/pmtiles/darkTheme.js +19 -0
- package/dist/gcds-ext-map/assets/pmtiles/lightTheme.js +19 -0
- package/dist/gcds-ext-map/fonts/icons/LICENSE.txt +92 -0
- package/dist/gcds-ext-map/fonts/icons/README.md +543 -0
- package/dist/gcds-ext-map/fonts/icons/gcds-icons.css +110 -0
- package/dist/gcds-ext-map/fonts/icons/gcds-icons.eot +0 -0
- package/dist/gcds-ext-map/fonts/icons/gcds-icons.svg +82 -0
- package/dist/gcds-ext-map/fonts/icons/gcds-icons.ttf +0 -0
- package/dist/gcds-ext-map/fonts/icons/gcds-icons.woff +0 -0
- package/dist/gcds-ext-map/fonts/lato/LICENSE.txt +48 -0
- package/dist/gcds-ext-map/fonts/lato/README.md +195 -0
- package/dist/gcds-ext-map/fonts/lato/gcds-lato-italic.woff +0 -0
- package/dist/gcds-ext-map/fonts/lato/gcds-lato-italic.woff2 +0 -0
- package/dist/gcds-ext-map/fonts/lato/gcds-lato.css +30 -0
- package/dist/gcds-ext-map/fonts/lato/gcds-lato.woff +0 -0
- package/dist/gcds-ext-map/fonts/lato/gcds-lato.woff2 +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/LICENSE.txt +43 -0
- package/dist/gcds-ext-map/fonts/noto-sans/README.md +423 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-bold-italic.woff +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-bold-italic.woff2 +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-bold.woff +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-bold.woff2 +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-light-italic.woff +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-light-italic.woff2 +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-light.woff +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-light.woff2 +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-medium-italic.woff +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-medium-italic.woff2 +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-medium.woff +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-medium.woff2 +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-regular-italic.woff +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-regular-italic.woff2 +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-regular.woff +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-regular.woff2 +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-semibold-italic.woff +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-semibold-italic.woff2 +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-semibold.woff +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans-semibold.woff2 +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans/gcds-noto-sans.css +89 -0
- package/dist/gcds-ext-map/fonts/noto-sans-mono/LICENSE.txt +93 -0
- package/dist/gcds-ext-map/fonts/noto-sans-mono/README.md +135 -0
- package/dist/gcds-ext-map/fonts/noto-sans-mono/gcds-noto-sans-mono.css +17 -0
- package/dist/gcds-ext-map/fonts/noto-sans-mono/gcds-noto-sans-mono.woff +0 -0
- package/dist/gcds-ext-map/fonts/noto-sans-mono/gcds-noto-sans-mono.woff2 +0 -0
- package/dist/gcds-ext-map/gcds-ext-map.esm.js +1 -0
- package/dist/gcds-ext-map/index.esm.js +0 -0
- package/dist/gcds-ext-map/leaflet-src.esm.js +14419 -0
- package/dist/gcds-ext-map/p-1b22f774.entry.js +1 -0
- package/dist/gcds-ext-map/p-29b4ba34.entry.js +1 -0
- package/dist/gcds-ext-map/p-2dd09d44.entry.js +1 -0
- package/dist/gcds-ext-map/p-3fef47e5.entry.js +1 -0
- package/dist/gcds-ext-map/p-4e324a1d.entry.js +1 -0
- package/dist/gcds-ext-map/p-4f4a6873.entry.js +1 -0
- package/dist/gcds-ext-map/p-9cc5ad37.entry.js +1 -0
- package/dist/gcds-ext-map/p-9edfea7d.entry.js +1 -0
- package/dist/gcds-ext-map/p-B4YLD_Og.js +1 -0
- package/dist/gcds-ext-map/p-B8Id5Ptd.js +1 -0
- package/dist/gcds-ext-map/p-BUsJ7i5g.js +6 -0
- package/dist/gcds-ext-map/p-Bpv_U_Lb.js +1 -0
- package/dist/gcds-ext-map/p-CtOuMgy9.js +1 -0
- package/dist/gcds-ext-map/p-Dd474fsL.js +1 -0
- package/dist/gcds-ext-map/p-EYVT9Efh.js +1 -0
- package/dist/gcds-ext-map/p-a67d721d.entry.js +1 -0
- package/dist/gcds-ext-map/p-b16e862b.entry.js +1 -0
- package/dist/gcds-ext-map/p-b9cbf1e0.entry.js +10 -0
- package/dist/gcds-ext-map/p-cab5246e.entry.js +1 -0
- package/dist/gcds-ext-map/p-d58d409b.entry.js +1 -0
- package/dist/gcds-ext-map/p-dfa21368.entry.js +1 -0
- package/dist/gcds-ext-map/p-f211048a.entry.js +1 -0
- package/dist/index.cjs.js +1 -0
- package/dist/index.js +1 -0
- package/dist/types/components/gcds-ext-map/gcds-ext-map.d.ts +125 -0
- package/dist/types/components/gcds-ext-map/stories/gcds-ext-map.stories.d.ts +230 -0
- package/dist/types/components/map-a/map-a.d.ts +7 -0
- package/dist/types/components/map-caption/map-caption.d.ts +7 -0
- package/dist/types/components/map-extent/map-extent.d.ts +53 -0
- package/dist/types/components/map-feature/map-feature.d.ts +50 -0
- package/dist/types/components/map-featurecaption/map-featurecaption.d.ts +3 -0
- package/dist/types/components/map-geometry/map-geometry.d.ts +7 -0
- package/dist/types/components/map-input/map-input.d.ts +24 -0
- package/dist/types/components/map-layer/map-layer.d.ts +85 -0
- package/dist/types/components/map-layer/stories/map-layer.stories.d.ts +96 -0
- package/dist/types/components/map-link/map-link.d.ts +66 -0
- package/dist/types/components/map-meta/map-meta.d.ts +11 -0
- package/dist/types/components/map-properties/map-properties.d.ts +3 -0
- package/dist/types/components/map-select/map-select.d.ts +13 -0
- package/dist/types/components/map-span/map-span.d.ts +5 -0
- package/dist/types/components/map-style/map-style.d.ts +17 -0
- package/dist/types/components/map-tile/map-tile.d.ts +32 -0
- package/dist/types/components/utils/mapml/DOMTokenList.d.ts +30 -0
- package/dist/types/components/utils/mapml/elementSupport/inputs/heightInput.d.ts +7 -0
- package/dist/types/components/utils/mapml/elementSupport/inputs/hiddenInput.d.ts +7 -0
- package/dist/types/components/utils/mapml/elementSupport/inputs/locationInput.d.ts +14 -0
- package/dist/types/components/utils/mapml/elementSupport/inputs/widthInput.d.ts +7 -0
- package/dist/types/components/utils/mapml/elementSupport/inputs/zoomInput.d.ts +11 -0
- package/dist/types/components/utils/mapml/layers/MapLayer.d.ts +69 -0
- package/dist/types/components/utils/utils.d.ts +2 -0
- package/dist/types/components.d.ts +521 -0
- package/dist/types/gcds-ext-map.d.ts +17 -0
- package/dist/types/generated/locale.d.ts +146 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/stencil-public-runtime.d.ts +1861 -0
- package/loader/cdn.js +1 -0
- package/loader/index.cjs.js +1 -0
- package/loader/index.d.ts +24 -0
- package/loader/index.es2017.js +1 -0
- package/loader/index.js +2 -0
- package/package.json +87 -0
|
@@ -0,0 +1,1245 @@
|
|
|
1
|
+
import { setOptions, DomUtil, bounds, point } from "leaflet";
|
|
2
|
+
import { Util } from "../utils/mapml/Util.js";
|
|
3
|
+
import * as MapLayerModule from "../utils/mapml/layers/MapLayer.js";
|
|
4
|
+
import { MapTileLayer } from "../utils/mapml/layers/MapTileLayer.js";
|
|
5
|
+
import { MapFeatureLayer } from "../utils/mapml/layers/MapFeatureLayer.js";
|
|
6
|
+
import { createLayerControlHTML } from "../utils/mapml/elementSupport/layers/createLayerControlForLayer.js";
|
|
7
|
+
export class GcdsMapLayer {
|
|
8
|
+
/*
|
|
9
|
+
* MapML Compatibility: The following properties are exposed on this.el for MapML compatibility:
|
|
10
|
+
* - _layer: The MapML layer instance
|
|
11
|
+
* - _layerControl: The layer control instance
|
|
12
|
+
* - _layerControlHTML: The layer control HTML elements
|
|
13
|
+
* - _fetchError: Boolean indicating if there was a fetch error
|
|
14
|
+
* - _layerControlCheckbox: The layer control checkbox element (set by createLayerControlHTML)
|
|
15
|
+
* - _opacitySlider: The opacity slider element (set by createLayerControlHTML)
|
|
16
|
+
* - Other layer control elements set dynamically by createLayerControlHTML
|
|
17
|
+
*/
|
|
18
|
+
el;
|
|
19
|
+
// Core properties matching BaseLayerElement observedAttributes
|
|
20
|
+
src;
|
|
21
|
+
checked;
|
|
22
|
+
hidden = false;
|
|
23
|
+
opacity = 1;
|
|
24
|
+
_opacity;
|
|
25
|
+
media;
|
|
26
|
+
get opacityValue() {
|
|
27
|
+
return this._opacity ?? this.opacity ?? 1.0;
|
|
28
|
+
}
|
|
29
|
+
_layer;
|
|
30
|
+
_layerControl;
|
|
31
|
+
_layerControlHTML;
|
|
32
|
+
_layerItemSettingsHTML;
|
|
33
|
+
_propertiesGroupAnatomy;
|
|
34
|
+
disabled = false;
|
|
35
|
+
_fetchError = false;
|
|
36
|
+
// the layer registry is a semi-private Map stored on each map-link and map-layer element
|
|
37
|
+
// structured as follows: position -> {layer: layerInstance, count: number}
|
|
38
|
+
// where layer is either a MapTileLayer or a MapFeatureLayer,
|
|
39
|
+
// and count is the number of tiles or features in that layer
|
|
40
|
+
_layerRegistry = new Map();
|
|
41
|
+
// Watchers for attribute changes - these automatically don't fire during initial load
|
|
42
|
+
srcChanged(newValue, oldValue) {
|
|
43
|
+
if (oldValue !== newValue) {
|
|
44
|
+
this._onRemove();
|
|
45
|
+
if (this.el.isConnected) {
|
|
46
|
+
this._onAdd();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
checkedChanged(newValue) {
|
|
51
|
+
if (this._layer) {
|
|
52
|
+
// Get the parent map element
|
|
53
|
+
const mapEl = this.getMapEl();
|
|
54
|
+
if (mapEl && mapEl._map) {
|
|
55
|
+
const leafletMap = mapEl._map;
|
|
56
|
+
if (newValue) {
|
|
57
|
+
// If checked is true, add the layer to the map
|
|
58
|
+
leafletMap.addLayer(this._layer);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
// If checked is false, remove the layer from the map
|
|
62
|
+
leafletMap.removeLayer(this._layer);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Update the layer control checkbox to match the checked state
|
|
66
|
+
if (this._layerControlCheckbox) {
|
|
67
|
+
this._layerControlCheckbox.checked = newValue;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
opacityChanged(newValue, oldValue) {
|
|
72
|
+
// This watcher handles programmatic changes to the opacity property
|
|
73
|
+
if (oldValue !== newValue && this._layer) {
|
|
74
|
+
this._opacity = newValue;
|
|
75
|
+
this._layer.changeOpacity(newValue);
|
|
76
|
+
// reflect to map-layer opacity attribute when opacity property changes
|
|
77
|
+
// this.el.setAttribute('opacity', newValue.toString());
|
|
78
|
+
// Update opacity slider if it exists
|
|
79
|
+
if (this._opacitySlider) {
|
|
80
|
+
this._opacitySlider.value = newValue.toString();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
mediaChanged(newValue, oldValue) {
|
|
85
|
+
if (oldValue !== newValue) {
|
|
86
|
+
this._registerMediaQuery(newValue);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
hiddenChanged(newValue, oldValue) {
|
|
90
|
+
// Only process hidden changes after the layer is fully initialized
|
|
91
|
+
// During initial load, this will be handled in _attachedToMap()
|
|
92
|
+
if (oldValue !== newValue && this._layer && this._layerControl) {
|
|
93
|
+
this._applyHiddenState(newValue);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
_applyHiddenState(isHidden) {
|
|
97
|
+
if (!this._layer || !this._layerControl)
|
|
98
|
+
return;
|
|
99
|
+
if (isHidden) {
|
|
100
|
+
// Hidden was set to true - remove from layer control
|
|
101
|
+
this._layerControl.removeLayer(this._layer);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
// Hidden was set to false - add back to layer control and validate
|
|
105
|
+
this._layerControl.addOrUpdateOverlay(this._layer, this.label);
|
|
106
|
+
this._validateDisabled();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
loggedMessages;
|
|
110
|
+
_observer;
|
|
111
|
+
_mql;
|
|
112
|
+
_changeHandler;
|
|
113
|
+
_boundCreateLayerControlHTML;
|
|
114
|
+
// Layer control element references (synced from DOM element properties)
|
|
115
|
+
_layerControlCheckbox;
|
|
116
|
+
_layerControlLabel;
|
|
117
|
+
_opacityControl;
|
|
118
|
+
_opacitySlider;
|
|
119
|
+
// private _layerItemSettingsHTML?: HTMLElement;
|
|
120
|
+
// private _propertiesGroupAnatomy?: HTMLElement;
|
|
121
|
+
_styles;
|
|
122
|
+
get label() {
|
|
123
|
+
if (this._layer)
|
|
124
|
+
return this._layer.getName();
|
|
125
|
+
else
|
|
126
|
+
return this.el.hasAttribute('label') ? this.el.getAttribute('label') : '';
|
|
127
|
+
}
|
|
128
|
+
set label(val) {
|
|
129
|
+
if (val) {
|
|
130
|
+
this.el.setAttribute('label', val);
|
|
131
|
+
if (this._layer)
|
|
132
|
+
this._layer.setName(val);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
get extent() {
|
|
136
|
+
// calculate the bounds of all content, return it.
|
|
137
|
+
if (this._layer) {
|
|
138
|
+
this._layer._calculateBounds();
|
|
139
|
+
}
|
|
140
|
+
return this._layer
|
|
141
|
+
? Object.assign(Util._convertAndFormatPCRS(this._layer.bounds, window.M[this.getProjection()], this.getProjection()), { zoom: this._layer.zoomBounds })
|
|
142
|
+
: null;
|
|
143
|
+
}
|
|
144
|
+
_registerMediaQuery(mq) {
|
|
145
|
+
if (!this._changeHandler) {
|
|
146
|
+
this._changeHandler = () => {
|
|
147
|
+
this._onRemove();
|
|
148
|
+
if (this._mql.matches) {
|
|
149
|
+
this._onAdd();
|
|
150
|
+
}
|
|
151
|
+
// set the disabled 'read-only' attribute indirectly, via _validateDisabled
|
|
152
|
+
this._validateDisabled();
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
if (mq) {
|
|
156
|
+
// a new media query is being established
|
|
157
|
+
let map = this.getMapEl();
|
|
158
|
+
if (!map)
|
|
159
|
+
return;
|
|
160
|
+
// Remove listener from the old media query (if it exists)
|
|
161
|
+
if (this._mql) {
|
|
162
|
+
this._mql.removeEventListener('change', this._changeHandler);
|
|
163
|
+
}
|
|
164
|
+
this._mql = map.matchMedia(mq);
|
|
165
|
+
this._changeHandler();
|
|
166
|
+
this._mql.addEventListener('change', this._changeHandler);
|
|
167
|
+
}
|
|
168
|
+
else if (this._mql) {
|
|
169
|
+
// the media attribute removed or query set to ''
|
|
170
|
+
this._mql.removeEventListener('change', this._changeHandler);
|
|
171
|
+
delete this._mql;
|
|
172
|
+
// effectively, no / empty media attribute matches, do what changeHandler does
|
|
173
|
+
this._onRemove();
|
|
174
|
+
this._onAdd();
|
|
175
|
+
this._validateDisabled();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
getMapEl() {
|
|
179
|
+
return Util.getClosest(this.el, 'gcds-ext-map');
|
|
180
|
+
}
|
|
181
|
+
// Note: Stencil handles constructor automatically, but we can use componentWillLoad for initialization
|
|
182
|
+
componentWillLoad() {
|
|
183
|
+
// Mirror the original constructor logic
|
|
184
|
+
// by keeping track of console.log, we can avoid overwhelming the console
|
|
185
|
+
this.loggedMessages = new Set();
|
|
186
|
+
// Publish queryable() early so it's available even before connectedCallback
|
|
187
|
+
// This is needed for dynamically added layers (e.g., via inplace links)
|
|
188
|
+
Object.defineProperty(this.el, 'queryable', {
|
|
189
|
+
value: () => this.queryable(),
|
|
190
|
+
writable: true,
|
|
191
|
+
configurable: true
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
disconnectedCallback() {
|
|
195
|
+
// if the map-layer node is removed from the dom, the layer should be
|
|
196
|
+
// removed from the map and the layer control
|
|
197
|
+
if (this.el.hasAttribute('data-moving'))
|
|
198
|
+
return;
|
|
199
|
+
this._onRemove();
|
|
200
|
+
if (this._mql) {
|
|
201
|
+
if (this._changeHandler) {
|
|
202
|
+
this._mql.removeEventListener('change', this._changeHandler);
|
|
203
|
+
}
|
|
204
|
+
delete this._mql;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
_onRemove() {
|
|
208
|
+
if (this._observer) {
|
|
209
|
+
this._observer.disconnect();
|
|
210
|
+
}
|
|
211
|
+
let l = this._layer, lc = this._layerControl;
|
|
212
|
+
if (l) {
|
|
213
|
+
l.off();
|
|
214
|
+
}
|
|
215
|
+
// if this layer has never been connected, it will not have a _layer
|
|
216
|
+
if (l && l._map) {
|
|
217
|
+
l._map.removeLayer(l);
|
|
218
|
+
}
|
|
219
|
+
if (lc && !this.el.hasAttribute('hidden')) {
|
|
220
|
+
// lc.removeLayer depends on this._layerControlHTML, can't delete it until after
|
|
221
|
+
lc.removeLayer(l);
|
|
222
|
+
}
|
|
223
|
+
// remove properties of layer involved in whenReady() logic
|
|
224
|
+
delete this._layer;
|
|
225
|
+
delete this._layerControl;
|
|
226
|
+
delete this._layerControlHTML;
|
|
227
|
+
delete this._fetchError;
|
|
228
|
+
// Clean up DOM element properties exposed for MapML compatibility
|
|
229
|
+
delete this.el._layer;
|
|
230
|
+
delete this.el._layerControl;
|
|
231
|
+
delete this.el._layerControlHTML;
|
|
232
|
+
delete this.el._fetchError;
|
|
233
|
+
// Clean up layer control element references
|
|
234
|
+
this._layerControlCheckbox = undefined;
|
|
235
|
+
this._layerControlLabel = undefined;
|
|
236
|
+
this._opacityControl = undefined;
|
|
237
|
+
this._opacitySlider = undefined;
|
|
238
|
+
// this._layerItemSettingsHTML = undefined;
|
|
239
|
+
// this._propertiesGroupAnatomy = undefined;
|
|
240
|
+
this._styles = undefined;
|
|
241
|
+
this.el.shadowRoot.innerHTML = '';
|
|
242
|
+
if (this.src)
|
|
243
|
+
this.el.innerHTML = '';
|
|
244
|
+
this._layerRegistry.clear();
|
|
245
|
+
}
|
|
246
|
+
connectedCallback() {
|
|
247
|
+
if (this.el.hasAttribute('data-moving'))
|
|
248
|
+
return;
|
|
249
|
+
this._boundCreateLayerControlHTML = createLayerControlHTML.bind(this.el);
|
|
250
|
+
// Publish _validateDisabled on element for MapML compatibility
|
|
251
|
+
this.el._validateDisabled = this._validateDisabled.bind(this);
|
|
252
|
+
// Expose disabled property on DOM element
|
|
253
|
+
Object.defineProperty(this.el, 'disabled', {
|
|
254
|
+
get: () => this.disabled,
|
|
255
|
+
set: (val) => {
|
|
256
|
+
this.disabled = val;
|
|
257
|
+
},
|
|
258
|
+
configurable: true,
|
|
259
|
+
enumerable: true
|
|
260
|
+
});
|
|
261
|
+
// Expose _opacity property on DOM element (internal opacity state)
|
|
262
|
+
Object.defineProperty(this.el, '_opacity', {
|
|
263
|
+
get: () => this._opacity,
|
|
264
|
+
set: (val) => {
|
|
265
|
+
if (val !== this._opacity) {
|
|
266
|
+
this._opacity = val;
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
configurable: true,
|
|
270
|
+
enumerable: true
|
|
271
|
+
});
|
|
272
|
+
// Expose opacity getter/setter on DOM element using the component's opacityValue
|
|
273
|
+
Object.defineProperty(this.el, 'opacity', {
|
|
274
|
+
get: () => {
|
|
275
|
+
return this.opacityValue;
|
|
276
|
+
},
|
|
277
|
+
set: (val) => {
|
|
278
|
+
if (+val > 1 || +val < 0)
|
|
279
|
+
return;
|
|
280
|
+
this._opacity = val;
|
|
281
|
+
this._layer?.changeOpacity(val);
|
|
282
|
+
},
|
|
283
|
+
configurable: true,
|
|
284
|
+
enumerable: true
|
|
285
|
+
});
|
|
286
|
+
Object.defineProperty(this.el, 'whenElemsReady', {
|
|
287
|
+
value: () => this.whenElemsReady(),
|
|
288
|
+
writable: true,
|
|
289
|
+
configurable: true
|
|
290
|
+
});
|
|
291
|
+
Object.defineProperty(this.el, 'zoomTo', {
|
|
292
|
+
value: () => this.zoomTo(),
|
|
293
|
+
writable: true,
|
|
294
|
+
configurable: true
|
|
295
|
+
});
|
|
296
|
+
Object.defineProperty(this.el, 'mapml2geojson', {
|
|
297
|
+
value: (options = {}) => this.mapml2geojson(options),
|
|
298
|
+
writable: true,
|
|
299
|
+
configurable: true
|
|
300
|
+
});
|
|
301
|
+
Object.defineProperty(this.el, 'pasteFeature', {
|
|
302
|
+
value: (feature) => this.pasteFeature(feature),
|
|
303
|
+
writable: true,
|
|
304
|
+
configurable: true
|
|
305
|
+
});
|
|
306
|
+
Object.defineProperty(this.el, 'getAlternateStyles', {
|
|
307
|
+
value: (styleLinks) => this.getAlternateStyles(styleLinks),
|
|
308
|
+
writable: true,
|
|
309
|
+
configurable: true
|
|
310
|
+
});
|
|
311
|
+
Object.defineProperty(this.el, 'getOuterHTML', {
|
|
312
|
+
value: () => this.getOuterHTML(),
|
|
313
|
+
writable: true,
|
|
314
|
+
configurable: true
|
|
315
|
+
});
|
|
316
|
+
Object.defineProperty(this.el, 'getMapEl', {
|
|
317
|
+
value: () => this.getMapEl(),
|
|
318
|
+
writable: true,
|
|
319
|
+
configurable: true
|
|
320
|
+
});
|
|
321
|
+
Object.defineProperty(this.el, 'getProjection', {
|
|
322
|
+
value: () => this.getProjection(),
|
|
323
|
+
writable: true,
|
|
324
|
+
configurable: true
|
|
325
|
+
});
|
|
326
|
+
// Expose label property on DOM element for MapML compatibility
|
|
327
|
+
Object.defineProperty(this.el, 'label', {
|
|
328
|
+
get: () => this.label,
|
|
329
|
+
set: (val) => this.label = val,
|
|
330
|
+
configurable: true,
|
|
331
|
+
enumerable: true
|
|
332
|
+
});
|
|
333
|
+
// Expose hidden property on DOM element for MapML compatibility
|
|
334
|
+
// The @Watch('hidden') decorator handles the side effects
|
|
335
|
+
Object.defineProperty(this.el, 'hidden', {
|
|
336
|
+
get: () => this.el.hasAttribute('hidden'),
|
|
337
|
+
set: (val) => {
|
|
338
|
+
if (val) {
|
|
339
|
+
this.el.setAttribute('hidden', '');
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
this.el.removeAttribute('hidden');
|
|
343
|
+
}
|
|
344
|
+
},
|
|
345
|
+
configurable: true,
|
|
346
|
+
enumerable: true
|
|
347
|
+
});
|
|
348
|
+
// Expose extent property on DOM element for MapML compatibility
|
|
349
|
+
Object.defineProperty(this.el, 'extent', {
|
|
350
|
+
get: () => this.extent,
|
|
351
|
+
configurable: true,
|
|
352
|
+
enumerable: true
|
|
353
|
+
});
|
|
354
|
+
this.el._layerRegistry = this._layerRegistry;
|
|
355
|
+
const doConnected = this._onAdd.bind(this);
|
|
356
|
+
const doRemove = this._onRemove.bind(this);
|
|
357
|
+
const registerMediaQuery = this._registerMediaQuery.bind(this);
|
|
358
|
+
let mq = this.media;
|
|
359
|
+
this.getMapEl()
|
|
360
|
+
.whenReady()
|
|
361
|
+
.then(() => {
|
|
362
|
+
doRemove();
|
|
363
|
+
if (mq) {
|
|
364
|
+
registerMediaQuery(mq);
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
doConnected();
|
|
368
|
+
}
|
|
369
|
+
})
|
|
370
|
+
.catch((error) => {
|
|
371
|
+
throw new Error('Map never became ready: ' + error);
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
_onAdd() {
|
|
375
|
+
new Promise((resolve, reject) => {
|
|
376
|
+
this.el.addEventListener('changestyle', (e) => {
|
|
377
|
+
e.stopPropagation();
|
|
378
|
+
// if user changes the style in layer control
|
|
379
|
+
if (e.detail) {
|
|
380
|
+
this.src = e.detail.src;
|
|
381
|
+
}
|
|
382
|
+
}, { once: true });
|
|
383
|
+
let base = this.el.baseURI ? this.el.baseURI : document.baseURI;
|
|
384
|
+
const headers = new Headers();
|
|
385
|
+
headers.append('Accept', 'text/mapml');
|
|
386
|
+
if (this.src) {
|
|
387
|
+
fetch(this.src, { headers: headers })
|
|
388
|
+
.then((response) => {
|
|
389
|
+
if (!response.ok) {
|
|
390
|
+
throw new Error(`HTTP error! Status: ${response.status}`);
|
|
391
|
+
}
|
|
392
|
+
// Save the response URL to use as base for resolving relative URLs
|
|
393
|
+
const responseUrl = response.url;
|
|
394
|
+
return response.text().then(text => ({ text, url: responseUrl }));
|
|
395
|
+
})
|
|
396
|
+
.then(({ text, url: sourceUrl }) => {
|
|
397
|
+
let content = new DOMParser().parseFromString(text, 'text/xml');
|
|
398
|
+
if (content.querySelector('parsererror') ||
|
|
399
|
+
!content.querySelector('mapml-')) {
|
|
400
|
+
// cut short whenReady with the _fetchError property
|
|
401
|
+
this._fetchError = true;
|
|
402
|
+
// Expose _fetchError on DOM element for MapML compatibility
|
|
403
|
+
this.el._fetchError = this._fetchError;
|
|
404
|
+
console.log('Error fetching layer content:\n\n' + text + '\n');
|
|
405
|
+
throw new Error('Parser error');
|
|
406
|
+
}
|
|
407
|
+
// Attach the source URL to the content for later use
|
|
408
|
+
content._sourceUrl = sourceUrl;
|
|
409
|
+
return content;
|
|
410
|
+
})
|
|
411
|
+
.then((content) => {
|
|
412
|
+
this._copyRemoteContentToShadowRoot(content.querySelector('mapml-'), content._sourceUrl);
|
|
413
|
+
this._copyRemoteContentToShadowRoot(content.querySelector('mapml-'));
|
|
414
|
+
let elements = this.el.shadowRoot.querySelectorAll('*');
|
|
415
|
+
let elementsReady = [];
|
|
416
|
+
for (let i = 0; i < elements.length; i++) {
|
|
417
|
+
if (elements[i].whenReady) {
|
|
418
|
+
elementsReady.push(elements[i].whenReady().catch(error => {
|
|
419
|
+
console.warn(`Element ${elements[i].tagName} failed to become ready:`, error);
|
|
420
|
+
return null; // Convert rejection to resolution so layer can still proceed
|
|
421
|
+
}));
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
return Promise.allSettled(elementsReady);
|
|
425
|
+
})
|
|
426
|
+
.then(() => {
|
|
427
|
+
// may throw:
|
|
428
|
+
this._selectAlternateOrChangeProjection();
|
|
429
|
+
})
|
|
430
|
+
.then(() => {
|
|
431
|
+
this._layer = MapLayerModule.mapLayer(new URL(this.src, base).href, this.el, {
|
|
432
|
+
projection: this.getProjection(),
|
|
433
|
+
opacity: this.opacityValue
|
|
434
|
+
});
|
|
435
|
+
// Expose _layer on DOM element for MapML compatibility
|
|
436
|
+
this.el._layer = this._layer;
|
|
437
|
+
this._createLayerControlHTML();
|
|
438
|
+
this._setLocalizedDefaultLabel();
|
|
439
|
+
this._attachedToMap();
|
|
440
|
+
// Process any elements that were created before layer was ready
|
|
441
|
+
this._runMutationObserver(this.el.shadowRoot.children);
|
|
442
|
+
this._bindMutationObserver();
|
|
443
|
+
this._validateDisabled();
|
|
444
|
+
// re-use 'loadedmetadata' event from HTMLMediaElement inteface, applied
|
|
445
|
+
// to MapML extent as metadata
|
|
446
|
+
// Should always be fired at the end of initialization process
|
|
447
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/loadedmetadata_event
|
|
448
|
+
// https://maps4html.org/web-map-doc/docs/api/layer-api#events
|
|
449
|
+
this.el.dispatchEvent(new CustomEvent('loadedmetadata', { detail: { target: this.el } }));
|
|
450
|
+
resolve(undefined);
|
|
451
|
+
})
|
|
452
|
+
.catch((error) => {
|
|
453
|
+
reject(error);
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
let elements = this.el.querySelectorAll('*');
|
|
458
|
+
let elementsReady = [];
|
|
459
|
+
for (let i = 0; i < elements.length; i++) {
|
|
460
|
+
if (elements[i].whenReady)
|
|
461
|
+
elementsReady.push(elements[i].whenReady());
|
|
462
|
+
}
|
|
463
|
+
Promise.allSettled(elementsReady)
|
|
464
|
+
.then(() => {
|
|
465
|
+
// may throw:
|
|
466
|
+
this._selectAlternateOrChangeProjection();
|
|
467
|
+
})
|
|
468
|
+
.then(() => {
|
|
469
|
+
this._layer = MapLayerModule.mapLayer(null, this.el, {
|
|
470
|
+
projection: this.getProjection(),
|
|
471
|
+
opacity: this.opacityValue
|
|
472
|
+
});
|
|
473
|
+
// Expose _layer on DOM element for MapML compatibility
|
|
474
|
+
this.el._layer = this._layer;
|
|
475
|
+
this._createLayerControlHTML();
|
|
476
|
+
this._setLocalizedDefaultLabel();
|
|
477
|
+
this._attachedToMap();
|
|
478
|
+
// Process any elements that were created before layer was ready
|
|
479
|
+
this._runMutationObserver(this.el.children);
|
|
480
|
+
this._bindMutationObserver();
|
|
481
|
+
this._validateDisabled();
|
|
482
|
+
// re-use 'loadedmetadata' event from HTMLMediaElement inteface, applied
|
|
483
|
+
// to MapML extent as metadata
|
|
484
|
+
// Should always be fired at the end of initialization process
|
|
485
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/loadedmetadata_event
|
|
486
|
+
// https://maps4html.org/web-map-doc/docs/api/layer-api#events
|
|
487
|
+
this.el.dispatchEvent(new CustomEvent('loadedmetadata', { detail: { target: this.el } }));
|
|
488
|
+
resolve(undefined);
|
|
489
|
+
})
|
|
490
|
+
.catch((error) => {
|
|
491
|
+
reject(error);
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
}).catch((e) => {
|
|
495
|
+
if (e.message === 'changeprojection') {
|
|
496
|
+
if (e.cause.href) {
|
|
497
|
+
console.log('Changing layer src to: ' + e.cause.href);
|
|
498
|
+
this.src = e.cause.href;
|
|
499
|
+
}
|
|
500
|
+
else if (e.cause.mapprojection) {
|
|
501
|
+
console.log('Changing map projection to match layer: ' + e.cause.mapprojection);
|
|
502
|
+
const mapEl = this.getMapEl();
|
|
503
|
+
if (mapEl) {
|
|
504
|
+
mapEl.projection = e.cause.mapprojection;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
else if (e.message === 'Failed to fetch') {
|
|
509
|
+
// cut short whenReady with the _fetchError property
|
|
510
|
+
this._fetchError = true;
|
|
511
|
+
// Expose _fetchError on DOM element for MapML compatibility
|
|
512
|
+
this.el._fetchError = this._fetchError;
|
|
513
|
+
}
|
|
514
|
+
else {
|
|
515
|
+
console.log(e);
|
|
516
|
+
this.el.dispatchEvent(new CustomEvent('error', { detail: { target: this.el } }));
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
_setLocalizedDefaultLabel() {
|
|
521
|
+
if (!this._layer?._titleIsReadOnly && !this._layer?._title) {
|
|
522
|
+
const mapEl = this.getMapEl();
|
|
523
|
+
if (mapEl && mapEl.locale?.dfLayer) {
|
|
524
|
+
this.label = mapEl.locale.dfLayer;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
_selectAlternateOrChangeProjection() {
|
|
529
|
+
const mapml = this.src ? this.el.shadowRoot : this.el;
|
|
530
|
+
const mapEl = this.getMapEl();
|
|
531
|
+
if (!mapml || !mapEl)
|
|
532
|
+
return;
|
|
533
|
+
const selectedAlternate = this.getProjection() !== mapEl.projection &&
|
|
534
|
+
mapml.querySelector('map-link[rel=alternate][projection=' +
|
|
535
|
+
mapEl.projection +
|
|
536
|
+
'][href]');
|
|
537
|
+
if (selectedAlternate) {
|
|
538
|
+
// Use the same base resolution logic as map-link.getBase()
|
|
539
|
+
// Check for map-base element first, then fall back to layer src
|
|
540
|
+
let baseUrl;
|
|
541
|
+
const mapBase = mapml.querySelector('map-base[href]');
|
|
542
|
+
if (mapBase) {
|
|
543
|
+
baseUrl = mapBase.getAttribute('href');
|
|
544
|
+
}
|
|
545
|
+
else if (this.src) {
|
|
546
|
+
// Fallback to resolving layer's src against document base
|
|
547
|
+
baseUrl = new URL(this.src, this.el.baseURI || document.baseURI).href;
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
baseUrl = this.el.baseURI || document.baseURI;
|
|
551
|
+
}
|
|
552
|
+
const url = new URL(selectedAlternate.getAttribute('href'), baseUrl).href;
|
|
553
|
+
throw new Error('changeprojection', {
|
|
554
|
+
cause: { href: url }
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
const contentProjection = this.getProjection();
|
|
558
|
+
if (contentProjection !== mapEl.projection &&
|
|
559
|
+
mapEl.layers?.length === 1) {
|
|
560
|
+
throw new Error('changeprojection', {
|
|
561
|
+
cause: { mapprojection: contentProjection }
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
_copyRemoteContentToShadowRoot(mapml, sourceUrl) {
|
|
566
|
+
const shadowRoot = this.el.shadowRoot;
|
|
567
|
+
if (!shadowRoot || !mapml)
|
|
568
|
+
return;
|
|
569
|
+
const frag = document.createDocumentFragment();
|
|
570
|
+
const elements = mapml.querySelectorAll('map-head > *, map-body > *');
|
|
571
|
+
// Find or create a map-base element to store the source document's base URL
|
|
572
|
+
let mapBase = Array.from(elements).find(el => el.nodeName === 'MAP-BASE');
|
|
573
|
+
if (!mapBase && sourceUrl) {
|
|
574
|
+
// Create a synthetic map-base element if none exists
|
|
575
|
+
mapBase = document.createElement('map-base');
|
|
576
|
+
mapBase.setAttribute('href', sourceUrl);
|
|
577
|
+
frag.appendChild(mapBase);
|
|
578
|
+
}
|
|
579
|
+
else if (mapBase && sourceUrl) {
|
|
580
|
+
// Resolve existing map-base href against the source URL
|
|
581
|
+
const resolvedHref = new URL(mapBase.getAttribute('href') || '', sourceUrl).href;
|
|
582
|
+
mapBase.setAttribute('href', resolvedHref);
|
|
583
|
+
}
|
|
584
|
+
for (let i = 0; i < elements.length; i++) {
|
|
585
|
+
frag.appendChild(elements[i]);
|
|
586
|
+
}
|
|
587
|
+
shadowRoot.appendChild(frag);
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* For "local" content, getProjection will use content of "this"
|
|
591
|
+
* For "remote" content, you need to pass the shadowRoot to search through
|
|
592
|
+
*/
|
|
593
|
+
getProjection() {
|
|
594
|
+
let mapml = this.src ? this.el.shadowRoot : this.el;
|
|
595
|
+
let projection = this.getMapEl().projection;
|
|
596
|
+
if (mapml.querySelector('map-meta[name=projection][content]')) {
|
|
597
|
+
projection =
|
|
598
|
+
Util._metaContentToObject(mapml
|
|
599
|
+
.querySelector('map-meta[name=projection]')
|
|
600
|
+
.getAttribute('content')).content || projection;
|
|
601
|
+
}
|
|
602
|
+
else if (mapml.querySelector('map-extent[units]')) {
|
|
603
|
+
const getProjectionFrom = (extents) => {
|
|
604
|
+
let extentProj = extents[0].attributes.units.value;
|
|
605
|
+
let isMatch = true;
|
|
606
|
+
for (let i = 0; i < extents.length; i++) {
|
|
607
|
+
if (extentProj !== extents[i].attributes.units.value) {
|
|
608
|
+
isMatch = false;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
return isMatch ? extentProj : null;
|
|
612
|
+
};
|
|
613
|
+
projection =
|
|
614
|
+
getProjectionFrom(Array.from(mapml.querySelectorAll('map-extent[units]'))) || projection;
|
|
615
|
+
}
|
|
616
|
+
else {
|
|
617
|
+
const titleElement = this.el.querySelector('map-title');
|
|
618
|
+
const layerLabel = this.label || (titleElement ? titleElement.textContent : 'Unnamed');
|
|
619
|
+
const message = `A projection was not assigned to the '${layerLabel}' Layer. \nPlease specify a projection for that layer using a map-meta element. \nSee more here - https://maps4html.org/web-map-doc/docs/elements/meta/`;
|
|
620
|
+
if (!this.loggedMessages.has(message)) {
|
|
621
|
+
console.log(message);
|
|
622
|
+
this.loggedMessages.add(message);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
return projection;
|
|
626
|
+
}
|
|
627
|
+
_attachedToMap() {
|
|
628
|
+
// Refactored from layer.js _attachedToMap()
|
|
629
|
+
// Set i to the position of this layer element in the set of layers
|
|
630
|
+
const mapEl = this.getMapEl();
|
|
631
|
+
if (!mapEl || !this._layer)
|
|
632
|
+
return;
|
|
633
|
+
let i = 0;
|
|
634
|
+
let position = 1;
|
|
635
|
+
const nodes = mapEl.children;
|
|
636
|
+
for (i = 0; i < nodes.length; i++) {
|
|
637
|
+
if (nodes[i].nodeName === 'MAP-LAYER' ||
|
|
638
|
+
nodes[i].nodeName === 'LAYER-') {
|
|
639
|
+
if (nodes[i] === this.el) {
|
|
640
|
+
position = i + 1;
|
|
641
|
+
}
|
|
642
|
+
else if (nodes[i]._layer) {
|
|
643
|
+
nodes[i]._layer.setZIndex(i + 1);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
const proj = mapEl.projection ? mapEl.projection : 'OSMTILE';
|
|
648
|
+
setOptions(this._layer, {
|
|
649
|
+
zIndex: position,
|
|
650
|
+
mapprojection: proj,
|
|
651
|
+
opacity: window.getComputedStyle(this.el).opacity
|
|
652
|
+
});
|
|
653
|
+
if (this.checked) {
|
|
654
|
+
this._layer.addTo(mapEl._map);
|
|
655
|
+
// Toggle the this.disabled attribute depending on whether the layer
|
|
656
|
+
// is: same prj as map, within view/zoom of map
|
|
657
|
+
}
|
|
658
|
+
mapEl._map.on('moveend layeradd', this._validateDisabled, this);
|
|
659
|
+
this._layer.on('add remove', this._validateDisabled, this);
|
|
660
|
+
if (mapEl._layerControl) {
|
|
661
|
+
this._layerControl = mapEl._layerControl;
|
|
662
|
+
// Expose _layerControl on DOM element for MapML compatibility
|
|
663
|
+
this.el._layerControl = this._layerControl;
|
|
664
|
+
}
|
|
665
|
+
// If controls option is enabled, insert the layer into the overlays array
|
|
666
|
+
if (mapEl._layerControl && !this.hidden) {
|
|
667
|
+
this._layerControl.addOrUpdateOverlay(this._layer, this.label);
|
|
668
|
+
}
|
|
669
|
+
// The mapml document associated to this layer can in theory contain many
|
|
670
|
+
// link[@rel=legend] elements with different @type or other attributes;
|
|
671
|
+
// currently only support a single link, don't care about type, lang etc.
|
|
672
|
+
// TODO: add support for full LayerLegend object, and > one link.
|
|
673
|
+
if (this._layer._legendUrl) {
|
|
674
|
+
this.el.legendLinks = [
|
|
675
|
+
{
|
|
676
|
+
type: 'application/octet-stream',
|
|
677
|
+
href: this._layer._legendUrl,
|
|
678
|
+
rel: 'legend',
|
|
679
|
+
lang: null,
|
|
680
|
+
hreflang: null,
|
|
681
|
+
sizes: null
|
|
682
|
+
}
|
|
683
|
+
];
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
_runMutationObserver(elementsGroup) {
|
|
687
|
+
const _addStylesheetLink = (mapLink) => {
|
|
688
|
+
this.whenReady().then(() => {
|
|
689
|
+
this._layer.renderStyles(mapLink);
|
|
690
|
+
});
|
|
691
|
+
};
|
|
692
|
+
const _addStyleElement = (mapStyle) => {
|
|
693
|
+
this.whenReady().then(() => {
|
|
694
|
+
this._layer.renderStyles(mapStyle);
|
|
695
|
+
});
|
|
696
|
+
};
|
|
697
|
+
const _addExtentElement = (mapExtent) => {
|
|
698
|
+
this.whenReady().then(() => {
|
|
699
|
+
// Wait for the extent itself to be ready before recalculating bounds
|
|
700
|
+
if (typeof mapExtent.whenReady === 'function') {
|
|
701
|
+
mapExtent.whenReady().then(() => {
|
|
702
|
+
// Force complete recalculation by deleting cached bounds
|
|
703
|
+
delete this._layer.bounds;
|
|
704
|
+
this._layer._calculateBounds();
|
|
705
|
+
this._validateDisabled();
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
else {
|
|
709
|
+
delete this._layer.bounds;
|
|
710
|
+
this._layer._calculateBounds();
|
|
711
|
+
this._validateDisabled();
|
|
712
|
+
}
|
|
713
|
+
});
|
|
714
|
+
};
|
|
715
|
+
const root = this.src ? this.el.shadowRoot : this.el;
|
|
716
|
+
const pseudo = root instanceof ShadowRoot ? ':host' : ':scope';
|
|
717
|
+
const _addMetaElement = (_mapMeta) => {
|
|
718
|
+
this.whenReady().then(() => {
|
|
719
|
+
this._layer._calculateBounds();
|
|
720
|
+
this._validateDisabled();
|
|
721
|
+
});
|
|
722
|
+
};
|
|
723
|
+
for (let i = 0; i < elementsGroup.length; ++i) {
|
|
724
|
+
const element = elementsGroup[i];
|
|
725
|
+
switch (element.nodeName) {
|
|
726
|
+
case 'MAP-LINK':
|
|
727
|
+
if (element.link && !element.link.isConnected)
|
|
728
|
+
_addStylesheetLink(element);
|
|
729
|
+
break;
|
|
730
|
+
case 'MAP-STYLE':
|
|
731
|
+
if (element.styleElement && !element.styleElement.isConnected) {
|
|
732
|
+
_addStyleElement(element);
|
|
733
|
+
}
|
|
734
|
+
break;
|
|
735
|
+
case 'MAP-EXTENT':
|
|
736
|
+
_addExtentElement(element);
|
|
737
|
+
break;
|
|
738
|
+
case 'MAP-META':
|
|
739
|
+
const name = element.hasAttribute('name') &&
|
|
740
|
+
(element.getAttribute('name').toLowerCase() === 'zoom' ||
|
|
741
|
+
element.getAttribute('name').toLowerCase() === 'extent');
|
|
742
|
+
if (name &&
|
|
743
|
+
element ===
|
|
744
|
+
root.querySelector(`${pseudo} > [name=${element.getAttribute('name')}]`) &&
|
|
745
|
+
element.hasAttribute('content')) {
|
|
746
|
+
_addMetaElement(element);
|
|
747
|
+
}
|
|
748
|
+
break;
|
|
749
|
+
default:
|
|
750
|
+
break;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
/**
|
|
755
|
+
* Set up a function to watch additions of child elements of map-layer or
|
|
756
|
+
* map-layer.shadowRoot and invoke desired side effects via _runMutationObserver
|
|
757
|
+
*/
|
|
758
|
+
_bindMutationObserver() {
|
|
759
|
+
this._observer = new MutationObserver((mutationList) => {
|
|
760
|
+
for (let mutation of mutationList) {
|
|
761
|
+
if (mutation.type === 'childList') {
|
|
762
|
+
this._runMutationObserver(mutation.addedNodes);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
});
|
|
766
|
+
this._observer.observe(this.src ? this.el.shadowRoot : this.el, {
|
|
767
|
+
childList: true
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
_validateDisabled() {
|
|
771
|
+
const countTileLayers = () => {
|
|
772
|
+
let totalCount = 0;
|
|
773
|
+
let disabledCount = 0;
|
|
774
|
+
this._layer.eachLayer((layer) => {
|
|
775
|
+
if (layer instanceof MapTileLayer) {
|
|
776
|
+
totalCount++;
|
|
777
|
+
if (!layer.isVisible())
|
|
778
|
+
disabledCount++;
|
|
779
|
+
}
|
|
780
|
+
});
|
|
781
|
+
return { totalCount, disabledCount };
|
|
782
|
+
};
|
|
783
|
+
const countFeatureLayers = () => {
|
|
784
|
+
let totalCount = 0;
|
|
785
|
+
let disabledCount = 0;
|
|
786
|
+
this._layer.eachLayer((layer) => {
|
|
787
|
+
if (layer instanceof MapFeatureLayer) {
|
|
788
|
+
totalCount++;
|
|
789
|
+
if (!layer.isVisible())
|
|
790
|
+
disabledCount++;
|
|
791
|
+
}
|
|
792
|
+
});
|
|
793
|
+
return { totalCount, disabledCount };
|
|
794
|
+
};
|
|
795
|
+
// setTimeout is necessary to make the validateDisabled happen later than the moveend operations etc.,
|
|
796
|
+
// to ensure that the validated result is correct
|
|
797
|
+
setTimeout(() => {
|
|
798
|
+
let layer = this._layer, map = layer?._map;
|
|
799
|
+
// if there's a media query in play, check it early
|
|
800
|
+
if (this._mql && !this._mql.matches) {
|
|
801
|
+
this.el.setAttribute('disabled', '');
|
|
802
|
+
this.disabled = true;
|
|
803
|
+
return;
|
|
804
|
+
}
|
|
805
|
+
if (map) {
|
|
806
|
+
// prerequisite: no inline and remote mapml elements exists at the same time
|
|
807
|
+
const mapExtents = this.src
|
|
808
|
+
? this.el.shadowRoot?.querySelectorAll('map-extent')
|
|
809
|
+
: this.el.querySelectorAll('map-extent');
|
|
810
|
+
let extentLinksReady = [];
|
|
811
|
+
if (mapExtents) {
|
|
812
|
+
for (let i = 0; i < mapExtents.length; i++) {
|
|
813
|
+
if (mapExtents[i].whenLinksReady) {
|
|
814
|
+
extentLinksReady.push(mapExtents[i].whenLinksReady());
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
Promise.allSettled(extentLinksReady)
|
|
819
|
+
.then(() => {
|
|
820
|
+
let disabledExtentCount = 0, totalExtentCount = 0, layerTypes = [
|
|
821
|
+
'_staticTileLayer',
|
|
822
|
+
'_mapmlvectors',
|
|
823
|
+
'_extentLayer'
|
|
824
|
+
];
|
|
825
|
+
for (let j = 0; j < layerTypes.length; j++) {
|
|
826
|
+
let type = layerTypes[j];
|
|
827
|
+
if (this.checked) {
|
|
828
|
+
if (type === '_extentLayer' && mapExtents && mapExtents.length > 0) {
|
|
829
|
+
for (let i = 0; i < mapExtents.length; i++) {
|
|
830
|
+
totalExtentCount++;
|
|
831
|
+
if (mapExtents[i]._validateDisabled && mapExtents[i]._validateDisabled())
|
|
832
|
+
disabledExtentCount++;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
else if (type === '_mapmlvectors') {
|
|
836
|
+
// inline / static features
|
|
837
|
+
const featureLayerCounts = countFeatureLayers();
|
|
838
|
+
totalExtentCount += featureLayerCounts.totalCount;
|
|
839
|
+
disabledExtentCount += featureLayerCounts.disabledCount;
|
|
840
|
+
}
|
|
841
|
+
else {
|
|
842
|
+
// inline tiles
|
|
843
|
+
const tileLayerCounts = countTileLayers();
|
|
844
|
+
totalExtentCount += tileLayerCounts.totalCount;
|
|
845
|
+
disabledExtentCount += tileLayerCounts.disabledCount;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
// if all extents are not visible / disabled, set layer to disabled
|
|
850
|
+
if (disabledExtentCount === totalExtentCount &&
|
|
851
|
+
disabledExtentCount !== 0) {
|
|
852
|
+
this.el.setAttribute('disabled', '');
|
|
853
|
+
this.disabled = true;
|
|
854
|
+
}
|
|
855
|
+
else {
|
|
856
|
+
this.el.removeAttribute('disabled');
|
|
857
|
+
this.disabled = false;
|
|
858
|
+
}
|
|
859
|
+
this.toggleLayerControlDisabled();
|
|
860
|
+
})
|
|
861
|
+
.catch((e) => {
|
|
862
|
+
console.log(e);
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
}, 0);
|
|
866
|
+
}
|
|
867
|
+
// disable/italicize layer control elements based on the map-layer.disabled property
|
|
868
|
+
toggleLayerControlDisabled() {
|
|
869
|
+
let input = this._layerControlCheckbox, label = this._layerControlLabel, opacityControl = this._opacityControl, opacitySlider = this._opacitySlider, styleControl = this._styles;
|
|
870
|
+
if (this.disabled) {
|
|
871
|
+
if (input)
|
|
872
|
+
input.disabled = true;
|
|
873
|
+
if (opacitySlider)
|
|
874
|
+
opacitySlider.disabled = true;
|
|
875
|
+
if (label)
|
|
876
|
+
label.style.fontStyle = 'italic';
|
|
877
|
+
if (opacityControl)
|
|
878
|
+
opacityControl.style.fontStyle = 'italic';
|
|
879
|
+
if (styleControl) {
|
|
880
|
+
styleControl.style.fontStyle = 'italic';
|
|
881
|
+
styleControl.querySelectorAll('input').forEach((i) => {
|
|
882
|
+
i.disabled = true;
|
|
883
|
+
});
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
else {
|
|
887
|
+
if (input)
|
|
888
|
+
input.disabled = false;
|
|
889
|
+
if (opacitySlider)
|
|
890
|
+
opacitySlider.disabled = false;
|
|
891
|
+
if (label)
|
|
892
|
+
label.style.fontStyle = 'normal';
|
|
893
|
+
if (opacityControl)
|
|
894
|
+
opacityControl.style.fontStyle = 'normal';
|
|
895
|
+
if (styleControl) {
|
|
896
|
+
styleControl.style.fontStyle = 'normal';
|
|
897
|
+
styleControl.querySelectorAll('input').forEach((i) => {
|
|
898
|
+
i.disabled = false;
|
|
899
|
+
});
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
queryable() {
|
|
904
|
+
let content = this.src ? this.el.shadowRoot : this.el;
|
|
905
|
+
return !!(content?.querySelector('map-extent[checked] > map-link[rel=query]:not([disabled])') &&
|
|
906
|
+
this.checked &&
|
|
907
|
+
this._layer &&
|
|
908
|
+
!this.el.hasAttribute('hidden'));
|
|
909
|
+
}
|
|
910
|
+
getAlternateStyles(styleLinks) {
|
|
911
|
+
if (styleLinks.length > 1) {
|
|
912
|
+
const stylesControl = document.createElement('details');
|
|
913
|
+
const stylesControlSummary = document.createElement('summary');
|
|
914
|
+
const mapEl = this.getMapEl();
|
|
915
|
+
stylesControlSummary.innerText = mapEl?.locale?.lmStyle || 'Style';
|
|
916
|
+
stylesControl.appendChild(stylesControlSummary);
|
|
917
|
+
for (let j = 0; j < styleLinks.length; j++) {
|
|
918
|
+
stylesControl.appendChild(styleLinks[j].getLayerControlOption());
|
|
919
|
+
DomUtil.addClass(stylesControl, 'mapml-layer-item-style mapml-control-layers');
|
|
920
|
+
}
|
|
921
|
+
return stylesControl;
|
|
922
|
+
}
|
|
923
|
+
return null;
|
|
924
|
+
}
|
|
925
|
+
getOuterHTML() {
|
|
926
|
+
let tempElement = this.el.cloneNode(true);
|
|
927
|
+
if (this.el.hasAttribute('src')) {
|
|
928
|
+
let newSrc = this._layer.getHref();
|
|
929
|
+
tempElement.setAttribute('src', newSrc);
|
|
930
|
+
}
|
|
931
|
+
if (this.el.querySelector('map-link')) {
|
|
932
|
+
let mapLinks = tempElement.querySelectorAll('map-link');
|
|
933
|
+
mapLinks.forEach((mapLink) => {
|
|
934
|
+
if (mapLink.hasAttribute('href')) {
|
|
935
|
+
mapLink.setAttribute('href', decodeURI(new URL(mapLink.getAttribute('href'), this.el.baseURI ? this.el.baseURI : document.baseURI).href));
|
|
936
|
+
}
|
|
937
|
+
else if (mapLink.hasAttribute('tref')) {
|
|
938
|
+
mapLink.setAttribute('tref', decodeURI(new URL(mapLink.getAttribute('tref'), this.el.baseURI ? this.el.baseURI : document.baseURI).href));
|
|
939
|
+
}
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
let outerLayer = tempElement.outerHTML;
|
|
943
|
+
tempElement.remove();
|
|
944
|
+
return outerLayer;
|
|
945
|
+
}
|
|
946
|
+
zoomTo() {
|
|
947
|
+
this.whenReady().then(() => {
|
|
948
|
+
let map = this.getMapEl()?._map, extent = this.extent, tL = extent.topLeft.pcrs, bR = extent.bottomRight.pcrs, layerBounds = bounds(point(tL.horizontal, tL.vertical), point(bR.horizontal, bR.vertical)), center = map.options.crs.unproject(layerBounds.getCenter(true));
|
|
949
|
+
let maxZoom = extent.zoom.maxZoom, minZoom = extent.zoom.minZoom;
|
|
950
|
+
map.setView(center, Util.getMaxZoom(layerBounds, map, minZoom, maxZoom), {
|
|
951
|
+
animate: false
|
|
952
|
+
});
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
pasteFeature(feature) {
|
|
956
|
+
switch (typeof feature) {
|
|
957
|
+
case 'string':
|
|
958
|
+
feature.trim();
|
|
959
|
+
if (feature.slice(0, 12) === '<map-feature' &&
|
|
960
|
+
feature.slice(-14) === '</map-feature>') {
|
|
961
|
+
this.el.insertAdjacentHTML('beforeend', feature);
|
|
962
|
+
}
|
|
963
|
+
break;
|
|
964
|
+
case 'object':
|
|
965
|
+
if (feature.nodeName?.toUpperCase() === 'MAP-FEATURE') {
|
|
966
|
+
this.el.appendChild(feature);
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
_createLayerControlHTML() {
|
|
971
|
+
// Use the bound function that was set up in connectedCallback
|
|
972
|
+
// The createLayerControlHTML function was bound to this.el in connectedCallback
|
|
973
|
+
if (this._boundCreateLayerControlHTML) {
|
|
974
|
+
// Call the async function but don't await it (matches original layer.js behavior)
|
|
975
|
+
this._boundCreateLayerControlHTML().then((result) => {
|
|
976
|
+
this._layerControlHTML = result;
|
|
977
|
+
// Expose _layerControlHTML on DOM element for MapML compatibility
|
|
978
|
+
this.el._layerControlHTML = this._layerControlHTML;
|
|
979
|
+
// Sync all layer control properties created by createLayerControlForLayer
|
|
980
|
+
// These properties are set on the DOM element by the bound function and need to be
|
|
981
|
+
// available on both the element and the component for future refactoring
|
|
982
|
+
this._layerControlCheckbox = this.el._layerControlCheckbox;
|
|
983
|
+
this._layerControlLabel = this.el._layerControlLabel;
|
|
984
|
+
this._opacityControl = this.el._opacityControl;
|
|
985
|
+
this._opacitySlider = this.el._opacitySlider;
|
|
986
|
+
this._layerItemSettingsHTML = this.el._layerItemSettingsHTML;
|
|
987
|
+
this._propertiesGroupAnatomy = this.el._propertiesGroupAnatomy;
|
|
988
|
+
this._styles = this.el._styles;
|
|
989
|
+
// Ensure opacity slider is synced with current opacity value
|
|
990
|
+
if (this._opacitySlider && this._opacity !== undefined) {
|
|
991
|
+
this._opacitySlider.value = this._opacity.toString();
|
|
992
|
+
}
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
async whenReady() {
|
|
997
|
+
return new Promise((resolve, reject) => {
|
|
998
|
+
let interval, failureTimer;
|
|
999
|
+
if (this.el._layer &&
|
|
1000
|
+
this._layerControlHTML &&
|
|
1001
|
+
(!this.src || this.el.shadowRoot?.childNodes.length)) {
|
|
1002
|
+
resolve();
|
|
1003
|
+
}
|
|
1004
|
+
else {
|
|
1005
|
+
const layerElement = this.el;
|
|
1006
|
+
interval = setInterval(testForLayer, 200, layerElement);
|
|
1007
|
+
failureTimer = setTimeout(layerNotDefined, 5000);
|
|
1008
|
+
}
|
|
1009
|
+
function testForLayer(layerElement) {
|
|
1010
|
+
if (layerElement._layer &&
|
|
1011
|
+
layerElement._layerControlHTML &&
|
|
1012
|
+
(!layerElement.src || layerElement.shadowRoot?.childNodes.length)) {
|
|
1013
|
+
clearInterval(interval);
|
|
1014
|
+
clearTimeout(failureTimer);
|
|
1015
|
+
resolve();
|
|
1016
|
+
}
|
|
1017
|
+
else if (layerElement._fetchError) {
|
|
1018
|
+
clearInterval(interval);
|
|
1019
|
+
clearTimeout(failureTimer);
|
|
1020
|
+
reject('Error fetching layer content');
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
function layerNotDefined() {
|
|
1024
|
+
clearInterval(interval);
|
|
1025
|
+
clearTimeout(failureTimer);
|
|
1026
|
+
reject('Timeout reached waiting for layer to be ready');
|
|
1027
|
+
}
|
|
1028
|
+
});
|
|
1029
|
+
}
|
|
1030
|
+
/**
|
|
1031
|
+
* Wait for all map-extent and map-feature elements to be ready.
|
|
1032
|
+
* Returns a promise that resolves when all are settled.
|
|
1033
|
+
*/
|
|
1034
|
+
async whenElemsReady() {
|
|
1035
|
+
let elemsReady = [];
|
|
1036
|
+
// Use shadowRoot if src is set, otherwise use this.el
|
|
1037
|
+
let target = this.src ? this.el.shadowRoot : this.el;
|
|
1038
|
+
if (!target)
|
|
1039
|
+
return [];
|
|
1040
|
+
const extents = Array.from(target.querySelectorAll('map-extent'));
|
|
1041
|
+
const features = Array.from(target.querySelectorAll('map-feature'));
|
|
1042
|
+
for (let elem of [...extents, ...features]) {
|
|
1043
|
+
if (typeof elem.whenReady === 'function') {
|
|
1044
|
+
elemsReady.push(elem.whenReady());
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
return Promise.allSettled(elemsReady);
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1050
|
+
* Convert this MapML layer to GeoJSON FeatureCollection
|
|
1051
|
+
* @param options - Conversion options:
|
|
1052
|
+
* - propertyFunction: Function to map <map-properties> to GeoJSON properties
|
|
1053
|
+
* - transform: Whether to transform coordinates to GCRS (EPSG:4326), defaults to true
|
|
1054
|
+
* @returns GeoJSON FeatureCollection object
|
|
1055
|
+
*/
|
|
1056
|
+
mapml2geojson(options = {}) {
|
|
1057
|
+
return Util.mapml2geojson(this.el, options);
|
|
1058
|
+
}
|
|
1059
|
+
render() {
|
|
1060
|
+
return null;
|
|
1061
|
+
}
|
|
1062
|
+
static get is() { return "map-layer"; }
|
|
1063
|
+
static get encapsulation() { return "shadow"; }
|
|
1064
|
+
static get properties() {
|
|
1065
|
+
return {
|
|
1066
|
+
"src": {
|
|
1067
|
+
"type": "string",
|
|
1068
|
+
"mutable": true,
|
|
1069
|
+
"complexType": {
|
|
1070
|
+
"original": "string",
|
|
1071
|
+
"resolved": "string",
|
|
1072
|
+
"references": {}
|
|
1073
|
+
},
|
|
1074
|
+
"required": false,
|
|
1075
|
+
"optional": true,
|
|
1076
|
+
"docs": {
|
|
1077
|
+
"tags": [],
|
|
1078
|
+
"text": ""
|
|
1079
|
+
},
|
|
1080
|
+
"getter": false,
|
|
1081
|
+
"setter": false,
|
|
1082
|
+
"reflect": true,
|
|
1083
|
+
"attribute": "src"
|
|
1084
|
+
},
|
|
1085
|
+
"checked": {
|
|
1086
|
+
"type": "boolean",
|
|
1087
|
+
"mutable": true,
|
|
1088
|
+
"complexType": {
|
|
1089
|
+
"original": "boolean",
|
|
1090
|
+
"resolved": "boolean",
|
|
1091
|
+
"references": {}
|
|
1092
|
+
},
|
|
1093
|
+
"required": false,
|
|
1094
|
+
"optional": true,
|
|
1095
|
+
"docs": {
|
|
1096
|
+
"tags": [],
|
|
1097
|
+
"text": ""
|
|
1098
|
+
},
|
|
1099
|
+
"getter": false,
|
|
1100
|
+
"setter": false,
|
|
1101
|
+
"reflect": true,
|
|
1102
|
+
"attribute": "checked"
|
|
1103
|
+
},
|
|
1104
|
+
"hidden": {
|
|
1105
|
+
"type": "boolean",
|
|
1106
|
+
"mutable": true,
|
|
1107
|
+
"complexType": {
|
|
1108
|
+
"original": "boolean",
|
|
1109
|
+
"resolved": "boolean",
|
|
1110
|
+
"references": {}
|
|
1111
|
+
},
|
|
1112
|
+
"required": false,
|
|
1113
|
+
"optional": false,
|
|
1114
|
+
"docs": {
|
|
1115
|
+
"tags": [],
|
|
1116
|
+
"text": ""
|
|
1117
|
+
},
|
|
1118
|
+
"getter": false,
|
|
1119
|
+
"setter": false,
|
|
1120
|
+
"reflect": true,
|
|
1121
|
+
"attribute": "hidden",
|
|
1122
|
+
"defaultValue": "false"
|
|
1123
|
+
},
|
|
1124
|
+
"opacity": {
|
|
1125
|
+
"type": "number",
|
|
1126
|
+
"mutable": true,
|
|
1127
|
+
"complexType": {
|
|
1128
|
+
"original": "number",
|
|
1129
|
+
"resolved": "number",
|
|
1130
|
+
"references": {}
|
|
1131
|
+
},
|
|
1132
|
+
"required": false,
|
|
1133
|
+
"optional": true,
|
|
1134
|
+
"docs": {
|
|
1135
|
+
"tags": [],
|
|
1136
|
+
"text": ""
|
|
1137
|
+
},
|
|
1138
|
+
"getter": false,
|
|
1139
|
+
"setter": false,
|
|
1140
|
+
"reflect": false,
|
|
1141
|
+
"attribute": "opacity",
|
|
1142
|
+
"defaultValue": "1"
|
|
1143
|
+
},
|
|
1144
|
+
"_opacity": {
|
|
1145
|
+
"type": "number",
|
|
1146
|
+
"mutable": true,
|
|
1147
|
+
"complexType": {
|
|
1148
|
+
"original": "number",
|
|
1149
|
+
"resolved": "number",
|
|
1150
|
+
"references": {}
|
|
1151
|
+
},
|
|
1152
|
+
"required": false,
|
|
1153
|
+
"optional": true,
|
|
1154
|
+
"docs": {
|
|
1155
|
+
"tags": [],
|
|
1156
|
+
"text": ""
|
|
1157
|
+
},
|
|
1158
|
+
"getter": false,
|
|
1159
|
+
"setter": false,
|
|
1160
|
+
"reflect": false,
|
|
1161
|
+
"attribute": "_opacity"
|
|
1162
|
+
},
|
|
1163
|
+
"media": {
|
|
1164
|
+
"type": "string",
|
|
1165
|
+
"mutable": true,
|
|
1166
|
+
"complexType": {
|
|
1167
|
+
"original": "string",
|
|
1168
|
+
"resolved": "string",
|
|
1169
|
+
"references": {}
|
|
1170
|
+
},
|
|
1171
|
+
"required": false,
|
|
1172
|
+
"optional": true,
|
|
1173
|
+
"docs": {
|
|
1174
|
+
"tags": [],
|
|
1175
|
+
"text": ""
|
|
1176
|
+
},
|
|
1177
|
+
"getter": false,
|
|
1178
|
+
"setter": false,
|
|
1179
|
+
"reflect": true,
|
|
1180
|
+
"attribute": "media"
|
|
1181
|
+
}
|
|
1182
|
+
};
|
|
1183
|
+
}
|
|
1184
|
+
static get methods() {
|
|
1185
|
+
return {
|
|
1186
|
+
"whenReady": {
|
|
1187
|
+
"complexType": {
|
|
1188
|
+
"signature": "() => Promise<void>",
|
|
1189
|
+
"parameters": [],
|
|
1190
|
+
"references": {
|
|
1191
|
+
"Promise": {
|
|
1192
|
+
"location": "global",
|
|
1193
|
+
"id": "global::Promise"
|
|
1194
|
+
}
|
|
1195
|
+
},
|
|
1196
|
+
"return": "Promise<void>"
|
|
1197
|
+
},
|
|
1198
|
+
"docs": {
|
|
1199
|
+
"text": "",
|
|
1200
|
+
"tags": []
|
|
1201
|
+
}
|
|
1202
|
+
},
|
|
1203
|
+
"whenElemsReady": {
|
|
1204
|
+
"complexType": {
|
|
1205
|
+
"signature": "() => Promise<PromiseSettledResult<unknown>[]>",
|
|
1206
|
+
"parameters": [],
|
|
1207
|
+
"references": {
|
|
1208
|
+
"Promise": {
|
|
1209
|
+
"location": "global",
|
|
1210
|
+
"id": "global::Promise"
|
|
1211
|
+
},
|
|
1212
|
+
"PromiseSettledResult": {
|
|
1213
|
+
"location": "global",
|
|
1214
|
+
"id": "global::PromiseSettledResult"
|
|
1215
|
+
}
|
|
1216
|
+
},
|
|
1217
|
+
"return": "Promise<PromiseSettledResult<unknown>[]>"
|
|
1218
|
+
},
|
|
1219
|
+
"docs": {
|
|
1220
|
+
"text": "Wait for all map-extent and map-feature elements to be ready.\nReturns a promise that resolves when all are settled.",
|
|
1221
|
+
"tags": []
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
};
|
|
1225
|
+
}
|
|
1226
|
+
static get elementRef() { return "el"; }
|
|
1227
|
+
static get watchers() {
|
|
1228
|
+
return [{
|
|
1229
|
+
"propName": "src",
|
|
1230
|
+
"methodName": "srcChanged"
|
|
1231
|
+
}, {
|
|
1232
|
+
"propName": "checked",
|
|
1233
|
+
"methodName": "checkedChanged"
|
|
1234
|
+
}, {
|
|
1235
|
+
"propName": "_opacity",
|
|
1236
|
+
"methodName": "opacityChanged"
|
|
1237
|
+
}, {
|
|
1238
|
+
"propName": "media",
|
|
1239
|
+
"methodName": "mediaChanged"
|
|
1240
|
+
}, {
|
|
1241
|
+
"propName": "hidden",
|
|
1242
|
+
"methodName": "hiddenChanged"
|
|
1243
|
+
}];
|
|
1244
|
+
}
|
|
1245
|
+
}
|