@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,1601 @@
|
|
|
1
|
+
/* global M */
|
|
2
|
+
|
|
3
|
+
import { bounds, latLngBounds, point, latLng } from 'leaflet';
|
|
4
|
+
|
|
5
|
+
import proj4 from 'proj4';
|
|
6
|
+
|
|
7
|
+
export const Util = {
|
|
8
|
+
// _convertAndFormatPCRS returns the converted CRS and formatted pcrsBounds in gcrs, pcrs, tcrs, and tilematrix. Used for setting extent for the map and layer (map.extent, layer.extent).
|
|
9
|
+
// _convertAndFormatPCRS: Bounds, _map, projection -> {...}
|
|
10
|
+
_convertAndFormatPCRS: function (pcrsBounds, crs, projection) {
|
|
11
|
+
if (!pcrsBounds || !crs) return {};
|
|
12
|
+
|
|
13
|
+
let tcrsTopLeft = [],
|
|
14
|
+
tcrsBottomRight = [],
|
|
15
|
+
tileMatrixTopLeft = [],
|
|
16
|
+
tileMatrixBottomRight = [],
|
|
17
|
+
tileSize = crs.options.crs.tile.bounds.max.y;
|
|
18
|
+
|
|
19
|
+
for (let i = 0; i < crs.options.resolutions.length; i++) {
|
|
20
|
+
let scale = crs.scale(i),
|
|
21
|
+
minConverted = crs.transformation.transform(pcrsBounds.min, scale),
|
|
22
|
+
maxConverted = crs.transformation.transform(pcrsBounds.max, scale);
|
|
23
|
+
|
|
24
|
+
tcrsTopLeft.push({
|
|
25
|
+
horizontal: minConverted.x,
|
|
26
|
+
vertical: maxConverted.y
|
|
27
|
+
});
|
|
28
|
+
tcrsBottomRight.push({
|
|
29
|
+
horizontal: maxConverted.x,
|
|
30
|
+
vertical: minConverted.y
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
//converts the tcrs values from earlier to tilematrix
|
|
34
|
+
tileMatrixTopLeft.push({
|
|
35
|
+
horizontal: tcrsTopLeft[i].horizontal / tileSize,
|
|
36
|
+
vertical: tcrsTopLeft[i].vertical / tileSize
|
|
37
|
+
});
|
|
38
|
+
tileMatrixBottomRight.push({
|
|
39
|
+
horizontal: tcrsBottomRight[i].horizontal / tileSize,
|
|
40
|
+
vertical: tcrsBottomRight[i].vertical / tileSize
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//converts the gcrs, I believe it can take any number values from -inf to +inf
|
|
45
|
+
let unprojectedMin = crs.unproject(pcrsBounds.min),
|
|
46
|
+
unprojectedMax = crs.unproject(pcrsBounds.max);
|
|
47
|
+
|
|
48
|
+
let gcrs = {
|
|
49
|
+
topLeft: {
|
|
50
|
+
horizontal: unprojectedMin.lng,
|
|
51
|
+
vertical: unprojectedMax.lat
|
|
52
|
+
},
|
|
53
|
+
bottomRight: {
|
|
54
|
+
horizontal: unprojectedMax.lng,
|
|
55
|
+
vertical: unprojectedMin.lat
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
//formats known pcrs bounds to correct format
|
|
60
|
+
let pcrs = {
|
|
61
|
+
topLeft: {
|
|
62
|
+
horizontal: pcrsBounds.min.x,
|
|
63
|
+
vertical: pcrsBounds.max.y
|
|
64
|
+
},
|
|
65
|
+
bottomRight: {
|
|
66
|
+
horizontal: pcrsBounds.max.x,
|
|
67
|
+
vertical: pcrsBounds.min.y
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
//formats all extent data
|
|
72
|
+
let extent = {
|
|
73
|
+
topLeft: {
|
|
74
|
+
tcrs: tcrsTopLeft,
|
|
75
|
+
tilematrix: tileMatrixTopLeft,
|
|
76
|
+
gcrs: gcrs.topLeft,
|
|
77
|
+
pcrs: pcrs.topLeft
|
|
78
|
+
},
|
|
79
|
+
bottomRight: {
|
|
80
|
+
tcrs: tcrsBottomRight,
|
|
81
|
+
tilematrix: tileMatrixBottomRight,
|
|
82
|
+
gcrs: gcrs.bottomRight,
|
|
83
|
+
pcrs: pcrs.bottomRight
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
if (projection) {
|
|
87
|
+
extent.projection = projection;
|
|
88
|
+
}
|
|
89
|
+
return extent;
|
|
90
|
+
},
|
|
91
|
+
// extentToBounds: returns bounds in gcrs, pcrs. Used for setting bounds for the map (map.totalLayerBounds).
|
|
92
|
+
// extentToBounds: {...}, crs -> Bounds / LatlngBounds
|
|
93
|
+
extentToBounds(extent, crs) {
|
|
94
|
+
switch (crs.toUpperCase()) {
|
|
95
|
+
case 'PCRS':
|
|
96
|
+
return bounds(
|
|
97
|
+
point(extent.topLeft.pcrs.horizontal, extent.topLeft.pcrs.vertical),
|
|
98
|
+
point(
|
|
99
|
+
extent.bottomRight.pcrs.horizontal,
|
|
100
|
+
extent.bottomRight.pcrs.vertical
|
|
101
|
+
)
|
|
102
|
+
);
|
|
103
|
+
case 'GCRS':
|
|
104
|
+
return latLngBounds(
|
|
105
|
+
latLng(extent.topLeft.gcrs.vertical, extent.topLeft.gcrs.horizontal),
|
|
106
|
+
latLng(
|
|
107
|
+
extent.bottomRight.gcrs.vertical,
|
|
108
|
+
extent.bottomRight.gcrs.horizontal
|
|
109
|
+
)
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
// axisToCS returns the CRS when given the axis:
|
|
115
|
+
// https://maps4html.org/web-map-doc/docs/elements/input/#axis
|
|
116
|
+
// axisToCS: (Axis String) -> (CRS String)
|
|
117
|
+
axisToCS: function (axis) {
|
|
118
|
+
try {
|
|
119
|
+
switch (axis.toLowerCase()) {
|
|
120
|
+
case 'row':
|
|
121
|
+
case 'column':
|
|
122
|
+
return 'TILEMATRIX';
|
|
123
|
+
case 'i':
|
|
124
|
+
case 'j':
|
|
125
|
+
return ['MAP', 'TILE'];
|
|
126
|
+
case 'x':
|
|
127
|
+
case 'y':
|
|
128
|
+
return 'TCRS';
|
|
129
|
+
case 'latitude':
|
|
130
|
+
case 'longitude':
|
|
131
|
+
return 'GCRS';
|
|
132
|
+
case 'northing':
|
|
133
|
+
case 'easting':
|
|
134
|
+
return 'PCRS';
|
|
135
|
+
default:
|
|
136
|
+
return M.FALLBACK_CS;
|
|
137
|
+
}
|
|
138
|
+
} catch (e) {
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
// csToAxes takes a given cs and retuns the axes, first horizontal then vertical
|
|
144
|
+
// https://maps4html.org/web-map-doc/docs/elements/input/#axis
|
|
145
|
+
// csToAxes: (CRS String) -> [(horizontal axis String), (Vertical axis String)]
|
|
146
|
+
csToAxes: function (cs) {
|
|
147
|
+
try {
|
|
148
|
+
switch (cs.toLowerCase()) {
|
|
149
|
+
case 'tilematrix':
|
|
150
|
+
return ['column', 'row'];
|
|
151
|
+
case 'map':
|
|
152
|
+
case 'tile':
|
|
153
|
+
return ['i', 'j'];
|
|
154
|
+
case 'tcrs':
|
|
155
|
+
return ['x', 'y'];
|
|
156
|
+
case 'gcrs':
|
|
157
|
+
return ['longitude', 'latitude'];
|
|
158
|
+
case 'pcrs':
|
|
159
|
+
return ['easting', 'northing'];
|
|
160
|
+
}
|
|
161
|
+
} catch (e) {
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
// axisToXY takes horizontal axis and returns 'x', or takes vertical axis and returns 'y'
|
|
167
|
+
// https://maps4html.org/web-map-doc/docs/elements/input/#axis
|
|
168
|
+
// axisToXY: (Axis String) -> 'x' or 'y'
|
|
169
|
+
axisToXY: function (axis) {
|
|
170
|
+
try {
|
|
171
|
+
switch (axis.toLowerCase()) {
|
|
172
|
+
case 'i':
|
|
173
|
+
case 'column':
|
|
174
|
+
case 'longitude':
|
|
175
|
+
case 'x':
|
|
176
|
+
case 'easting':
|
|
177
|
+
return 'x';
|
|
178
|
+
case 'row':
|
|
179
|
+
case 'j':
|
|
180
|
+
case 'latitude':
|
|
181
|
+
case 'y':
|
|
182
|
+
case 'northing':
|
|
183
|
+
return 'y';
|
|
184
|
+
|
|
185
|
+
default:
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
} catch (e) {
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
|
|
193
|
+
// convertPCRSBounds converts pcrsBounds to the given cs Bounds.
|
|
194
|
+
// convertPCRSBounds: Bounds, Int, CRS, Str('PCRS'|'TCRS'|'TILEMATRIX'|'GCRS') -> Bounds
|
|
195
|
+
convertPCRSBounds: function (pcrsBounds, zoom, projection, cs) {
|
|
196
|
+
if (
|
|
197
|
+
!pcrsBounds ||
|
|
198
|
+
(!zoom && zoom !== 0) ||
|
|
199
|
+
!Number.isFinite(+zoom) ||
|
|
200
|
+
!projection ||
|
|
201
|
+
!cs
|
|
202
|
+
)
|
|
203
|
+
return undefined;
|
|
204
|
+
projection = typeof projection === 'string' ? M[projection] : projection;
|
|
205
|
+
switch (cs.toUpperCase()) {
|
|
206
|
+
case 'PCRS':
|
|
207
|
+
return pcrsBounds;
|
|
208
|
+
case 'TCRS':
|
|
209
|
+
case 'TILEMATRIX':
|
|
210
|
+
let minPixel = projection.transformation.transform(
|
|
211
|
+
pcrsBounds.min,
|
|
212
|
+
projection.scale(+zoom)
|
|
213
|
+
),
|
|
214
|
+
maxPixel = projection.transformation.transform(
|
|
215
|
+
pcrsBounds.max,
|
|
216
|
+
projection.scale(+zoom)
|
|
217
|
+
);
|
|
218
|
+
if (cs.toUpperCase() === 'TCRS') return bounds(minPixel, maxPixel);
|
|
219
|
+
let tileSize = projection.options.crs.tile.bounds.max.x;
|
|
220
|
+
return bounds(
|
|
221
|
+
point(minPixel.x / tileSize, minPixel.y / tileSize),
|
|
222
|
+
point(maxPixel.x / tileSize, maxPixel.y / tileSize)
|
|
223
|
+
);
|
|
224
|
+
case 'GCRS':
|
|
225
|
+
let minGCRS = projection.unproject(pcrsBounds.min),
|
|
226
|
+
maxGCRS = projection.unproject(pcrsBounds.max);
|
|
227
|
+
return bounds(
|
|
228
|
+
point(minGCRS.lng, minGCRS.lat),
|
|
229
|
+
point(maxGCRS.lng, maxGCRS.lat)
|
|
230
|
+
);
|
|
231
|
+
default:
|
|
232
|
+
return undefined;
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
|
|
236
|
+
// pointToPCRSPoint takes a point, with a projection and cs and converts it to a pcrs point/latLng
|
|
237
|
+
//pointToPCRSPoint: Point, Int, CRS, Str('PCRS'|'TCRS'|'TILEMATRIX'|'GCRS') -> point|latLng
|
|
238
|
+
pointToPCRSPoint: function (pt, zoom, projection, cs) {
|
|
239
|
+
if (
|
|
240
|
+
!pt ||
|
|
241
|
+
(zoom !== undefined && !Number.isFinite(+zoom)) ||
|
|
242
|
+
(zoom === undefined &&
|
|
243
|
+
(cs === 'TILEMATRIX' || cs === 'TCRS' || cs === 'TILE')) ||
|
|
244
|
+
!cs ||
|
|
245
|
+
!projection
|
|
246
|
+
)
|
|
247
|
+
return undefined;
|
|
248
|
+
projection = typeof projection === 'string' ? M[projection] : projection;
|
|
249
|
+
let tileSize = projection.options.crs.tile.bounds.max.x;
|
|
250
|
+
switch (cs.toUpperCase()) {
|
|
251
|
+
case 'TILEMATRIX':
|
|
252
|
+
return Util.pixelToPCRSPoint(
|
|
253
|
+
point(pt.x * tileSize, pt.y * tileSize),
|
|
254
|
+
zoom,
|
|
255
|
+
projection
|
|
256
|
+
);
|
|
257
|
+
case 'PCRS':
|
|
258
|
+
return pt;
|
|
259
|
+
case 'TCRS' || 'TILE':
|
|
260
|
+
return Util.pixelToPCRSPoint(pt, zoom, projection);
|
|
261
|
+
case 'GCRS':
|
|
262
|
+
return projection.project(latLng(pt.y, pt.x));
|
|
263
|
+
default:
|
|
264
|
+
return undefined;
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
|
|
268
|
+
// pixelToPCRSPoint takes a pixel point, the zoom and projection and returns a point in pcrs
|
|
269
|
+
// pixelToPCRSPoint: Point, Int, CRS|Str -> point
|
|
270
|
+
pixelToPCRSPoint: function (point, zoom, projection) {
|
|
271
|
+
if (
|
|
272
|
+
!point ||
|
|
273
|
+
(!zoom && zoom !== 0) ||
|
|
274
|
+
!Number.isFinite(+zoom) ||
|
|
275
|
+
!projection
|
|
276
|
+
)
|
|
277
|
+
return undefined;
|
|
278
|
+
projection = typeof projection === 'string' ? M[projection] : projection;
|
|
279
|
+
return projection.transformation.untransform(point, projection.scale(zoom));
|
|
280
|
+
},
|
|
281
|
+
|
|
282
|
+
// boundsToPCRSBounds converts bounds with projection and cs to PCRS bounds
|
|
283
|
+
// boundsToPCRSBounds: bounds, Int, CRS|Str, Str('PCRS'|'TCRS'|'TILEMATRIX'|'GCRS') -> bounds
|
|
284
|
+
boundsToPCRSBounds: function (bnds, zoom, projection, cs) {
|
|
285
|
+
if (
|
|
286
|
+
!bnds ||
|
|
287
|
+
!bnds.max ||
|
|
288
|
+
!bnds.min ||
|
|
289
|
+
(zoom !== undefined && !Number.isFinite(+zoom)) ||
|
|
290
|
+
(zoom === undefined &&
|
|
291
|
+
(cs === 'TILEMATRIX' || cs === 'TCRS' || cs === 'TILE')) ||
|
|
292
|
+
!projection ||
|
|
293
|
+
!cs
|
|
294
|
+
)
|
|
295
|
+
return undefined;
|
|
296
|
+
projection = typeof projection === 'string' ? M[projection] : projection;
|
|
297
|
+
return bounds(
|
|
298
|
+
Util.pointToPCRSPoint(bnds.min, zoom, projection, cs),
|
|
299
|
+
Util.pointToPCRSPoint(bnds.max, zoom, projection, cs)
|
|
300
|
+
);
|
|
301
|
+
},
|
|
302
|
+
|
|
303
|
+
//bounds have fixed point positions, where min is always topleft, max is always bottom right, and the values are always sorted by leaflet
|
|
304
|
+
//important to consider when working with pcrs where the origin is not topleft but rather bottomleft, could lead to confusion
|
|
305
|
+
pixelToPCRSBounds: function (bnds, zoom, projection) {
|
|
306
|
+
if (
|
|
307
|
+
!bnds ||
|
|
308
|
+
!bnds.max ||
|
|
309
|
+
!bnds.min ||
|
|
310
|
+
(!zoom && zoom !== 0) ||
|
|
311
|
+
!Number.isFinite(+zoom) ||
|
|
312
|
+
!projection
|
|
313
|
+
)
|
|
314
|
+
return undefined;
|
|
315
|
+
projection = typeof projection === 'string' ? M[projection] : projection;
|
|
316
|
+
return bounds(
|
|
317
|
+
Util.pixelToPCRSPoint(bnds.min, zoom, projection),
|
|
318
|
+
Util.pixelToPCRSPoint(bnds.max, zoom, projection)
|
|
319
|
+
);
|
|
320
|
+
},
|
|
321
|
+
|
|
322
|
+
//meta content is the content attribute of meta
|
|
323
|
+
// input "max=5,min=4" => [[max,5][min,5]]
|
|
324
|
+
_metaContentToObject: function (input) {
|
|
325
|
+
if (!input || input instanceof Object) return {};
|
|
326
|
+
let content = input.split(/\s+/).join('');
|
|
327
|
+
let contentArray = {};
|
|
328
|
+
let stringSplit = content.split(',');
|
|
329
|
+
|
|
330
|
+
for (let i = 0; i < stringSplit.length; i++) {
|
|
331
|
+
let prop = stringSplit[i].split('=');
|
|
332
|
+
if (prop.length === 2) contentArray[prop[0]] = prop[1];
|
|
333
|
+
}
|
|
334
|
+
if (contentArray !== '' && stringSplit[0].split('=').length === 1)
|
|
335
|
+
contentArray.content = stringSplit[0];
|
|
336
|
+
return contentArray;
|
|
337
|
+
},
|
|
338
|
+
|
|
339
|
+
// _coordsToArray returns an array of arrays of coordinate pairs
|
|
340
|
+
// _coordsToArray: ("1,2,3,4") -> [[1,2],[3,4]]
|
|
341
|
+
_coordsToArray: function (containerPoints) {
|
|
342
|
+
for (
|
|
343
|
+
var i = 1, pairs = [], coords = containerPoints.split(',');
|
|
344
|
+
i < coords.length;
|
|
345
|
+
i += 2
|
|
346
|
+
) {
|
|
347
|
+
pairs.push([parseInt(coords[i - 1]), parseInt(coords[i])]);
|
|
348
|
+
}
|
|
349
|
+
return pairs;
|
|
350
|
+
},
|
|
351
|
+
|
|
352
|
+
// _splitCoordinate splits string coordinates to an array as floating point numbers
|
|
353
|
+
_splitCoordinate: function (element, index, array) {
|
|
354
|
+
var a = [];
|
|
355
|
+
element.split(/\s+/gim).forEach(Util._parseNumber, a);
|
|
356
|
+
this.push(a);
|
|
357
|
+
},
|
|
358
|
+
|
|
359
|
+
// _parseNumber parses a string as a floating point number, helper function for _splitCoordinate
|
|
360
|
+
_parseNumber: function (element, index, array) {
|
|
361
|
+
this.push(parseFloat(element));
|
|
362
|
+
},
|
|
363
|
+
|
|
364
|
+
// _handleLink handles map-a links, when clicked on a map-a link
|
|
365
|
+
_handleLink: function (link, leafletLayer) {
|
|
366
|
+
let zoomTo,
|
|
367
|
+
justPan = false,
|
|
368
|
+
layer,
|
|
369
|
+
map = leafletLayer._map,
|
|
370
|
+
opacity;
|
|
371
|
+
if (link.type === 'text/html' && link.target !== '_blank') {
|
|
372
|
+
// all other target values other than blank behave as _top
|
|
373
|
+
link.target = '_top';
|
|
374
|
+
} else if (link.type !== 'text/html' && link.url.includes('#')) {
|
|
375
|
+
let hash = link.url.split('#'),
|
|
376
|
+
loc = hash[1].split(',');
|
|
377
|
+
zoomTo = { z: loc[0] || 0, lng: loc[1] || 0, lat: loc[2] || 0 };
|
|
378
|
+
justPan = !hash[0]; // if the first half of the array is an empty string then the link is just for panning
|
|
379
|
+
if (['/', '.', '#'].includes(link.url[0])) link.target = '_self';
|
|
380
|
+
}
|
|
381
|
+
if (!justPan) {
|
|
382
|
+
layer = document.createElement('map-layer');
|
|
383
|
+
layer.setAttribute('src', link.url);
|
|
384
|
+
layer.setAttribute('checked', '');
|
|
385
|
+
switch (link.target) {
|
|
386
|
+
case '_blank':
|
|
387
|
+
if (link.type === 'text/html') {
|
|
388
|
+
window.open(link.url);
|
|
389
|
+
} else {
|
|
390
|
+
postTraversalSetup();
|
|
391
|
+
map.options.mapEl.appendChild(layer);
|
|
392
|
+
}
|
|
393
|
+
break;
|
|
394
|
+
case '_parent':
|
|
395
|
+
postTraversalSetup();
|
|
396
|
+
for (let l of map.options.mapEl.querySelectorAll('map-layer,layer-'))
|
|
397
|
+
if (l._layer !== leafletLayer) map.options.mapEl.removeChild(l);
|
|
398
|
+
map.options.mapEl.appendChild(layer);
|
|
399
|
+
leafletLayer._layerEl.remove();
|
|
400
|
+
break;
|
|
401
|
+
case '_top':
|
|
402
|
+
window.location.href = link.url;
|
|
403
|
+
break;
|
|
404
|
+
default:
|
|
405
|
+
postTraversalSetup();
|
|
406
|
+
opacity = leafletLayer._layerEl.opacity;
|
|
407
|
+
leafletLayer._layerEl.insertAdjacentElement('beforebegin', layer);
|
|
408
|
+
map.options.mapEl.removeChild(leafletLayer._layerEl);
|
|
409
|
+
}
|
|
410
|
+
} else if (zoomTo && !link.inPlace && justPan) {
|
|
411
|
+
leafletLayer._map.options.mapEl.zoomTo(
|
|
412
|
+
+zoomTo.lat,
|
|
413
|
+
+zoomTo.lng,
|
|
414
|
+
+zoomTo.z
|
|
415
|
+
);
|
|
416
|
+
if (opacity) layer.opacity = opacity;
|
|
417
|
+
map.getContainer().focus();
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
function postTraversalSetup() {
|
|
421
|
+
// when the projection is changed as part of the link traversal process,
|
|
422
|
+
// it's necessary to set the map viewer's lat, lon and zoom NOW, so that
|
|
423
|
+
// the promises that are created when the viewer's projection is changed
|
|
424
|
+
// can use the viewer's lat, lon and zoom properties that were in effect
|
|
425
|
+
// before the projection change i.e. in the closure for that code
|
|
426
|
+
// see mapml-viewer / map is=web-map projection attributeChangedCallback
|
|
427
|
+
// specifically required for use cases like changing projection after
|
|
428
|
+
// link traversal, e.g. BC link here https://maps4html.org/experiments/linking/features/
|
|
429
|
+
if (!link.inPlace && zoomTo) updateMapZoomTo(zoomTo);
|
|
430
|
+
|
|
431
|
+
// Wait for projection change to complete before calling layer.zoomTo()
|
|
432
|
+
// This ensures zoom constraints are set properly in projectionChanged (gcds-ext-map.tsx)
|
|
433
|
+
// NOTE: We cannot determine in advance whether projection will change because:
|
|
434
|
+
// 1. Would need to fetch/parse the MapML document first
|
|
435
|
+
// 2. Would need to check if result leaves single layer (triggers projection change)
|
|
436
|
+
// 3. This adds complexity and delays that offset the timeout benefit
|
|
437
|
+
// So we always wait with 5000ms fallback. Tests must account for this delay.
|
|
438
|
+
// See: gcds-ext-map.tsx projectionChanged() and test files for related code.
|
|
439
|
+
const projectionChangePromise = new Promise(resolve => {
|
|
440
|
+
const timeout = setTimeout(resolve, 5000); // Fallback if no projection change
|
|
441
|
+
map.options.mapEl.addEventListener('map-projectionchange', () => {
|
|
442
|
+
clearTimeout(timeout);
|
|
443
|
+
resolve();
|
|
444
|
+
}, { once: true });
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
// the layer is newly created, so have to wait until it's fully init'd
|
|
448
|
+
// before setting properties.
|
|
449
|
+
Promise.all([layer.whenReady(), projectionChangePromise]).then(() => {
|
|
450
|
+
// if the map projection isnt' changed by link traversal, it's necessary
|
|
451
|
+
// to perform pan/zoom operations after the layer is ready
|
|
452
|
+
if (!link.inPlace && zoomTo)
|
|
453
|
+
layer.parentElement.zoomTo(+zoomTo.lat, +zoomTo.lng, +zoomTo.z);
|
|
454
|
+
else if (!link.inPlace) layer.zoomTo();
|
|
455
|
+
// not sure if this is necessary
|
|
456
|
+
if (opacity) layer.opacity = opacity;
|
|
457
|
+
// this is necessary to display the FeatureIndexOverlay, I believe
|
|
458
|
+
map.getContainer().focus();
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
function updateMapZoomTo(zoomTo) {
|
|
463
|
+
// can't use mapEl.zoomTo(...) here, it's too slow!
|
|
464
|
+
map.options.mapEl.lat = +zoomTo.lat;
|
|
465
|
+
map.options.mapEl.lon = +zoomTo.lng;
|
|
466
|
+
map.options.mapEl.zoom = +zoomTo.z;
|
|
467
|
+
}
|
|
468
|
+
},
|
|
469
|
+
getBoundsFromMeta: function (mapml) {
|
|
470
|
+
if (!mapml) return null;
|
|
471
|
+
let cs,
|
|
472
|
+
pseudo = mapml instanceof ShadowRoot ? ':host' : ':scope',
|
|
473
|
+
projection =
|
|
474
|
+
(mapml.querySelector(pseudo + ' > map-meta[name=projection]') &&
|
|
475
|
+
Util._metaContentToObject(
|
|
476
|
+
mapml
|
|
477
|
+
.querySelector(pseudo + ' > map-meta[name=projection]')
|
|
478
|
+
.getAttribute('content')
|
|
479
|
+
).content.toUpperCase()) ||
|
|
480
|
+
M.FALLBACK_PROJECTION;
|
|
481
|
+
try {
|
|
482
|
+
let meta =
|
|
483
|
+
mapml.querySelector(pseudo + ' > map-meta[name=extent]') &&
|
|
484
|
+
Util._metaContentToObject(
|
|
485
|
+
mapml
|
|
486
|
+
.querySelector(pseudo + ' > map-meta[name=extent]')
|
|
487
|
+
.getAttribute('content')
|
|
488
|
+
);
|
|
489
|
+
|
|
490
|
+
let zoom = meta.zoom;
|
|
491
|
+
|
|
492
|
+
let metaKeys = Object.keys(meta);
|
|
493
|
+
for (let i = 0; i < metaKeys.length; i++) {
|
|
494
|
+
if (!metaKeys[i].includes('zoom')) {
|
|
495
|
+
cs = Util.axisToCS(metaKeys[i].split('-')[2]);
|
|
496
|
+
break;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
// this could happen if the content didn't match the grammar for map-meta[name=extent]
|
|
500
|
+
if (cs === undefined) throw new Error('cs undefined when getting bounds');
|
|
501
|
+
|
|
502
|
+
// when cs is tilematrix, tcrs or tile, zoom is required.
|
|
503
|
+
// should throw / return null instead of trying to construct a bounds
|
|
504
|
+
|
|
505
|
+
if (
|
|
506
|
+
zoom === undefined &&
|
|
507
|
+
(cs === 'TILEMATRIX' || cs === 'TCRS' || cs === 'TILE')
|
|
508
|
+
)
|
|
509
|
+
throw new Error(
|
|
510
|
+
'map-meta[name=extent] zoom= parameter not provided for tcrs,tile or tilematrix bounds'
|
|
511
|
+
);
|
|
512
|
+
let axes = Util.csToAxes(cs);
|
|
513
|
+
return Util.boundsToPCRSBounds(
|
|
514
|
+
bounds(
|
|
515
|
+
point(+meta[`top-left-${axes[0]}`], +meta[`top-left-${axes[1]}`]),
|
|
516
|
+
point(
|
|
517
|
+
+meta[`bottom-right-${axes[0]}`],
|
|
518
|
+
+meta[`bottom-right-${axes[1]}`]
|
|
519
|
+
)
|
|
520
|
+
),
|
|
521
|
+
zoom,
|
|
522
|
+
projection,
|
|
523
|
+
cs
|
|
524
|
+
);
|
|
525
|
+
} catch (error) {
|
|
526
|
+
//if error then by default set the layer to osm and bounds to the entire map view
|
|
527
|
+
return Util.boundsToPCRSBounds(
|
|
528
|
+
M[projection].options.crs.tilematrix.bounds(0),
|
|
529
|
+
0,
|
|
530
|
+
projection,
|
|
531
|
+
cs
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
},
|
|
535
|
+
/**
|
|
536
|
+
* TODO Review and improve design logic with Aliyan
|
|
537
|
+
*
|
|
538
|
+
* Parses object from <map-meta name="zoom" content="...">
|
|
539
|
+
* @param {type} mapml
|
|
540
|
+
* @returns {minZoom, maxZoom, minNativeZoom, maxNativeZoom}
|
|
541
|
+
*/
|
|
542
|
+
getZoomBoundsFromMeta: function (mapml) {
|
|
543
|
+
if (!mapml) return null;
|
|
544
|
+
let pseudo = mapml instanceof ShadowRoot ? ':host' : ':scope';
|
|
545
|
+
|
|
546
|
+
let meta = Util._metaContentToObject(
|
|
547
|
+
mapml
|
|
548
|
+
.querySelector(pseudo + '> map-meta[name=zoom]')
|
|
549
|
+
.getAttribute('content')
|
|
550
|
+
);
|
|
551
|
+
if (meta.min && meta.max && meta.value)
|
|
552
|
+
return {
|
|
553
|
+
minZoom: +meta.min,
|
|
554
|
+
maxZoom: +meta.max,
|
|
555
|
+
minNativeZoom: +meta.value,
|
|
556
|
+
maxNativeZoom: +meta.value
|
|
557
|
+
};
|
|
558
|
+
else if (meta.min && meta.max)
|
|
559
|
+
return {
|
|
560
|
+
minZoom: +meta.min,
|
|
561
|
+
maxZoom: +meta.max
|
|
562
|
+
};
|
|
563
|
+
else if (meta.min)
|
|
564
|
+
return {
|
|
565
|
+
minZoom: +meta.min
|
|
566
|
+
};
|
|
567
|
+
else if (meta.max)
|
|
568
|
+
return {
|
|
569
|
+
maxZoom: +meta.max
|
|
570
|
+
};
|
|
571
|
+
},
|
|
572
|
+
getZoomBounds: function (mapml, nativeZoom) {
|
|
573
|
+
if (!mapml) return null;
|
|
574
|
+
let nMin = 100,
|
|
575
|
+
nMax = 0,
|
|
576
|
+
features = mapml.querySelectorAll('map-feature'),
|
|
577
|
+
meta,
|
|
578
|
+
projection;
|
|
579
|
+
for (let i = 0; i < features.length; i++) {
|
|
580
|
+
let lZoom = +features[i].getAttribute('zoom');
|
|
581
|
+
if (!features[i].getAttribute('zoom')) lZoom = nativeZoom;
|
|
582
|
+
nMax = Math.max(nMax, lZoom);
|
|
583
|
+
nMin = Math.min(nMin, lZoom);
|
|
584
|
+
}
|
|
585
|
+
try {
|
|
586
|
+
projection = Util._metaContentToObject(
|
|
587
|
+
mapml.querySelector('map-meta[name=projection]').getAttribute('content')
|
|
588
|
+
).content;
|
|
589
|
+
meta = Util._metaContentToObject(
|
|
590
|
+
mapml.querySelector('map-meta[name=zoom]').getAttribute('content')
|
|
591
|
+
);
|
|
592
|
+
} catch (error) {
|
|
593
|
+
return {
|
|
594
|
+
minZoom: 0,
|
|
595
|
+
maxZoom:
|
|
596
|
+
M[projection || M.FALLBACK_PROJECTION].options.resolutions.length - 1,
|
|
597
|
+
minNativeZoom: nMin,
|
|
598
|
+
maxNativeZoom: nMax
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
return {
|
|
602
|
+
minZoom: +meta.min,
|
|
603
|
+
maxZoom: +meta.max,
|
|
604
|
+
minNativeZoom: nMin,
|
|
605
|
+
maxNativeZoom: nMax
|
|
606
|
+
};
|
|
607
|
+
},
|
|
608
|
+
// getNativeVariables: returns an object with the native zoom and CS,
|
|
609
|
+
// based on the map-metas that are available within
|
|
610
|
+
// the layer or the fallback default values.
|
|
611
|
+
// getNativeVariables: mapml-||map-layer||null||[map-feature,...] -> {zoom: _, val: _}
|
|
612
|
+
// mapml can be a mapml- element, map-layer element, null, or an array of map-features
|
|
613
|
+
getNativeVariables: function (mapml) {
|
|
614
|
+
let nativeZoom, nativeCS;
|
|
615
|
+
// when mapml is an array of features provided by the query
|
|
616
|
+
if (
|
|
617
|
+
mapml.length &&
|
|
618
|
+
mapml[0].parentElement.parentElement &&
|
|
619
|
+
mapml[0].parentElement.parentElement.tagName === 'mapml-'
|
|
620
|
+
) {
|
|
621
|
+
let mapmlEl = mapml[0].parentElement.parentElement;
|
|
622
|
+
nativeZoom =
|
|
623
|
+
(mapmlEl.querySelector &&
|
|
624
|
+
mapmlEl.querySelector('map-meta[name=zoom]') &&
|
|
625
|
+
+Util._metaContentToObject(
|
|
626
|
+
mapmlEl.querySelector('map-meta[name=zoom]').getAttribute('content')
|
|
627
|
+
).value) ||
|
|
628
|
+
0;
|
|
629
|
+
nativeCS =
|
|
630
|
+
(mapmlEl.querySelector &&
|
|
631
|
+
mapmlEl.querySelector('map-meta[name=cs]') &&
|
|
632
|
+
Util._metaContentToObject(
|
|
633
|
+
mapmlEl.querySelector('map-meta[name=cs]').getAttribute('content')
|
|
634
|
+
).content) ||
|
|
635
|
+
'GCRS';
|
|
636
|
+
} else {
|
|
637
|
+
// when mapml is null or a map-layer/mapml- element
|
|
638
|
+
nativeZoom =
|
|
639
|
+
(mapml.querySelector &&
|
|
640
|
+
mapml.querySelector('map-meta[name=zoom]') &&
|
|
641
|
+
+Util._metaContentToObject(
|
|
642
|
+
mapml.querySelector('map-meta[name=zoom]').getAttribute('content')
|
|
643
|
+
).value) ||
|
|
644
|
+
0;
|
|
645
|
+
nativeCS =
|
|
646
|
+
(mapml.querySelector &&
|
|
647
|
+
mapml.querySelector('map-meta[name=cs]') &&
|
|
648
|
+
Util._metaContentToObject(
|
|
649
|
+
mapml.querySelector('map-meta[name=cs]').getAttribute('content')
|
|
650
|
+
).content) ||
|
|
651
|
+
'GCRS';
|
|
652
|
+
}
|
|
653
|
+
return { zoom: nativeZoom, cs: nativeCS };
|
|
654
|
+
},
|
|
655
|
+
|
|
656
|
+
// _gcrsToTileMatrix returns the [column, row] of the tiles at map center. Used for Announce movement for screen readers
|
|
657
|
+
// _gcrsToTileMatrix: map/mapml-viewer -> [column, row]
|
|
658
|
+
_gcrsToTileMatrix: function (mapEl) {
|
|
659
|
+
let pt0 = mapEl._map.project(mapEl._map.getCenter());
|
|
660
|
+
let tileSize = mapEl._map.options.crs.options.crs.tile.bounds.max.y;
|
|
661
|
+
let column = Math.trunc(pt0.x / tileSize);
|
|
662
|
+
let row = Math.trunc(pt0.y / tileSize);
|
|
663
|
+
return [column, row];
|
|
664
|
+
},
|
|
665
|
+
|
|
666
|
+
// Pastes text to a mapml-viewer/map element(mapEl), text can be a mapml link, GeoJSON link, GeoJSON,
|
|
667
|
+
// or a map-layer used for pasting layers through ctrl+v, drag/drop, and pasting through the contextmenu
|
|
668
|
+
// _pasteLayer: HTMLElement Str -> None
|
|
669
|
+
// Effects: append a map-layer element to mapEl, if it is valid
|
|
670
|
+
_pasteLayer: async function (mapEl, text) {
|
|
671
|
+
try {
|
|
672
|
+
// try to process text as a link
|
|
673
|
+
new URL(text);
|
|
674
|
+
// get the content type of the link
|
|
675
|
+
const response = await fetch(text);
|
|
676
|
+
const contentType = response.headers.get('Content-Type');
|
|
677
|
+
// get the file extension by removing any query strings that may exist
|
|
678
|
+
let ext = response.url
|
|
679
|
+
.split('?')[0]
|
|
680
|
+
.split('#')[0]
|
|
681
|
+
.split('.')
|
|
682
|
+
.pop()
|
|
683
|
+
.toLowerCase();
|
|
684
|
+
if (
|
|
685
|
+
contentType === 'application/json' ||
|
|
686
|
+
contentType === 'application/geo+json' ||
|
|
687
|
+
ext === 'geojson' ||
|
|
688
|
+
ext === 'json'
|
|
689
|
+
) {
|
|
690
|
+
// try to process as GeoJSON
|
|
691
|
+
const textContent = await response.text();
|
|
692
|
+
try {
|
|
693
|
+
mapEl.geojson2mapml(JSON.parse(textContent));
|
|
694
|
+
} catch {
|
|
695
|
+
console.log('Error parsing GeoJSON from: ' + text);
|
|
696
|
+
}
|
|
697
|
+
} else {
|
|
698
|
+
// try to process as a mapml file
|
|
699
|
+
// create a new <map-layer> child of the <mapml-viewer> element
|
|
700
|
+
let l =
|
|
701
|
+
'<map-layer src="' +
|
|
702
|
+
text +
|
|
703
|
+
'" label="' +
|
|
704
|
+
mapEl.locale.dfLayer +
|
|
705
|
+
'" checked=""></map-layer>';
|
|
706
|
+
mapEl.insertAdjacentHTML('beforeend', l);
|
|
707
|
+
mapEl.lastElementChild.whenReady().catch(() => {
|
|
708
|
+
if (mapEl) {
|
|
709
|
+
// should invoke lifecyle callbacks automatically by removing it from DOM
|
|
710
|
+
mapEl.removeChild(mapEl.lastChild);
|
|
711
|
+
}
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
} catch (err) {
|
|
715
|
+
text = text
|
|
716
|
+
.replace(/(<!--.*?-->)|(<!--[\S\s]+?-->)|(<!--[\S\s]*?$)/g, '')
|
|
717
|
+
.trim();
|
|
718
|
+
if (
|
|
719
|
+
text.slice(0, 10) === '<map-layer' &&
|
|
720
|
+
text.slice(-12) === '</map-layer>'
|
|
721
|
+
) {
|
|
722
|
+
mapEl.insertAdjacentHTML('beforeend', text);
|
|
723
|
+
} else if (
|
|
724
|
+
text.slice(0, 12) === '<map-feature' &&
|
|
725
|
+
text.slice(-14) === '</map-feature>'
|
|
726
|
+
) {
|
|
727
|
+
let layer =
|
|
728
|
+
`<map-layer label="${mapEl.locale.dfPastedLayer}" checked>
|
|
729
|
+
<map-meta name='projection' content='${mapEl.projection}'></map-meta>` +
|
|
730
|
+
text +
|
|
731
|
+
'</map-layer>';
|
|
732
|
+
mapEl.insertAdjacentHTML('beforeend', layer);
|
|
733
|
+
} else {
|
|
734
|
+
try {
|
|
735
|
+
mapEl.geojson2mapml(JSON.parse(text));
|
|
736
|
+
} catch {
|
|
737
|
+
console.log('Invalid Input!');
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
},
|
|
742
|
+
|
|
743
|
+
// Takes GeoJSON Properties to return an HTML table, helper function
|
|
744
|
+
// for geojson2mapml
|
|
745
|
+
// _properties2Table: geojsonPropertiesOBJ -> HTML Table
|
|
746
|
+
_properties2Table: function (json) {
|
|
747
|
+
let table = document.createElement('table');
|
|
748
|
+
|
|
749
|
+
// Creating a Table Header
|
|
750
|
+
let thead = table.createTHead();
|
|
751
|
+
let row = thead.insertRow();
|
|
752
|
+
let th1 = document.createElement('th');
|
|
753
|
+
let th2 = document.createElement('th');
|
|
754
|
+
th1.appendChild(document.createTextNode(M.options.locale.popupPropName));
|
|
755
|
+
th2.appendChild(document.createTextNode(M.options.locale.popupPropValue));
|
|
756
|
+
th1.setAttribute('role', 'columnheader');
|
|
757
|
+
th2.setAttribute('role', 'columnheader');
|
|
758
|
+
th1.setAttribute('scope', 'col');
|
|
759
|
+
th2.setAttribute('scope', 'col');
|
|
760
|
+
row.appendChild(th1);
|
|
761
|
+
row.appendChild(th2);
|
|
762
|
+
|
|
763
|
+
// Creating table body and populating it from the JSON
|
|
764
|
+
let tbody = table.createTBody();
|
|
765
|
+
for (let key in json) {
|
|
766
|
+
if (json.hasOwnProperty(key)) {
|
|
767
|
+
let row = tbody.insertRow();
|
|
768
|
+
let th = document.createElement('th');
|
|
769
|
+
let td = document.createElement('td');
|
|
770
|
+
th.appendChild(document.createTextNode(key));
|
|
771
|
+
td.appendChild(document.createTextNode(json[key]));
|
|
772
|
+
th.setAttribute('scope', 'row');
|
|
773
|
+
td.setAttribute('itemprop', key);
|
|
774
|
+
row.appendChild(th);
|
|
775
|
+
row.appendChild(td);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
return table;
|
|
779
|
+
},
|
|
780
|
+
|
|
781
|
+
// Takes bbox array and a x,y coordinate to possibly update the extent, returns extent
|
|
782
|
+
// for geojson2mapml
|
|
783
|
+
// _updateExtent: [min x, min y, max x, max y], x, y -> [min x, min y, max x, max y]
|
|
784
|
+
_updateExtent: function (bboxExtent, x, y) {
|
|
785
|
+
if (!bboxExtent || Object.keys(bboxExtent).length === 0) {
|
|
786
|
+
return bboxExtent;
|
|
787
|
+
}
|
|
788
|
+
bboxExtent[0] = Math.min(x, bboxExtent[0]);
|
|
789
|
+
bboxExtent[1] = Math.min(y, bboxExtent[1]);
|
|
790
|
+
bboxExtent[2] = Math.max(x, bboxExtent[2]);
|
|
791
|
+
bboxExtent[3] = Math.max(y, bboxExtent[3]);
|
|
792
|
+
return bboxExtent;
|
|
793
|
+
},
|
|
794
|
+
|
|
795
|
+
// Takes a GeoJSON geojson and an options Object which returns a <map-layer> Element
|
|
796
|
+
// The options object can contain the following:
|
|
797
|
+
// label - String, contains the layer name, if included overrides the default label mapping
|
|
798
|
+
// projection - String, contains the projection of the layer (OSMTILE, WGS84, CBMTILE, APSTILE), defaults to OSMTILE
|
|
799
|
+
// caption - Function | String, function accepts one argument being the feature object which produces the featurecaption string OR a string that is the name of the property that will be mapped to featurecaption
|
|
800
|
+
// properties - Function | String | HTMLElement, a function which maps the geojson feature to an HTMLElement or a string that will be parsed as an HTMLElement or an HTMLElement
|
|
801
|
+
// geometryFunction - Function, A function you supply that can add classes, hyperlinks and spans to the created <map-geometry> element, default would be the plain map-geometry element
|
|
802
|
+
// geojson2mapml: geojson Object <map-layer> [min x, min y, max x, max y] -> <map-layer>
|
|
803
|
+
geojson2mapml: function (json, options = {}, layer = null, bboxExtent = {}) {
|
|
804
|
+
let defaults = {
|
|
805
|
+
label: null,
|
|
806
|
+
projection: 'OSMTILE',
|
|
807
|
+
caption: null,
|
|
808
|
+
properties: null,
|
|
809
|
+
geometryFunction: null
|
|
810
|
+
};
|
|
811
|
+
// assign default values for undefined options
|
|
812
|
+
options = Object.assign({}, defaults, options);
|
|
813
|
+
|
|
814
|
+
// If string json is received
|
|
815
|
+
if (typeof json === 'string') {
|
|
816
|
+
json = JSON.parse(json);
|
|
817
|
+
}
|
|
818
|
+
let geometryType = [
|
|
819
|
+
'POINT',
|
|
820
|
+
'LINESTRING',
|
|
821
|
+
'POLYGON',
|
|
822
|
+
'MULTIPOINT',
|
|
823
|
+
'MULTILINESTRING',
|
|
824
|
+
'MULTIPOLYGON',
|
|
825
|
+
'GEOMETRYCOLLECTION'
|
|
826
|
+
];
|
|
827
|
+
let jsonType = json.type.toUpperCase();
|
|
828
|
+
let out = '';
|
|
829
|
+
let setExtent = false;
|
|
830
|
+
|
|
831
|
+
// HTML parser
|
|
832
|
+
let parser = new DOMParser();
|
|
833
|
+
|
|
834
|
+
// initializing layer
|
|
835
|
+
if (layer === null) {
|
|
836
|
+
if (!json.bbox) {
|
|
837
|
+
setExtent = true;
|
|
838
|
+
}
|
|
839
|
+
// creating an empty mapml layer
|
|
840
|
+
let xmlStringLayer =
|
|
841
|
+
"<map-layer label='' checked><map-meta name='projection' content='" +
|
|
842
|
+
options.projection +
|
|
843
|
+
"'></map-meta><map-meta name='cs' content='gcrs'></map-meta></map-layer>";
|
|
844
|
+
layer = parser.parseFromString(xmlStringLayer, 'text/html');
|
|
845
|
+
//console.log(layer)
|
|
846
|
+
if (options.label !== null) {
|
|
847
|
+
layer.querySelector('map-layer').setAttribute('label', options.label);
|
|
848
|
+
} else if (json.name) {
|
|
849
|
+
layer.querySelector('map-layer').setAttribute('label', json.name);
|
|
850
|
+
} else if (json.title) {
|
|
851
|
+
layer.querySelector('map-layer').setAttribute('label', json.title);
|
|
852
|
+
} else {
|
|
853
|
+
layer
|
|
854
|
+
.querySelector('map-layer')
|
|
855
|
+
.setAttribute('label', M.options.locale.dfLayer);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
let ptElStr = '<map-point></map-point>',
|
|
859
|
+
ptEl = parser.parseFromString(ptElStr, 'text/html');
|
|
860
|
+
|
|
861
|
+
let multiPoint =
|
|
862
|
+
'<map-multipoint><map-coordinates></map-coordinates></map-multipoint>';
|
|
863
|
+
multiPoint = parser.parseFromString(multiPoint, 'text/html');
|
|
864
|
+
|
|
865
|
+
let linestring =
|
|
866
|
+
'<map-linestring><map-coordinates></map-coordinates></map-linestring>';
|
|
867
|
+
linestring = parser.parseFromString(linestring, 'text/html');
|
|
868
|
+
|
|
869
|
+
let multilinestring = '<map-multilinestring></map-multilinestring>';
|
|
870
|
+
multilinestring = parser.parseFromString(multilinestring, 'text/html');
|
|
871
|
+
|
|
872
|
+
let polygon = '<map-polygon></map-polygon>';
|
|
873
|
+
polygon = parser.parseFromString(polygon, 'text/html');
|
|
874
|
+
|
|
875
|
+
let multiPolygon = '<map-multipolygon></map-multipolygon>';
|
|
876
|
+
multiPolygon = parser.parseFromString(multiPolygon, 'text/html');
|
|
877
|
+
|
|
878
|
+
let geometrycollection =
|
|
879
|
+
'<map-geometrycollection></map-geometrycollection>';
|
|
880
|
+
geometrycollection = parser.parseFromString(
|
|
881
|
+
geometrycollection,
|
|
882
|
+
'text/html'
|
|
883
|
+
);
|
|
884
|
+
|
|
885
|
+
let feature =
|
|
886
|
+
'<map-feature><map-featurecaption></map-featurecaption><map-geometry></map-geometry><map-properties></map-properties></map-feature>';
|
|
887
|
+
feature = parser.parseFromString(feature, 'text/html');
|
|
888
|
+
|
|
889
|
+
// Template to add coordinates to Geometries
|
|
890
|
+
let coords = '<map-coordinates></map-coordinates>';
|
|
891
|
+
coords = parser.parseFromString(coords, 'text/html');
|
|
892
|
+
|
|
893
|
+
//console.log(layer);
|
|
894
|
+
if (jsonType === 'FEATURECOLLECTION') {
|
|
895
|
+
// Setting bbox if it exists
|
|
896
|
+
if (json.bbox) {
|
|
897
|
+
layer
|
|
898
|
+
.querySelector('map-layer')
|
|
899
|
+
.insertAdjacentHTML(
|
|
900
|
+
'afterbegin',
|
|
901
|
+
"<map-meta name='extent' content='top-left-longitude=" +
|
|
902
|
+
json.bbox[0] +
|
|
903
|
+
', top-left-latitude=' +
|
|
904
|
+
json.bbox[1] +
|
|
905
|
+
', bottom-right-longitude=' +
|
|
906
|
+
json.bbox[2] +
|
|
907
|
+
',bottom-right-latitude=' +
|
|
908
|
+
json.bbox[3] +
|
|
909
|
+
"'></map-meta>"
|
|
910
|
+
);
|
|
911
|
+
} else {
|
|
912
|
+
bboxExtent = [
|
|
913
|
+
Infinity,
|
|
914
|
+
Infinity,
|
|
915
|
+
Number.NEGATIVE_INFINITY,
|
|
916
|
+
Number.NEGATIVE_INFINITY
|
|
917
|
+
];
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
let features = json.features;
|
|
921
|
+
//console.log("Features length - " + features.length);
|
|
922
|
+
for (let l = 0; l < features.length; l++) {
|
|
923
|
+
Util.geojson2mapml(features[l], options, layer, bboxExtent);
|
|
924
|
+
}
|
|
925
|
+
} else if (jsonType === 'FEATURE') {
|
|
926
|
+
let clone_feature = feature.cloneNode(true);
|
|
927
|
+
let curr_feature = clone_feature.querySelector('map-feature');
|
|
928
|
+
|
|
929
|
+
// Setting bbox if it exists
|
|
930
|
+
if (json.bbox) {
|
|
931
|
+
layer
|
|
932
|
+
.querySelector('map-layer')
|
|
933
|
+
.insertAdjacentHTML(
|
|
934
|
+
'afterbegin',
|
|
935
|
+
"<map-meta name='extent' content='top-left-longitude=" +
|
|
936
|
+
json.bbox[0] +
|
|
937
|
+
', top-left-latitude=' +
|
|
938
|
+
json.bbox[1] +
|
|
939
|
+
', bottom-right-longitude=' +
|
|
940
|
+
json.bbox[2] +
|
|
941
|
+
',bottom-right-latitude=' +
|
|
942
|
+
json.bbox[3] +
|
|
943
|
+
"'></map-meta>"
|
|
944
|
+
);
|
|
945
|
+
} else if (
|
|
946
|
+
typeof bboxExtent === 'object' &&
|
|
947
|
+
bboxExtent.length === undefined
|
|
948
|
+
) {
|
|
949
|
+
bboxExtent = [
|
|
950
|
+
Infinity,
|
|
951
|
+
Infinity,
|
|
952
|
+
Number.NEGATIVE_INFINITY,
|
|
953
|
+
Number.NEGATIVE_INFINITY
|
|
954
|
+
];
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
// Setting featurecaption
|
|
958
|
+
let featureCaption = layer
|
|
959
|
+
.querySelector('map-layer')
|
|
960
|
+
.getAttribute('label');
|
|
961
|
+
if (typeof options.caption === 'function') {
|
|
962
|
+
featureCaption = options.caption(json);
|
|
963
|
+
} else if (typeof options.caption === 'string') {
|
|
964
|
+
featureCaption = json.properties[options.caption];
|
|
965
|
+
// if property does not exist
|
|
966
|
+
if (featureCaption === undefined) {
|
|
967
|
+
featureCaption = options.caption;
|
|
968
|
+
}
|
|
969
|
+
} else if (json.id) {
|
|
970
|
+
// when no caption option available try setting id as featurecaption
|
|
971
|
+
featureCaption = json.id;
|
|
972
|
+
}
|
|
973
|
+
curr_feature.querySelector('map-featurecaption').innerHTML =
|
|
974
|
+
featureCaption;
|
|
975
|
+
|
|
976
|
+
// Setting Properties
|
|
977
|
+
let p;
|
|
978
|
+
// if properties function is passed
|
|
979
|
+
if (typeof options.properties === 'function') {
|
|
980
|
+
p = options.properties(json);
|
|
981
|
+
// if function output is not an element, ignore the properties.
|
|
982
|
+
if (!(p instanceof Element)) {
|
|
983
|
+
p = false;
|
|
984
|
+
console.error(
|
|
985
|
+
'options.properties function returns a string instead of an HTMLElement.'
|
|
986
|
+
);
|
|
987
|
+
}
|
|
988
|
+
} else if (typeof options.properties === 'string') {
|
|
989
|
+
// if properties string is passed
|
|
990
|
+
curr_feature
|
|
991
|
+
.querySelector('map-properties')
|
|
992
|
+
.insertAdjacentHTML('beforeend', options.properties);
|
|
993
|
+
p = false;
|
|
994
|
+
} else if (options.properties instanceof HTMLElement) {
|
|
995
|
+
// if an HTMLElement is passed - NOT TESTED
|
|
996
|
+
p = options.properties;
|
|
997
|
+
} else {
|
|
998
|
+
// If no properties function, string or HTMLElement is passed
|
|
999
|
+
p = Util._properties2Table(json.properties);
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
if (p) {
|
|
1003
|
+
curr_feature.querySelector('map-properties').appendChild(p);
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
// Setting map-geometry
|
|
1007
|
+
let g = Util.geojson2mapml(json.geometry, options, layer, bboxExtent);
|
|
1008
|
+
if (typeof options.geometryFunction === 'function') {
|
|
1009
|
+
curr_feature
|
|
1010
|
+
.querySelector('map-geometry')
|
|
1011
|
+
.appendChild(options.geometryFunction(g, json));
|
|
1012
|
+
} else {
|
|
1013
|
+
curr_feature.querySelector('map-geometry').appendChild(g);
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
// Appending feature to layer
|
|
1017
|
+
layer.querySelector('map-layer').appendChild(curr_feature);
|
|
1018
|
+
} else if (geometryType.includes(jsonType)) {
|
|
1019
|
+
//console.log("Geometry Type - " + jsonType);
|
|
1020
|
+
switch (jsonType) {
|
|
1021
|
+
case 'POINT':
|
|
1022
|
+
bboxExtent = Util._updateExtent(
|
|
1023
|
+
bboxExtent,
|
|
1024
|
+
json.coordinates[0],
|
|
1025
|
+
json.coordinates[1]
|
|
1026
|
+
);
|
|
1027
|
+
out = json.coordinates[0] + ' ' + json.coordinates[1];
|
|
1028
|
+
|
|
1029
|
+
// Create Point element
|
|
1030
|
+
let clone_point = ptEl.cloneNode(true);
|
|
1031
|
+
clone_point = clone_point.querySelector('map-point');
|
|
1032
|
+
|
|
1033
|
+
// Create map-coords to add to the polygon
|
|
1034
|
+
let clone_coords = coords.cloneNode(true);
|
|
1035
|
+
clone_coords = clone_coords.querySelector('map-coordinates');
|
|
1036
|
+
|
|
1037
|
+
clone_coords.innerHTML = out;
|
|
1038
|
+
|
|
1039
|
+
clone_point.appendChild(clone_coords);
|
|
1040
|
+
//console.log(clone_point);
|
|
1041
|
+
return clone_point;
|
|
1042
|
+
|
|
1043
|
+
case 'LINESTRING':
|
|
1044
|
+
let clone_linestring = linestring.cloneNode(true);
|
|
1045
|
+
let linestring_coordindates =
|
|
1046
|
+
clone_linestring.querySelector('map-coordinates');
|
|
1047
|
+
|
|
1048
|
+
out = '';
|
|
1049
|
+
|
|
1050
|
+
for (let x = 0; x < json.coordinates.length; x++) {
|
|
1051
|
+
bboxExtent = Util._updateExtent(
|
|
1052
|
+
bboxExtent,
|
|
1053
|
+
json.coordinates[x][0],
|
|
1054
|
+
json.coordinates[x][1]
|
|
1055
|
+
);
|
|
1056
|
+
out =
|
|
1057
|
+
out + json.coordinates[x][0] + ' ' + json.coordinates[x][1] + ' ';
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
linestring_coordindates.innerHTML = out;
|
|
1061
|
+
//console.log(clone_linestring.querySelector('map-linestring'));
|
|
1062
|
+
return clone_linestring.querySelector('map-linestring');
|
|
1063
|
+
|
|
1064
|
+
case 'POLYGON':
|
|
1065
|
+
let clone_polygon = polygon.cloneNode(true);
|
|
1066
|
+
clone_polygon = clone_polygon.querySelector('map-polygon');
|
|
1067
|
+
|
|
1068
|
+
// Going over each coordinates
|
|
1069
|
+
for (let y = 0; y < json.coordinates.length; y++) {
|
|
1070
|
+
let out = '';
|
|
1071
|
+
let clone_coords = coords.cloneNode(true);
|
|
1072
|
+
clone_coords = clone_coords.querySelector('map-coordinates');
|
|
1073
|
+
|
|
1074
|
+
// Going over coordinates for the polygon
|
|
1075
|
+
for (let x = 0; x < json.coordinates[y].length; x++) {
|
|
1076
|
+
bboxExtent = Util._updateExtent(
|
|
1077
|
+
bboxExtent,
|
|
1078
|
+
json.coordinates[y][x][0],
|
|
1079
|
+
json.coordinates[y][x][1]
|
|
1080
|
+
);
|
|
1081
|
+
out =
|
|
1082
|
+
out +
|
|
1083
|
+
json.coordinates[y][x][0] +
|
|
1084
|
+
' ' +
|
|
1085
|
+
json.coordinates[y][x][1] +
|
|
1086
|
+
' ';
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
// Create map-coordinates element and append it to clone_polygon
|
|
1090
|
+
clone_coords.innerHTML = out;
|
|
1091
|
+
|
|
1092
|
+
clone_polygon.appendChild(clone_coords);
|
|
1093
|
+
}
|
|
1094
|
+
//console.log(clone_polygon);
|
|
1095
|
+
return clone_polygon;
|
|
1096
|
+
|
|
1097
|
+
case 'MULTIPOINT':
|
|
1098
|
+
out = '';
|
|
1099
|
+
// Create multipoint element
|
|
1100
|
+
let clone_multipoint = multiPoint.cloneNode(true);
|
|
1101
|
+
clone_multipoint = clone_multipoint.querySelector('map-multipoint');
|
|
1102
|
+
|
|
1103
|
+
for (let i = 0; i < json.coordinates.length; i++) {
|
|
1104
|
+
bboxExtent = Util._updateExtent(
|
|
1105
|
+
bboxExtent,
|
|
1106
|
+
json.coordinates[i][0],
|
|
1107
|
+
json.coordinates[i][1]
|
|
1108
|
+
);
|
|
1109
|
+
out =
|
|
1110
|
+
out + json.coordinates[i][0] + ' ' + json.coordinates[i][1] + ' ';
|
|
1111
|
+
}
|
|
1112
|
+
clone_multipoint.querySelector('map-coordinates').innerHTML = out;
|
|
1113
|
+
return clone_multipoint;
|
|
1114
|
+
|
|
1115
|
+
case 'MULTILINESTRING':
|
|
1116
|
+
let clone_multilinestring = multilinestring.cloneNode(true);
|
|
1117
|
+
clone_multilinestring = clone_multilinestring.querySelector(
|
|
1118
|
+
'map-multilinestring'
|
|
1119
|
+
);
|
|
1120
|
+
|
|
1121
|
+
for (let i = 0; i < json.coordinates.length; i++) {
|
|
1122
|
+
let out = '';
|
|
1123
|
+
let clone_coords = coords.cloneNode(true);
|
|
1124
|
+
clone_coords = clone_coords.querySelector('map-coordinates');
|
|
1125
|
+
for (let y = 0; y < json.coordinates[i].length; y++) {
|
|
1126
|
+
bboxExtent = Util._updateExtent(
|
|
1127
|
+
bboxExtent,
|
|
1128
|
+
json.coordinates[i][y][0],
|
|
1129
|
+
json.coordinates[i][y][1]
|
|
1130
|
+
);
|
|
1131
|
+
out =
|
|
1132
|
+
out +
|
|
1133
|
+
json.coordinates[i][y][0] +
|
|
1134
|
+
' ' +
|
|
1135
|
+
json.coordinates[i][y][1] +
|
|
1136
|
+
' ';
|
|
1137
|
+
}
|
|
1138
|
+
clone_coords.innerHTML = out;
|
|
1139
|
+
clone_multilinestring.appendChild(clone_coords);
|
|
1140
|
+
}
|
|
1141
|
+
return clone_multilinestring;
|
|
1142
|
+
|
|
1143
|
+
case 'MULTIPOLYGON':
|
|
1144
|
+
let m = multiPolygon.cloneNode(true);
|
|
1145
|
+
m = m.querySelector('map-multiPolygon');
|
|
1146
|
+
|
|
1147
|
+
// Going over each Polygon
|
|
1148
|
+
for (let i = 0; i < json.coordinates.length; i++) {
|
|
1149
|
+
let clone_polygon = polygon.cloneNode(true);
|
|
1150
|
+
clone_polygon = clone_polygon.querySelector('map-polygon');
|
|
1151
|
+
|
|
1152
|
+
// Going over each coordinates
|
|
1153
|
+
for (let y = 0; y < json.coordinates[i].length; y++) {
|
|
1154
|
+
let out = '';
|
|
1155
|
+
let clone_coords = coords.cloneNode(true);
|
|
1156
|
+
clone_coords = clone_coords.querySelector('map-coordinates');
|
|
1157
|
+
|
|
1158
|
+
// Going over coordinates for the polygon
|
|
1159
|
+
for (let x = 0; x < json.coordinates[i][y].length; x++) {
|
|
1160
|
+
bboxExtent = Util._updateExtent(
|
|
1161
|
+
bboxExtent,
|
|
1162
|
+
json.coordinates[i][y][x][0],
|
|
1163
|
+
json.coordinates[i][y][x][1]
|
|
1164
|
+
);
|
|
1165
|
+
out =
|
|
1166
|
+
out +
|
|
1167
|
+
json.coordinates[i][y][x][0] +
|
|
1168
|
+
' ' +
|
|
1169
|
+
json.coordinates[i][y][x][1] +
|
|
1170
|
+
' ';
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
// Create map-coordinates element and append it to clone_polygon
|
|
1174
|
+
clone_coords.innerHTML = out;
|
|
1175
|
+
|
|
1176
|
+
clone_polygon.appendChild(clone_coords);
|
|
1177
|
+
}
|
|
1178
|
+
m.appendChild(clone_polygon);
|
|
1179
|
+
}
|
|
1180
|
+
return m;
|
|
1181
|
+
case 'GEOMETRYCOLLECTION': // ---------------------------------------------------------------------------
|
|
1182
|
+
let g = geometrycollection.cloneNode(true);
|
|
1183
|
+
g = g.querySelector('map-geometrycollection');
|
|
1184
|
+
//console.log(json.geometries);
|
|
1185
|
+
for (let i = 0; i < json.geometries.length; i++) {
|
|
1186
|
+
let fg = Util.geojson2mapml(
|
|
1187
|
+
json.geometries[i],
|
|
1188
|
+
options,
|
|
1189
|
+
layer,
|
|
1190
|
+
bboxExtent
|
|
1191
|
+
);
|
|
1192
|
+
g.appendChild(fg);
|
|
1193
|
+
}
|
|
1194
|
+
return g;
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
//Add default bbox
|
|
1198
|
+
if (setExtent) {
|
|
1199
|
+
layer
|
|
1200
|
+
.querySelector('map-layer')
|
|
1201
|
+
.insertAdjacentHTML(
|
|
1202
|
+
'afterbegin',
|
|
1203
|
+
"<map-meta name='extent' content='top-left-longitude=" +
|
|
1204
|
+
bboxExtent[0] +
|
|
1205
|
+
', top-left-latitude=' +
|
|
1206
|
+
bboxExtent[1] +
|
|
1207
|
+
', bottom-right-longitude=' +
|
|
1208
|
+
bboxExtent[2] +
|
|
1209
|
+
',bottom-right-latitude=' +
|
|
1210
|
+
bboxExtent[3] +
|
|
1211
|
+
"'></map-meta>"
|
|
1212
|
+
);
|
|
1213
|
+
}
|
|
1214
|
+
return layer.querySelector('map-layer');
|
|
1215
|
+
},
|
|
1216
|
+
|
|
1217
|
+
// Takes an array of length n to return an array of arrays with length 2, helper function
|
|
1218
|
+
// for mapml2geojson
|
|
1219
|
+
// _breakArray: arr(float) -> arr(arr(float, float))
|
|
1220
|
+
_breakArray: function (arr) {
|
|
1221
|
+
let size = 2;
|
|
1222
|
+
let arrayOfArrays = [];
|
|
1223
|
+
// removing anything other than numbers, ., - (used to remove <map-span> tags)
|
|
1224
|
+
arr = arr.filter((x) => !/[^\d.-]/g.test(x)).filter((x) => x);
|
|
1225
|
+
for (let i = 0; i < arr.length; i += size) {
|
|
1226
|
+
arrayOfArrays.push(arr.slice(i, i + size).map(Number));
|
|
1227
|
+
}
|
|
1228
|
+
return arrayOfArrays;
|
|
1229
|
+
},
|
|
1230
|
+
|
|
1231
|
+
// Takes an HTML Table to return geojson properties, helper function
|
|
1232
|
+
// for mapml2geojson
|
|
1233
|
+
// _table2properties: HTML Table -> geojson
|
|
1234
|
+
_table2properties: function (table) {
|
|
1235
|
+
// removing thead, if it exists
|
|
1236
|
+
let head = table.querySelector('thead');
|
|
1237
|
+
if (head !== null) {
|
|
1238
|
+
table.querySelector('thead').remove();
|
|
1239
|
+
}
|
|
1240
|
+
let json = {};
|
|
1241
|
+
table.querySelectorAll('tr').forEach((tr) => {
|
|
1242
|
+
let tableData = tr.querySelectorAll('th, td');
|
|
1243
|
+
json[tableData[0].innerHTML] = tableData[1].innerHTML;
|
|
1244
|
+
});
|
|
1245
|
+
return json;
|
|
1246
|
+
},
|
|
1247
|
+
|
|
1248
|
+
// Converts a geometry element (el) to geojson, helper function
|
|
1249
|
+
// for mapml2geojson, NOTE - el can not be a map-geometrycollection
|
|
1250
|
+
// _geometry2geojson: (child of <map-geometry>), Proj4, Proj4, Bool -> geojson
|
|
1251
|
+
_geometry2geojson: function (el, source, dest, transform) {
|
|
1252
|
+
// remove map-a, map-span elements if the geometry is wrapped in them
|
|
1253
|
+
while (
|
|
1254
|
+
el.nodeName.toUpperCase() === 'MAP-SPAN' ||
|
|
1255
|
+
el.nodeName.toUpperCase() === 'MAP-A'
|
|
1256
|
+
) {
|
|
1257
|
+
el = el.firstElementChild;
|
|
1258
|
+
}
|
|
1259
|
+
let elem = el.nodeName;
|
|
1260
|
+
let j = {};
|
|
1261
|
+
let coord;
|
|
1262
|
+
|
|
1263
|
+
switch (elem.toUpperCase()) {
|
|
1264
|
+
case 'MAP-POINT':
|
|
1265
|
+
j.type = 'Point';
|
|
1266
|
+
if (transform) {
|
|
1267
|
+
let pointConv = proj4.transform(
|
|
1268
|
+
source,
|
|
1269
|
+
dest,
|
|
1270
|
+
el
|
|
1271
|
+
.querySelector('map-coordinates')
|
|
1272
|
+
.innerHTML.split(/[<>\ ]/g)
|
|
1273
|
+
.map(Number)
|
|
1274
|
+
);
|
|
1275
|
+
j.coordinates = [pointConv.x, pointConv.y];
|
|
1276
|
+
} else {
|
|
1277
|
+
j.coordinates = el
|
|
1278
|
+
.querySelector('map-coordinates')
|
|
1279
|
+
.innerHTML.split(/[<>\ ]/g)
|
|
1280
|
+
.map(Number);
|
|
1281
|
+
}
|
|
1282
|
+
break;
|
|
1283
|
+
case 'MAP-LINESTRING':
|
|
1284
|
+
j.type = 'LineString';
|
|
1285
|
+
coord = el.querySelector('map-coordinates').innerHTML.split(/[<>\ ]/g);
|
|
1286
|
+
coord = Util._breakArray(coord);
|
|
1287
|
+
if (transform) {
|
|
1288
|
+
coord = Util._pcrsToGcrs(coord, source, dest);
|
|
1289
|
+
}
|
|
1290
|
+
j.coordinates = coord;
|
|
1291
|
+
break;
|
|
1292
|
+
case 'MAP-POLYGON':
|
|
1293
|
+
j.type = 'Polygon';
|
|
1294
|
+
j.coordinates = [];
|
|
1295
|
+
let x = 0;
|
|
1296
|
+
el.querySelectorAll('map-coordinates').forEach((coord) => {
|
|
1297
|
+
coord = coord.innerHTML.split(/[<>\ ]/g);
|
|
1298
|
+
coord = Util._breakArray(coord);
|
|
1299
|
+
if (transform) {
|
|
1300
|
+
coord = Util._pcrsToGcrs(coord, source, dest);
|
|
1301
|
+
}
|
|
1302
|
+
j.coordinates[x] = coord;
|
|
1303
|
+
x++;
|
|
1304
|
+
});
|
|
1305
|
+
break;
|
|
1306
|
+
case 'MAP-MULTIPOINT':
|
|
1307
|
+
j.type = 'MultiPoint';
|
|
1308
|
+
coord = Util._breakArray(
|
|
1309
|
+
el.querySelector('map-coordinates').innerHTML.split(/[<>\ ]/g)
|
|
1310
|
+
);
|
|
1311
|
+
if (transform) {
|
|
1312
|
+
coord = Util._pcrsToGcrs(coord, source, dest);
|
|
1313
|
+
}
|
|
1314
|
+
j.coordinates = coord;
|
|
1315
|
+
break;
|
|
1316
|
+
case 'MAP-MULTILINESTRING':
|
|
1317
|
+
j.type = 'MultiLineString';
|
|
1318
|
+
j.coordinates = [];
|
|
1319
|
+
let i = 0;
|
|
1320
|
+
el.querySelectorAll('map-coordinates').forEach((coord) => {
|
|
1321
|
+
coord = coord.innerHTML.split(/[<>\ ]/g);
|
|
1322
|
+
coord = Util._breakArray(coord);
|
|
1323
|
+
if (transform) {
|
|
1324
|
+
coord = Util._pcrsToGcrs(coord, source, dest);
|
|
1325
|
+
}
|
|
1326
|
+
j.coordinates[i] = coord;
|
|
1327
|
+
i++;
|
|
1328
|
+
});
|
|
1329
|
+
break;
|
|
1330
|
+
case 'MAP-MULTIPOLYGON':
|
|
1331
|
+
j.type = 'MultiPolygon';
|
|
1332
|
+
j.coordinates = [];
|
|
1333
|
+
let p = 0;
|
|
1334
|
+
el.querySelectorAll('map-polygon').forEach((poly) => {
|
|
1335
|
+
let y = 0;
|
|
1336
|
+
j.coordinates.push([]);
|
|
1337
|
+
poly.querySelectorAll('map-coordinates').forEach((coord) => {
|
|
1338
|
+
coord = coord.innerHTML.split(/[<>\ ]/g);
|
|
1339
|
+
coord = Util._breakArray(coord);
|
|
1340
|
+
if (transform) {
|
|
1341
|
+
coord = Util._pcrsToGcrs(coord, source, dest);
|
|
1342
|
+
}
|
|
1343
|
+
j.coordinates[p].push([]);
|
|
1344
|
+
j.coordinates[p][y] = coord;
|
|
1345
|
+
y++;
|
|
1346
|
+
});
|
|
1347
|
+
p++;
|
|
1348
|
+
});
|
|
1349
|
+
break;
|
|
1350
|
+
}
|
|
1351
|
+
return j;
|
|
1352
|
+
},
|
|
1353
|
+
|
|
1354
|
+
// _pcrsToGcrs: arrof([x,y]) Proj4, Proj4 -> arrof[x,y]
|
|
1355
|
+
_pcrsToGcrs: function (arr, source, dest) {
|
|
1356
|
+
let newArr = [];
|
|
1357
|
+
for (let i = 0; i < arr.length; i++) {
|
|
1358
|
+
let conv = proj4.transform(source, dest, arr[i]);
|
|
1359
|
+
conv = [conv.x, conv.y];
|
|
1360
|
+
newArr.push(conv);
|
|
1361
|
+
}
|
|
1362
|
+
return newArr;
|
|
1363
|
+
},
|
|
1364
|
+
|
|
1365
|
+
// Takes an <map-layer> element and returns a geojson feature collection object
|
|
1366
|
+
// The options object can contain the following:
|
|
1367
|
+
// propertyFunction - function(<map-properties>), A function that maps the features' <map-properties> element to a GeoJSON "properties" member.
|
|
1368
|
+
// transform - Bool, Transform coordinates to gcrs values, defaults to True
|
|
1369
|
+
// mapml2geojson: <map-layer> Object -> GeoJSON
|
|
1370
|
+
mapml2geojson: function (element, options = {}) {
|
|
1371
|
+
let defaults = {
|
|
1372
|
+
propertyFunction: null,
|
|
1373
|
+
transform: true
|
|
1374
|
+
};
|
|
1375
|
+
// assign default values for undefined options
|
|
1376
|
+
options = Object.assign({}, defaults, options);
|
|
1377
|
+
|
|
1378
|
+
let json = {};
|
|
1379
|
+
json.type = 'FeatureCollection';
|
|
1380
|
+
json.title = element.getAttribute('label');
|
|
1381
|
+
json.features = [];
|
|
1382
|
+
|
|
1383
|
+
// Transforming Coordinates to gcrs if transformation = true and coordinate is not (EPSG:3857 or EPSG:4326)
|
|
1384
|
+
let source = null;
|
|
1385
|
+
let dest = null;
|
|
1386
|
+
if (options.transform) {
|
|
1387
|
+
source = new proj4.Proj(element.parentElement._map.options.crs.code);
|
|
1388
|
+
dest = new proj4.Proj('EPSG:4326');
|
|
1389
|
+
if (
|
|
1390
|
+
element.parentElement._map.options.crs.code === 'EPSG:3857' ||
|
|
1391
|
+
element.parentElement._map.options.crs.code === 'EPSG:4326'
|
|
1392
|
+
) {
|
|
1393
|
+
options.transform = false;
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
// Setting all meta settings, if any
|
|
1398
|
+
let metas = element.querySelectorAll('map-meta');
|
|
1399
|
+
metas.forEach((meta) => {
|
|
1400
|
+
let name = meta.getAttribute('name');
|
|
1401
|
+
if (name === 'extent') {
|
|
1402
|
+
let content = meta.getAttribute('content');
|
|
1403
|
+
let arr = content.split(',');
|
|
1404
|
+
let ex = {};
|
|
1405
|
+
for (let i = 0; i < arr.length; i++) {
|
|
1406
|
+
let s = arr[i].split('=');
|
|
1407
|
+
s[0] = s[0].trim(); // removing whitespace
|
|
1408
|
+
s[1] = parseFloat(s[1]);
|
|
1409
|
+
ex[s[0]] = s[1];
|
|
1410
|
+
}
|
|
1411
|
+
json.bbox = [
|
|
1412
|
+
ex['top-left-longitude'],
|
|
1413
|
+
ex['top-left-latitude'],
|
|
1414
|
+
ex['bottom-right-longitude'],
|
|
1415
|
+
ex['bottom-right-latitude']
|
|
1416
|
+
];
|
|
1417
|
+
}
|
|
1418
|
+
});
|
|
1419
|
+
|
|
1420
|
+
// Iterating over each feature
|
|
1421
|
+
let features = element.querySelectorAll('map-feature');
|
|
1422
|
+
let num = 0;
|
|
1423
|
+
|
|
1424
|
+
// Going over each feature in the layer
|
|
1425
|
+
features.forEach((feature) => {
|
|
1426
|
+
//console.log(feature);
|
|
1427
|
+
|
|
1428
|
+
json.features[num] = { type: 'Feature' };
|
|
1429
|
+
json.features[num].geometry = {};
|
|
1430
|
+
json.features[num].properties = {};
|
|
1431
|
+
|
|
1432
|
+
// setting properties when function presented
|
|
1433
|
+
if (!feature.querySelector('map-properties')) {
|
|
1434
|
+
json.features[num].properties = null;
|
|
1435
|
+
} else if (typeof options.propertyFunction === 'function') {
|
|
1436
|
+
let properties = options.propertyFunction(
|
|
1437
|
+
feature.querySelector('map-properties')
|
|
1438
|
+
);
|
|
1439
|
+
json.features[num].properties = properties;
|
|
1440
|
+
} else if (
|
|
1441
|
+
feature.querySelector('map-properties').querySelector('table') !== null
|
|
1442
|
+
) {
|
|
1443
|
+
// setting properties when table presented
|
|
1444
|
+
let table = feature
|
|
1445
|
+
.querySelector('map-properties')
|
|
1446
|
+
.querySelector('table')
|
|
1447
|
+
.cloneNode(true),
|
|
1448
|
+
properties = Util._table2properties(table);
|
|
1449
|
+
json.features[num].properties = properties;
|
|
1450
|
+
} else {
|
|
1451
|
+
// when no table present, strip any possible html tags to only get text
|
|
1452
|
+
json.features[num].properties = {
|
|
1453
|
+
prop0: feature
|
|
1454
|
+
.querySelector('map-properties')
|
|
1455
|
+
.innerHTML.replace(/(<([^>]+)>)/gi, '')
|
|
1456
|
+
};
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
let geom = feature.querySelector('map-geometry').firstElementChild;
|
|
1460
|
+
|
|
1461
|
+
// remove map-a, map-span elements if the geometry is wrapped in them
|
|
1462
|
+
while (
|
|
1463
|
+
geom.nodeName.toUpperCase() === 'MAP-SPAN' ||
|
|
1464
|
+
geom.nodeName.toUpperCase() === 'MAP-A'
|
|
1465
|
+
) {
|
|
1466
|
+
geom = geom.firstElementChild;
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
// Adding Geometry
|
|
1470
|
+
if (geom.nodeName.toUpperCase() !== 'MAP-GEOMETRYCOLLECTION') {
|
|
1471
|
+
json.features[num].geometry = Util._geometry2geojson(
|
|
1472
|
+
geom,
|
|
1473
|
+
source,
|
|
1474
|
+
dest,
|
|
1475
|
+
options.transform
|
|
1476
|
+
);
|
|
1477
|
+
} else {
|
|
1478
|
+
json.features[num].geometry.type = 'GeometryCollection';
|
|
1479
|
+
json.features[num].geometry.geometries = [];
|
|
1480
|
+
|
|
1481
|
+
let geoms = geom.children;
|
|
1482
|
+
// Collect geometry elements from within map-a/map-span wrappers
|
|
1483
|
+
// without using cloneNode (Stencil components don't clone properly)
|
|
1484
|
+
const collectGeometries = (parent) => {
|
|
1485
|
+
Array.from(parent.children).forEach((child) => {
|
|
1486
|
+
let cn = child.nodeName.toUpperCase();
|
|
1487
|
+
if (cn === 'MAP-SPAN' || cn === 'MAP-A') {
|
|
1488
|
+
collectGeometries(child);
|
|
1489
|
+
} else {
|
|
1490
|
+
let geojson = Util._geometry2geojson(
|
|
1491
|
+
child,
|
|
1492
|
+
source,
|
|
1493
|
+
dest,
|
|
1494
|
+
options.transform
|
|
1495
|
+
);
|
|
1496
|
+
json.features[num].geometry.geometries.push(geojson);
|
|
1497
|
+
}
|
|
1498
|
+
});
|
|
1499
|
+
};
|
|
1500
|
+
Array.from(geoms).forEach((g) => {
|
|
1501
|
+
let n = g.nodeName.toUpperCase();
|
|
1502
|
+
if (n === 'MAP-SPAN' || n === 'MAP-A') {
|
|
1503
|
+
collectGeometries(g);
|
|
1504
|
+
} else {
|
|
1505
|
+
g = Util._geometry2geojson(g, source, dest, options.transform);
|
|
1506
|
+
json.features[num].geometry.geometries.push(g);
|
|
1507
|
+
}
|
|
1508
|
+
});
|
|
1509
|
+
}
|
|
1510
|
+
//going to next feature
|
|
1511
|
+
num++;
|
|
1512
|
+
});
|
|
1513
|
+
|
|
1514
|
+
return json;
|
|
1515
|
+
},
|
|
1516
|
+
|
|
1517
|
+
// Takes leaflet bound, leaflet map and min and max zoom limit,
|
|
1518
|
+
// return the maximum zoom level that can show the bound completely
|
|
1519
|
+
// getMaxZoom: Bound, Map, Number, Number -> Number
|
|
1520
|
+
getMaxZoom: function (bound, map, minZoom, maxZoom) {
|
|
1521
|
+
if (!bound) return;
|
|
1522
|
+
|
|
1523
|
+
let newZoom = map.getZoom(),
|
|
1524
|
+
scale = map.options.crs.scale(newZoom),
|
|
1525
|
+
mapCenterTCRS = map.options.crs.transformation.transform(
|
|
1526
|
+
bound.getCenter(true),
|
|
1527
|
+
scale
|
|
1528
|
+
);
|
|
1529
|
+
|
|
1530
|
+
let mapHalf = map.getSize().divideBy(2),
|
|
1531
|
+
mapTlNew = mapCenterTCRS.subtract(mapHalf).round(),
|
|
1532
|
+
mapBrNew = mapCenterTCRS.add(mapHalf).round();
|
|
1533
|
+
|
|
1534
|
+
let mapTlPCRSNew = Util.pixelToPCRSPoint(
|
|
1535
|
+
mapTlNew,
|
|
1536
|
+
newZoom,
|
|
1537
|
+
map.options.projection
|
|
1538
|
+
),
|
|
1539
|
+
mapBrPCRSNew = Util.pixelToPCRSPoint(
|
|
1540
|
+
mapBrNew,
|
|
1541
|
+
newZoom,
|
|
1542
|
+
map.options.projection
|
|
1543
|
+
);
|
|
1544
|
+
|
|
1545
|
+
let mapPCRS = bounds(mapTlPCRSNew, mapBrPCRSNew),
|
|
1546
|
+
zOffset = mapPCRS.contains(bound) ? 1 : -1;
|
|
1547
|
+
|
|
1548
|
+
while (
|
|
1549
|
+
(zOffset === -1 && !mapPCRS.contains(bound) && newZoom - 1 >= minZoom) ||
|
|
1550
|
+
(zOffset === 1 && mapPCRS.contains(bound) && newZoom + 1 <= maxZoom)
|
|
1551
|
+
) {
|
|
1552
|
+
newZoom += zOffset;
|
|
1553
|
+
scale = map.options.crs.scale(newZoom);
|
|
1554
|
+
mapCenterTCRS = map.options.crs.transformation.transform(
|
|
1555
|
+
bound.getCenter(true),
|
|
1556
|
+
scale
|
|
1557
|
+
);
|
|
1558
|
+
|
|
1559
|
+
mapTlNew = mapCenterTCRS.subtract(mapHalf).round();
|
|
1560
|
+
mapBrNew = mapCenterTCRS.add(mapHalf).round();
|
|
1561
|
+
mapTlPCRSNew = Util.pixelToPCRSPoint(
|
|
1562
|
+
mapTlNew,
|
|
1563
|
+
newZoom,
|
|
1564
|
+
map.options.projection
|
|
1565
|
+
);
|
|
1566
|
+
mapBrPCRSNew = Util.pixelToPCRSPoint(
|
|
1567
|
+
mapBrNew,
|
|
1568
|
+
newZoom,
|
|
1569
|
+
map.options.projection
|
|
1570
|
+
);
|
|
1571
|
+
|
|
1572
|
+
mapPCRS = bounds(mapTlPCRSNew, mapBrPCRSNew);
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
if (
|
|
1576
|
+
zOffset === 1 &&
|
|
1577
|
+
newZoom - 1 >= 0 &&
|
|
1578
|
+
!(newZoom === maxZoom && mapPCRS.contains(bound))
|
|
1579
|
+
)
|
|
1580
|
+
newZoom--;
|
|
1581
|
+
return newZoom;
|
|
1582
|
+
},
|
|
1583
|
+
getClosest(node, selector) {
|
|
1584
|
+
if (!node) {
|
|
1585
|
+
return null;
|
|
1586
|
+
}
|
|
1587
|
+
if (node instanceof ShadowRoot) {
|
|
1588
|
+
return Util.getClosest(node.host, selector);
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
if (node instanceof HTMLElement) {
|
|
1592
|
+
if (node.matches(selector)) {
|
|
1593
|
+
return node;
|
|
1594
|
+
} else {
|
|
1595
|
+
return Util.getClosest(node.parentNode, selector);
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
return Util.getClosest(node.parentNode, selector);
|
|
1600
|
+
}
|
|
1601
|
+
};
|