@npm9912/v-map 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +185 -0
- package/dist/cjs/_commonjsHelpers-B83fTs8d.js +36 -0
- package/dist/cjs/app-globals-V2Kpy_OQ.js +5 -0
- package/dist/cjs/cesium-provider-BiFFyAl9.js +2598 -0
- package/dist/cjs/deck-provider-Ctq3Q8a1.js +47824 -0
- package/dist/cjs/geotiff-CEwvF9cG.js +47 -0
- package/dist/cjs/geotiff-source-RaNzzWkC.js +1522 -0
- package/dist/cjs/index-B1oGO1g-.js +10658 -0
- package/dist/cjs/index-B8LHqjyg.js +1765 -0
- package/dist/cjs/index-BIL4VsgP.js +310 -0
- package/dist/cjs/index-Blku2QY8.js +167 -0
- package/dist/cjs/index-CJvvX4yx.js +21 -0
- package/dist/cjs/index-CbVT-Con.js +699 -0
- package/dist/cjs/index-ISOEpMC3.js +20478 -0
- package/dist/cjs/index-JSwBbvGA.js +1621 -0
- package/dist/cjs/index.browser-DQhD8Jwl.js +6873 -0
- package/dist/cjs/index.cjs.js +2 -0
- package/dist/cjs/layer-extension-B_olS0rc.js +65 -0
- package/dist/cjs/leaflet-provider-DOqfs7g5.js +1815 -0
- package/dist/cjs/loader.cjs.js +13 -0
- package/dist/cjs/main-dist-7TykwFci.js +2655 -0
- package/dist/cjs/messages-D7h4m8Tx.js +186 -0
- package/dist/cjs/openlayers-provider-Dfeg6L4n.js +1604 -0
- package/dist/cjs/polygon-layer-B9PrN7vr.js +1300 -0
- package/dist/cjs/scenegraph-layer-DwNoxQdi.js +2530 -0
- package/dist/cjs/styleconfig-CVRqArk-.js +23 -0
- package/dist/cjs/v-map-builder.cjs.entry.js +3786 -0
- package/dist/cjs/v-map-layer-geojson_12.cjs.entry.js +40894 -0
- package/dist/cjs/v-map-layer-helper-iAzxAg9I.js +285 -0
- package/dist/cjs/v-map-layer-terrain-geotiff.cjs.entry.js +258 -0
- package/dist/cjs/v-map-layercontrol.cjs.entry.js +247 -0
- package/dist/cjs/v-map.cjs.js +25 -0
- package/dist/cjs/v-map.v-map-layer-osm.v-map-layergroup-BsXp3BoL.js +582 -0
- package/dist/cjs/v-map_3.cjs.entry.js +12 -0
- package/dist/collection/collection-manifest.json +30 -0
- package/dist/collection/components/v-map/v-map.css +3 -0
- package/dist/collection/components/v-map/v-map.js +467 -0
- package/dist/collection/components/v-map/v-map.test.js +33 -0
- package/dist/collection/components/v-map-builder/v-map-builder.css +1 -0
- package/dist/collection/components/v-map-builder/v-map-builder.js +913 -0
- package/dist/collection/components/v-map-builder/v-map-builder.test.js +56 -0
- package/dist/collection/components/v-map-layer-geojson/v-map-layer-geojson.js +862 -0
- package/dist/collection/components/v-map-layer-geojson/v-map-layer-geojson.test.js +42 -0
- package/dist/collection/components/v-map-layer-geotiff/v-map-layer-geotiff.css +4 -0
- package/dist/collection/components/v-map-layer-geotiff/v-map-layer-geotiff.js +500 -0
- package/dist/collection/components/v-map-layer-geotiff/v-map-layer-geotiff.test.js +38 -0
- package/dist/collection/components/v-map-layer-google/v-map-layer-google.css +1 -0
- package/dist/collection/components/v-map-layer-google/v-map-layer-google.js +442 -0
- package/dist/collection/components/v-map-layer-osm/error-api.test.js +108 -0
- package/dist/collection/components/v-map-layer-osm/v-map-layer-osm.css +4 -0
- package/dist/collection/components/v-map-layer-osm/v-map-layer-osm.js +311 -0
- package/dist/collection/components/v-map-layer-osm/v-map-layer-osm.test.js +36 -0
- package/dist/collection/components/v-map-layer-scatterplot/v-map-layer-scatterplot.css +1 -0
- package/dist/collection/components/v-map-layer-scatterplot/v-map-layer-scatterplot.js +305 -0
- package/dist/collection/components/v-map-layer-terrain/v-map-layer-terrain.css +3 -0
- package/dist/collection/components/v-map-layer-terrain/v-map-layer-terrain.js +548 -0
- package/dist/collection/components/v-map-layer-terrain/v-map-layer-terrain.test.js +36 -0
- package/dist/collection/components/v-map-layer-terrain-geotiff/v-map-layer-terrain-geotiff.css +3 -0
- package/dist/collection/components/v-map-layer-terrain-geotiff/v-map-layer-terrain-geotiff.js +735 -0
- package/dist/collection/components/v-map-layer-terrain-geotiff/v-map-layer-terrain-geotiff.test.js +42 -0
- package/dist/collection/components/v-map-layer-tile3d/v-map-layer-tile3d.css +3 -0
- package/dist/collection/components/v-map-layer-tile3d/v-map-layer-tile3d.js +449 -0
- package/dist/collection/components/v-map-layer-tile3d/v-map-layer-tile3d.test.js +50 -0
- package/dist/collection/components/v-map-layer-wcs/v-map-layer-wcs.css +1 -0
- package/dist/collection/components/v-map-layer-wcs/v-map-layer-wcs.js +448 -0
- package/dist/collection/components/v-map-layer-wcs/v-map-layer-wcs.test.js +39 -0
- package/dist/collection/components/v-map-layer-wfs/v-map-layer-wfs.css +1 -0
- package/dist/collection/components/v-map-layer-wfs/v-map-layer-wfs.js +489 -0
- package/dist/collection/components/v-map-layer-wfs/v-map-layer-wfs.test.js +43 -0
- package/dist/collection/components/v-map-layer-wkt/v-map-layer-wkt.css +1 -0
- package/dist/collection/components/v-map-layer-wkt/v-map-layer-wkt.js +811 -0
- package/dist/collection/components/v-map-layer-wkt/v-map-layer-wkt.test.js +34 -0
- package/dist/collection/components/v-map-layer-wms/v-map-layer-wms.css +1 -0
- package/dist/collection/components/v-map-layer-wms/v-map-layer-wms.js +453 -0
- package/dist/collection/components/v-map-layer-wms/v-map-layer-wms.test.js +36 -0
- package/dist/collection/components/v-map-layer-xyz/v-map-layer-xyz.css +1 -0
- package/dist/collection/components/v-map-layer-xyz/v-map-layer-xyz.js +331 -0
- package/dist/collection/components/v-map-layer-xyz/v-map-layer-xyz.test.js +28 -0
- package/dist/collection/components/v-map-layercontrol/v-map-layercontrol.css +74 -0
- package/dist/collection/components/v-map-layercontrol/v-map-layercontrol.js +277 -0
- package/dist/collection/components/v-map-layercontrol/v-map-layercontrol.test.js +134 -0
- package/dist/collection/components/v-map-layergroup/v-map-layergroup.css +4 -0
- package/dist/collection/components/v-map-layergroup/v-map-layergroup.js +212 -0
- package/dist/collection/components/v-map-layergroup/v-map-layergroup.test.js +39 -0
- package/dist/collection/components/v-map-style/v-map-style.css +38 -0
- package/dist/collection/components/v-map-style/v-map-style.js +492 -0
- package/dist/collection/components/v-map-style/v-map-style.unit.js +62 -0
- package/dist/collection/index.js +1 -0
- package/dist/collection/layer/v-map-layer-helper.js +281 -0
- package/dist/collection/layer/v-map-layer-helper.unit.js +234 -0
- package/dist/collection/lib/cesium-loader.js +58 -0
- package/dist/collection/lib/ensure-importmap.js +12 -0
- package/dist/collection/lib/ensure-importmap.unit.js +57 -0
- package/dist/collection/lib/versions.gen.js +6 -0
- package/dist/collection/lib/vstyle.js +8 -0
- package/dist/collection/map-provider/cesium/CesiumGeoTIFFTerrainProvider.js +285 -0
- package/dist/collection/map-provider/cesium/CesiumLayerGroups.js +159 -0
- package/dist/collection/map-provider/cesium/GeoTIFFImageryProvider.js +192 -0
- package/dist/collection/map-provider/cesium/GeoTIFFImageryProvider.test.js +57 -0
- package/dist/collection/map-provider/cesium/cesium-provider.js +1408 -0
- package/dist/collection/map-provider/cesium/i-layer.js +1 -0
- package/dist/collection/map-provider/cesium/layer-manager.js +467 -0
- package/dist/collection/map-provider/deck/DeckGLGeoTIFFLayer.js +483 -0
- package/dist/collection/map-provider/deck/DeckGLGeoTIFFTerrainLayer.js +410 -0
- package/dist/collection/map-provider/deck/LayerGroupWithModel.js +169 -0
- package/dist/collection/map-provider/deck/LayerGroups.js +192 -0
- package/dist/collection/map-provider/deck/LayerModel.js +1 -0
- package/dist/collection/map-provider/deck/RenderableGroup.js +1 -0
- package/dist/collection/map-provider/deck/deck-provider.js +1563 -0
- package/dist/collection/map-provider/geotiff/geotiff-source.js +172 -0
- package/dist/collection/map-provider/geotiff/utils/AABB2D.js +24 -0
- package/dist/collection/map-provider/geotiff/utils/BVHNode2D.js +166 -0
- package/dist/collection/map-provider/geotiff/utils/GeoTIFFTileProcessor.js +484 -0
- package/dist/collection/map-provider/geotiff/utils/Triangle.js +1 -0
- package/dist/collection/map-provider/geotiff/utils/Triangulation.js +321 -0
- package/dist/collection/map-provider/geotiff/utils/colormap-utils.js +190 -0
- package/dist/collection/map-provider/geotiff/utils/normalization-utils.js +122 -0
- package/dist/collection/map-provider/geotiff/utils/sampling-utils.js +108 -0
- package/dist/collection/map-provider/leaflet/GeoTIFFGridLayer.js +147 -0
- package/dist/collection/map-provider/leaflet/WCSGridLayer.js +124 -0
- package/dist/collection/map-provider/leaflet/google-map-tiles-layer.js +352 -0
- package/dist/collection/map-provider/leaflet/leaflet-helpers.js +94 -0
- package/dist/collection/map-provider/leaflet/leaflet-provider.js +1095 -0
- package/dist/collection/map-provider/ol/CustomGeoTiff.js +145 -0
- package/dist/collection/map-provider/ol/openlayers-helper.js +26 -0
- package/dist/collection/map-provider/ol/openlayers-provider.js +1427 -0
- package/dist/collection/map-provider/provider-factory.js +44 -0
- package/dist/collection/map-provider/provider-factory.unit.js +66 -0
- package/dist/collection/testing/browser-test-utils.js +49 -0
- package/dist/collection/testing/e2e-testing.js +122 -0
- package/dist/collection/testing/e2e-utils.js +70 -0
- package/dist/collection/testing/geotiff-test-server.js +100 -0
- package/dist/collection/testing/mocks/geostyler-lyrx-parser.js +12 -0
- package/dist/collection/testing/mocks/geostyler-mapbox-parser.js +12 -0
- package/dist/collection/testing/mocks/geostyler-qgis-parser.js +12 -0
- package/dist/collection/testing/mocks/geostyler-sld-parser.js +13 -0
- package/dist/collection/testing/mocks/geostyler-style.js +5 -0
- package/dist/collection/testing/setupTests.browser.js +1 -0
- package/dist/collection/testing/setupTests.stencil.js +20 -0
- package/dist/collection/testing/setupTests.vitest.js +59 -0
- package/dist/collection/testing/stencil-testing-wrapper.js +43 -0
- package/dist/collection/testing/styleMock.js +1 -0
- package/dist/collection/types/color.js +1 -0
- package/dist/collection/types/cssmode.js +1 -0
- package/dist/collection/types/flavour.js +1 -0
- package/dist/collection/types/layerconfig.js +1 -0
- package/dist/collection/types/lonlat.js +1 -0
- package/dist/collection/types/mapinitoptions.js +1 -0
- package/dist/collection/types/mapprovider.js +1 -0
- package/dist/collection/types/provideroptions.js +1 -0
- package/dist/collection/types/styleconfig.js +19 -0
- package/dist/collection/types/styling.js +13 -0
- package/dist/collection/types/styling.unit.js +37 -0
- package/dist/collection/types/vmaplayer.js +1 -0
- package/dist/collection/utils/async-mutex.js +28 -0
- package/dist/collection/utils/diff.js +142 -0
- package/dist/collection/utils/diff.unit.js +59 -0
- package/dist/collection/utils/dom-env.js +43 -0
- package/dist/collection/utils/dom-env.unit.js +92 -0
- package/dist/collection/utils/events.js +8 -0
- package/dist/collection/utils/logger.js +183 -0
- package/dist/collection/utils/logger.unit.js +98 -0
- package/dist/collection/utils/messages.js +12 -0
- package/dist/collection/utils/spatial-utils.js +27 -0
- package/dist/collection/utils/spatial-utils.unit.js +24 -0
- package/dist/components/_commonjsHelpers.js +1 -0
- package/dist/components/cesium-provider.js +1 -0
- package/dist/components/deck-provider.js +1 -0
- package/dist/components/events.js +1 -0
- package/dist/components/geotiff-source.js +1 -0
- package/dist/components/geotiff.js +4 -0
- package/dist/components/index.browser.js +15 -0
- package/dist/components/index.d.ts +35 -0
- package/dist/components/index.js +1 -0
- package/dist/components/index2.js +1 -0
- package/dist/components/index3.js +1 -0
- package/dist/components/index4.js +1 -0
- package/dist/components/index5.js +1 -0
- package/dist/components/index6.js +1 -0
- package/dist/components/index7.js +1 -0
- package/dist/components/index8.js +7 -0
- package/dist/components/layer-extension.js +1 -0
- package/dist/components/leaflet-provider.js +1 -0
- package/dist/components/main-dist.js +1 -0
- package/dist/components/messages.js +1 -0
- package/dist/components/openlayers-provider.js +1 -0
- package/dist/components/polygon-layer.js +1 -0
- package/dist/components/scenegraph-layer.js +1 -0
- package/dist/components/styleconfig.js +1 -0
- package/dist/components/styling.js +1 -0
- package/dist/components/v-map-builder.d.ts +11 -0
- package/dist/components/v-map-builder.js +2 -0
- package/dist/components/v-map-layer-geojson.d.ts +11 -0
- package/dist/components/v-map-layer-geojson.js +1 -0
- package/dist/components/v-map-layer-geojson2.js +1 -0
- package/dist/components/v-map-layer-geotiff.d.ts +11 -0
- package/dist/components/v-map-layer-geotiff.js +1 -0
- package/dist/components/v-map-layer-geotiff2.js +1 -0
- package/dist/components/v-map-layer-google.d.ts +11 -0
- package/dist/components/v-map-layer-google.js +1 -0
- package/dist/components/v-map-layer-google2.js +1 -0
- package/dist/components/v-map-layer-helper.js +1 -0
- package/dist/components/v-map-layer-osm.d.ts +11 -0
- package/dist/components/v-map-layer-osm.js +1 -0
- package/dist/components/v-map-layer-osm2.js +1 -0
- package/dist/components/v-map-layer-scatterplot.d.ts +11 -0
- package/dist/components/v-map-layer-scatterplot.js +1 -0
- package/dist/components/v-map-layer-scatterplot2.js +1 -0
- package/dist/components/v-map-layer-terrain-geotiff.d.ts +11 -0
- package/dist/components/v-map-layer-terrain-geotiff.js +1 -0
- package/dist/components/v-map-layer-terrain.d.ts +11 -0
- package/dist/components/v-map-layer-terrain.js +1 -0
- package/dist/components/v-map-layer-terrain2.js +1 -0
- package/dist/components/v-map-layer-tile3d.d.ts +11 -0
- package/dist/components/v-map-layer-tile3d.js +1 -0
- package/dist/components/v-map-layer-tile3d2.js +1 -0
- package/dist/components/v-map-layer-wcs.d.ts +11 -0
- package/dist/components/v-map-layer-wcs.js +1 -0
- package/dist/components/v-map-layer-wcs2.js +1 -0
- package/dist/components/v-map-layer-wfs.d.ts +11 -0
- package/dist/components/v-map-layer-wfs.js +1 -0
- package/dist/components/v-map-layer-wfs2.js +1 -0
- package/dist/components/v-map-layer-wkt.d.ts +11 -0
- package/dist/components/v-map-layer-wkt.js +1 -0
- package/dist/components/v-map-layer-wkt2.js +1 -0
- package/dist/components/v-map-layer-wms.d.ts +11 -0
- package/dist/components/v-map-layer-wms.js +1 -0
- package/dist/components/v-map-layer-wms2.js +1 -0
- package/dist/components/v-map-layer-xyz.d.ts +11 -0
- package/dist/components/v-map-layer-xyz.js +1 -0
- package/dist/components/v-map-layer-xyz2.js +1 -0
- package/dist/components/v-map-layercontrol.d.ts +11 -0
- package/dist/components/v-map-layercontrol.js +1 -0
- package/dist/components/v-map-layergroup.d.ts +11 -0
- package/dist/components/v-map-layergroup.js +1 -0
- package/dist/components/v-map-layergroup2.js +1 -0
- package/dist/components/v-map-style.d.ts +11 -0
- package/dist/components/v-map-style.js +1 -0
- package/dist/components/v-map-style2.js +10 -0
- package/dist/components/v-map.d.ts +11 -0
- package/dist/components/v-map.js +1 -0
- package/dist/components/v-map2.js +1 -0
- package/dist/esm/_commonjsHelpers-E-ZsRS8r.js +32 -0
- package/dist/esm/app-globals-DQuL1Twl.js +3 -0
- package/dist/esm/cesium-provider-BJfAup3w.js +2596 -0
- package/dist/esm/deck-provider-C7U9VDEq.js +47709 -0
- package/dist/esm/geotiff-BEWxTIfH.js +45 -0
- package/dist/esm/geotiff-source-esnDnC-u.js +1516 -0
- package/dist/esm/index-B1zwA4IC.js +685 -0
- package/dist/esm/index-BBpiaTpT.js +165 -0
- package/dist/esm/index-BIEmlzCf.js +1697 -0
- package/dist/esm/index-BUHa4Jj0.js +307 -0
- package/dist/esm/index-DbSdn93t.js +20461 -0
- package/dist/esm/index-RpJarvr_.js +10656 -0
- package/dist/esm/index-jN06TXUp.js +14 -0
- package/dist/esm/index-jzneDarq.js +1613 -0
- package/dist/esm/index.browser-DhQAXuA7.js +6860 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/layer-extension-CZXK5goK.js +63 -0
- package/dist/esm/leaflet-provider-Q41TB6ku.js +1794 -0
- package/dist/esm/loader.js +11 -0
- package/dist/esm/main-dist-CwnA7_Xn.js +2652 -0
- package/dist/esm/messages-CMKJzsgL.js +180 -0
- package/dist/esm/openlayers-provider-CMsDsQTQ.js +1602 -0
- package/dist/esm/polygon-layer-ByhxGhWC.js +1295 -0
- package/dist/esm/scenegraph-layer-09K_B6DT.js +2526 -0
- package/dist/esm/styleconfig-B-bAcABs.js +21 -0
- package/dist/esm/v-map-builder.entry.js +3784 -0
- package/dist/esm/v-map-layer-geojson_12.entry.js +40881 -0
- package/dist/esm/v-map-layer-helper-Dys44Cgo.js +283 -0
- package/dist/esm/v-map-layer-terrain-geotiff.entry.js +256 -0
- package/dist/esm/v-map-layercontrol.entry.js +245 -0
- package/dist/esm/v-map.js +21 -0
- package/dist/esm/v-map.v-map-layer-osm.v-map-layergroup-B4pFHuSf.js +572 -0
- package/dist/esm/v-map_3.entry.js +4 -0
- package/dist/index.cjs.js +1 -0
- package/dist/index.js +1 -0
- package/dist/types/cesium-augment.d.ts +5 -0
- package/dist/types/components/v-map/v-map.d.ts +70 -0
- package/dist/types/components/v-map/v-map.test.d.ts +1 -0
- package/dist/types/components/v-map-builder/v-map-builder.d.ts +48 -0
- package/dist/types/components/v-map-builder/v-map-builder.test.d.ts +1 -0
- package/dist/types/components/v-map-layer-geojson/v-map-layer-geojson.d.ts +129 -0
- package/dist/types/components/v-map-layer-geojson/v-map-layer-geojson.test.d.ts +1 -0
- package/dist/types/components/v-map-layer-geotiff/v-map-layer-geotiff.d.ts +74 -0
- package/dist/types/components/v-map-layer-geotiff/v-map-layer-geotiff.test.d.ts +1 -0
- package/dist/types/components/v-map-layer-google/v-map-layer-google.d.ts +78 -0
- package/dist/types/components/v-map-layer-osm/error-api.test.d.ts +1 -0
- package/dist/types/components/v-map-layer-osm/v-map-layer-osm.d.ts +50 -0
- package/dist/types/components/v-map-layer-osm/v-map-layer-osm.test.d.ts +1 -0
- package/dist/types/components/v-map-layer-scatterplot/v-map-layer-scatterplot.d.ts +54 -0
- package/dist/types/components/v-map-layer-terrain/v-map-layer-terrain.d.ts +74 -0
- package/dist/types/components/v-map-layer-terrain/v-map-layer-terrain.test.d.ts +1 -0
- package/dist/types/components/v-map-layer-terrain-geotiff/v-map-layer-terrain-geotiff.d.ts +117 -0
- package/dist/types/components/v-map-layer-terrain-geotiff/v-map-layer-terrain-geotiff.test.d.ts +1 -0
- package/dist/types/components/v-map-layer-tile3d/v-map-layer-tile3d.d.ts +69 -0
- package/dist/types/components/v-map-layer-tile3d/v-map-layer-tile3d.test.d.ts +1 -0
- package/dist/types/components/v-map-layer-wcs/v-map-layer-wcs.d.ts +47 -0
- package/dist/types/components/v-map-layer-wcs/v-map-layer-wcs.test.d.ts +1 -0
- package/dist/types/components/v-map-layer-wfs/v-map-layer-wfs.d.ts +59 -0
- package/dist/types/components/v-map-layer-wfs/v-map-layer-wfs.test.d.ts +1 -0
- package/dist/types/components/v-map-layer-wkt/v-map-layer-wkt.d.ts +132 -0
- package/dist/types/components/v-map-layer-wkt/v-map-layer-wkt.test.d.ts +1 -0
- package/dist/types/components/v-map-layer-wms/v-map-layer-wms.d.ts +76 -0
- package/dist/types/components/v-map-layer-wms/v-map-layer-wms.test.d.ts +1 -0
- package/dist/types/components/v-map-layer-xyz/v-map-layer-xyz.d.ts +59 -0
- package/dist/types/components/v-map-layer-xyz/v-map-layer-xyz.test.d.ts +1 -0
- package/dist/types/components/v-map-layercontrol/v-map-layercontrol.d.ts +44 -0
- package/dist/types/components/v-map-layercontrol/v-map-layercontrol.test.d.ts +1 -0
- package/dist/types/components/v-map-layergroup/v-map-layergroup.d.ts +31 -0
- package/dist/types/components/v-map-layergroup/v-map-layergroup.test.d.ts +1 -0
- package/dist/types/components/v-map-style/v-map-style.d.ts +75 -0
- package/dist/types/components/v-map-style/v-map-style.unit.d.ts +1 -0
- package/dist/types/components.d.ts +2391 -0
- package/dist/types/globals.d.ts +16 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/layer/v-map-layer-helper.d.ts +45 -0
- package/dist/types/layer/v-map-layer-helper.unit.d.ts +1 -0
- package/dist/types/leaflet-augment.d.ts +15 -0
- package/dist/types/lib/cesium-loader.d.ts +3 -0
- package/dist/types/lib/ensure-importmap.d.ts +3 -0
- package/dist/types/lib/ensure-importmap.unit.d.ts +1 -0
- package/dist/types/lib/versions.gen.d.ts +5 -0
- package/dist/types/lib/vstyle.d.ts +44 -0
- package/dist/types/map-provider/cesium/CesiumGeoTIFFTerrainProvider.d.ts +92 -0
- package/dist/types/map-provider/cesium/CesiumLayerGroups.d.ts +64 -0
- package/dist/types/map-provider/cesium/GeoTIFFImageryProvider.d.ts +75 -0
- package/dist/types/map-provider/cesium/GeoTIFFImageryProvider.test.d.ts +1 -0
- package/dist/types/map-provider/cesium/cesium-provider.d.ts +87 -0
- package/dist/types/map-provider/cesium/i-layer.d.ts +11 -0
- package/dist/types/map-provider/cesium/layer-manager.d.ts +31 -0
- package/dist/types/map-provider/deck/DeckGLGeoTIFFLayer.d.ts +91 -0
- package/dist/types/map-provider/deck/DeckGLGeoTIFFTerrainLayer.d.ts +82 -0
- package/dist/types/map-provider/deck/LayerGroupWithModel.d.ts +55 -0
- package/dist/types/map-provider/deck/LayerGroups.d.ts +63 -0
- package/dist/types/map-provider/deck/LayerModel.d.ts +8 -0
- package/dist/types/map-provider/deck/RenderableGroup.d.ts +20 -0
- package/dist/types/map-provider/deck/deck-provider.d.ts +92 -0
- package/dist/types/map-provider/geotiff/geotiff-source.d.ts +30 -0
- package/dist/types/map-provider/geotiff/utils/AABB2D.d.ts +28 -0
- package/dist/types/map-provider/geotiff/utils/BVHNode2D.d.ts +36 -0
- package/dist/types/map-provider/geotiff/utils/GeoTIFFTileProcessor.d.ts +116 -0
- package/dist/types/map-provider/geotiff/utils/Triangle.d.ts +5 -0
- package/dist/types/map-provider/geotiff/utils/Triangulation.d.ts +94 -0
- package/dist/types/map-provider/geotiff/utils/colormap-utils.d.ts +47 -0
- package/dist/types/map-provider/geotiff/utils/normalization-utils.d.ts +39 -0
- package/dist/types/map-provider/geotiff/utils/sampling-utils.d.ts +13 -0
- package/dist/types/map-provider/leaflet/GeoTIFFGridLayer.d.ts +34 -0
- package/dist/types/map-provider/leaflet/WCSGridLayer.d.ts +38 -0
- package/dist/types/map-provider/leaflet/google-map-tiles-layer.d.ts +73 -0
- package/dist/types/map-provider/leaflet/leaflet-helpers.d.ts +6 -0
- package/dist/types/map-provider/leaflet/leaflet-provider.d.ts +73 -0
- package/dist/types/map-provider/ol/CustomGeoTiff.d.ts +14 -0
- package/dist/types/map-provider/ol/openlayers-helper.d.ts +2 -0
- package/dist/types/map-provider/ol/openlayers-provider.d.ts +80 -0
- package/dist/types/map-provider/provider-factory.d.ts +12 -0
- package/dist/types/map-provider/provider-factory.unit.d.ts +1 -0
- package/dist/types/namespaces.d.ts +3 -0
- package/dist/types/ol-augment.d.ts +3 -0
- package/dist/types/ol-override.d.ts +7 -0
- package/dist/types/ol.d.ts +10 -0
- package/dist/types/stencil-public-runtime.d.ts +1860 -0
- package/dist/types/testing/browser-test-utils.d.ts +6 -0
- package/dist/types/testing/e2e-testing.d.ts +5 -0
- package/dist/types/testing/e2e-utils.d.ts +4 -0
- package/dist/types/testing/geotiff-test-server.d.ts +5 -0
- package/dist/types/testing/mocks/geostyler-lyrx-parser.d.ts +11 -0
- package/dist/types/testing/mocks/geostyler-mapbox-parser.d.ts +11 -0
- package/dist/types/testing/mocks/geostyler-qgis-parser.d.ts +11 -0
- package/dist/types/testing/mocks/geostyler-sld-parser.d.ts +11 -0
- package/dist/types/testing/mocks/geostyler-style.d.ts +5 -0
- package/dist/types/testing/setupTests.browser.d.ts +1 -0
- package/dist/types/testing/setupTests.stencil.d.ts +1 -0
- package/dist/types/testing/setupTests.vitest.d.ts +1 -0
- package/dist/types/testing/stencil-testing-wrapper.d.ts +3 -0
- package/dist/types/types/color.d.ts +1 -0
- package/dist/types/types/cssmode.d.ts +1 -0
- package/dist/types/types/flavour.d.ts +1 -0
- package/dist/types/types/layerconfig.d.ts +207 -0
- package/dist/types/types/lonlat.d.ts +1 -0
- package/dist/types/types/mapinitoptions.d.ts +4 -0
- package/dist/types/types/mapprovider.d.ts +46 -0
- package/dist/types/types/provideroptions.d.ts +8 -0
- package/dist/types/types/styleconfig.d.ts +27 -0
- package/dist/types/types/styling.d.ts +24 -0
- package/dist/types/types/styling.unit.d.ts +1 -0
- package/dist/types/types/vmaplayer.d.ts +10 -0
- package/dist/types/utils/async-mutex.d.ts +7 -0
- package/dist/types/utils/diff.d.ts +64 -0
- package/dist/types/utils/diff.unit.d.ts +1 -0
- package/dist/types/utils/dom-env.d.ts +5 -0
- package/dist/types/utils/dom-env.unit.d.ts +1 -0
- package/dist/types/utils/events.d.ts +29 -0
- package/dist/types/utils/logger.d.ts +47 -0
- package/dist/types/utils/logger.unit.d.ts +1 -0
- package/dist/types/utils/messages.d.ts +12 -0
- package/dist/types/utils/spatial-utils.d.ts +6 -0
- package/dist/types/utils/spatial-utils.unit.d.ts +1 -0
- package/dist/types/versions.d.ts +7 -0
- package/dist/v-map/index.esm.js +0 -0
- package/dist/v-map/p--vVleK-M.js +1 -0
- package/dist/v-map/p-09d10db0.entry.js +1 -0
- package/dist/v-map/p-5eba6058.entry.js +10 -0
- package/dist/v-map/p-6b102336.entry.js +1 -0
- package/dist/v-map/p-B-bAcABs.js +1 -0
- package/dist/v-map/p-BBpiaTpT.js +1 -0
- package/dist/v-map/p-BdijL4Av.js +1 -0
- package/dist/v-map/p-Be3r33VF.js +4 -0
- package/dist/v-map/p-BeFu0ap4.js +1 -0
- package/dist/v-map/p-BxFJezdK.js +1 -0
- package/dist/v-map/p-CMKJzsgL.js +1 -0
- package/dist/v-map/p-CXfA_q8m.js +1 -0
- package/dist/v-map/p-CZqY0yW4.js +1 -0
- package/dist/v-map/p-CafTHT9i.js +1 -0
- package/dist/v-map/p-DCTHyf58.js +1 -0
- package/dist/v-map/p-DQuL1Twl.js +1 -0
- package/dist/v-map/p-DR9McdNX.js +1 -0
- package/dist/v-map/p-Dckgonw8.js +1 -0
- package/dist/v-map/p-DhQAXuA7.js +15 -0
- package/dist/v-map/p-DmICdG34.js +7 -0
- package/dist/v-map/p-DrOQ9V4h.js +1 -0
- package/dist/v-map/p-DvHXtWUg.js +1 -0
- package/dist/v-map/p-E-ZsRS8r.js +1 -0
- package/dist/v-map/p-MyTSFnEk.js +1 -0
- package/dist/v-map/p-RpJarvr_.js +1 -0
- package/dist/v-map/p-WaMDUuAz.js +1 -0
- package/dist/v-map/p-aa410e64.entry.js +2 -0
- package/dist/v-map/p-c21c93fe.entry.js +1 -0
- package/dist/v-map/p-jzneDarq.js +2 -0
- package/dist/v-map/p-uiIP-taz.js +1 -0
- package/dist/v-map/v-map.esm.js +1 -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 +193 -0
|
@@ -0,0 +1,1602 @@
|
|
|
1
|
+
import Map from 'ol/Map';
|
|
2
|
+
import View from 'ol/View';
|
|
3
|
+
import VectorLayer from 'ol/layer/Vector';
|
|
4
|
+
import LayerGroup from 'ol/layer/Group';
|
|
5
|
+
import TileLayer from 'ol/layer/Tile';
|
|
6
|
+
import ImageLayer from 'ol/layer/Image';
|
|
7
|
+
import VectorSource from 'ol/source/Vector';
|
|
8
|
+
import TileWMS from 'ol/source/TileWMS';
|
|
9
|
+
import OSM from 'ol/source/OSM';
|
|
10
|
+
import XYZ from 'ol/source/XYZ';
|
|
11
|
+
import Google from 'ol/source/Google';
|
|
12
|
+
import TileArcGISRest from 'ol/source/TileArcGISRest';
|
|
13
|
+
import OlImageWrapper from 'ol/Image';
|
|
14
|
+
import ImageSource from 'ol/source/Image';
|
|
15
|
+
import GeoJSON from 'ol/format/GeoJSON';
|
|
16
|
+
import GML2 from 'ol/format/GML2';
|
|
17
|
+
import GML3 from 'ol/format/GML3';
|
|
18
|
+
import GML32 from 'ol/format/GML32';
|
|
19
|
+
import WKT from 'ol/format/WKT';
|
|
20
|
+
import Control from 'ol/control/Control';
|
|
21
|
+
import OlStyle from 'ol/style/Style';
|
|
22
|
+
import OlFill from 'ol/style/Fill';
|
|
23
|
+
import OlStroke from 'ol/style/Stroke';
|
|
24
|
+
import OlCircle from 'ol/style/Circle';
|
|
25
|
+
import OlIcon from 'ol/style/Icon';
|
|
26
|
+
import OlText from 'ol/style/Text';
|
|
27
|
+
import { bbox } from 'ol/loadingstrategy';
|
|
28
|
+
import { get, fromLonLat } from 'ol/proj';
|
|
29
|
+
import { D as DEFAULT_STYLE } from './styleconfig-B-bAcABs.js';
|
|
30
|
+
import { w as warn, e as error, l as log } from './messages-CMKJzsgL.js';
|
|
31
|
+
import { O as OL_VERSION } from './v-map.v-map-layer-osm.v-map-layergroup-B4pFHuSf.js';
|
|
32
|
+
import proj4 from './index-RpJarvr_.js';
|
|
33
|
+
import GeoTIFF from 'ol/source/GeoTIFF';
|
|
34
|
+
import { g as geokeysToProj4 } from './main-dist-CwnA7_Xn.js';
|
|
35
|
+
import { register } from 'ol/proj/proj4';
|
|
36
|
+
import WebGLTileLayer from 'ol/layer/WebGLTile';
|
|
37
|
+
import './index-jzneDarq.js';
|
|
38
|
+
import './v-map-layer-helper-Dys44Cgo.js';
|
|
39
|
+
import './_commonjsHelpers-E-ZsRS8r.js';
|
|
40
|
+
|
|
41
|
+
/** CSS in ShadowRoot injizieren – ohne '?inline', kompatibel zu Stencil/Rollup */
|
|
42
|
+
async function injectOlCss(shadowRoot) {
|
|
43
|
+
if (!shadowRoot)
|
|
44
|
+
return;
|
|
45
|
+
const id = 'ol-css-sheet';
|
|
46
|
+
// Doppeltes Einfügen vermeiden
|
|
47
|
+
if (shadowRoot.querySelector(`style[data-id="${id}"]`))
|
|
48
|
+
return;
|
|
49
|
+
const url = `https://cdn.jsdelivr.net/npm/ol@${OL_VERSION}/ol.css`;
|
|
50
|
+
const css = await (await fetch(url)).text();
|
|
51
|
+
if ('adoptedStyleSheets' in Document.prototype) {
|
|
52
|
+
const sheet = new CSSStyleSheet();
|
|
53
|
+
await sheet.replace(css);
|
|
54
|
+
shadowRoot.adoptedStyleSheets = [
|
|
55
|
+
...(shadowRoot.adoptedStyleSheets ?? []),
|
|
56
|
+
sheet,
|
|
57
|
+
];
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
const style = document.createElement('style');
|
|
61
|
+
style.setAttribute('data-id', id);
|
|
62
|
+
style.textContent = css;
|
|
63
|
+
shadowRoot.appendChild(style);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// let projectionHelpersPromise: Promise<ProjectionHelpers> | null = null;
|
|
68
|
+
// async function loadProjectionHelpers(): Promise<ProjectionHelpers> {
|
|
69
|
+
// if (!projectionHelpersPromise) {
|
|
70
|
+
// projectionHelpersPromise = Promise.all([
|
|
71
|
+
// import('ol/proj'),
|
|
72
|
+
// import('ol/proj/proj4'),
|
|
73
|
+
// ]).then(([projModule, proj4Module]) => ({
|
|
74
|
+
// getProjection: getProjection,
|
|
75
|
+
// register: register,
|
|
76
|
+
// }));
|
|
77
|
+
// }
|
|
78
|
+
// return projectionHelpersPromise;
|
|
79
|
+
// }
|
|
80
|
+
async function createCustomGeoTiff(options) {
|
|
81
|
+
/**
|
|
82
|
+
* Gibt die GeoKeys eines GeoTIFF-Bildes zurück.
|
|
83
|
+
* @param image Das GeoTIFF-Bild.
|
|
84
|
+
* @returns Die GeoKeys oder `null`, falls keine vorhanden sind.
|
|
85
|
+
*/
|
|
86
|
+
function getGeoKeys(image) {
|
|
87
|
+
if (typeof image.getGeoKeys === 'function') {
|
|
88
|
+
return image.getGeoKeys() || null;
|
|
89
|
+
}
|
|
90
|
+
return image.geoKeys || null;
|
|
91
|
+
}
|
|
92
|
+
return class CustomGeoTiff extends GeoTIFF {
|
|
93
|
+
geoKeys_ = null;
|
|
94
|
+
constructor() {
|
|
95
|
+
super(options);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Gibt die GeoKeys der ersten Quelle zurück.
|
|
99
|
+
* @returns Ein Promise, das die GeoKeys oder `null` zurückgibt.
|
|
100
|
+
*/
|
|
101
|
+
async getGeoKeys() {
|
|
102
|
+
if (this.geoKeys_ !== null) {
|
|
103
|
+
return this.geoKeys_;
|
|
104
|
+
}
|
|
105
|
+
await this.getView();
|
|
106
|
+
//const sources = this.sources_;
|
|
107
|
+
// @ts-expect-error Zugriff auf private Eigenschaft `sourceImagery_`
|
|
108
|
+
const sources = this.sourceImagery_;
|
|
109
|
+
if (sources && sources.length > 0) {
|
|
110
|
+
this.determineGeoKeys(sources);
|
|
111
|
+
}
|
|
112
|
+
return this.geoKeys_;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Bestimmt die GeoKeys aus den Quellen.
|
|
116
|
+
* @param sources Die Quellen des GeoTIFFs.
|
|
117
|
+
*/
|
|
118
|
+
determineGeoKeys(sources) {
|
|
119
|
+
if (!sources || sources.length === 0) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const firstSource = sources[0];
|
|
123
|
+
for (let i = firstSource.length - 1; i >= 0; --i) {
|
|
124
|
+
const image = firstSource[i];
|
|
125
|
+
const geoKeys = getGeoKeys(image);
|
|
126
|
+
if (geoKeys) {
|
|
127
|
+
this.geoKeys_ = geoKeys;
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Gibt die Proj4-Projektionsparameter basierend auf den GeoKeys zurück.
|
|
134
|
+
* @returns Ein Promise, das die Proj4-Projektionsparameter oder `null` zurückgibt.
|
|
135
|
+
*/
|
|
136
|
+
async getProjectionParameters() {
|
|
137
|
+
const geoKeys = await this.getGeoKeys();
|
|
138
|
+
if (!geoKeys) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
return geokeysToProj4.toProj4(geoKeys);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Gibt die Proj4-Projektion als String basierend auf den GeoKeys zurück.
|
|
145
|
+
* @returns Ein Promise, das die Proj4-Projektion als String oder `null` zurückgibt.
|
|
146
|
+
*/
|
|
147
|
+
async getProj4String() {
|
|
148
|
+
const params = await this.getProjectionParameters();
|
|
149
|
+
if (!params) {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
// Proj4-String aus den Parametern erstellen
|
|
153
|
+
return params.proj4 || null;
|
|
154
|
+
}
|
|
155
|
+
// /**
|
|
156
|
+
// * Registriert die Proj4-Projektion in OpenLayers, falls sie noch nicht existiert.
|
|
157
|
+
// * @param proj4String Die Proj4-Projektion als String.
|
|
158
|
+
// * @param code Der Code für die Projektion (z. B. 'CUSTOM:1234').
|
|
159
|
+
// * @returns Die OpenLayers-Projektion oder `null`, falls die Registrierung fehlschlägt.
|
|
160
|
+
// */
|
|
161
|
+
// public async registerProjectionIfNeeded(
|
|
162
|
+
// proj4String: string,
|
|
163
|
+
// code: string,
|
|
164
|
+
// ): Promise<import('ol/proj').Projection | null> {
|
|
165
|
+
// try {
|
|
166
|
+
// const existingProjection = getProjection(code);
|
|
167
|
+
// if (existingProjection) {
|
|
168
|
+
// return existingProjection;
|
|
169
|
+
// }
|
|
170
|
+
// proj4.defs(code, proj4String);
|
|
171
|
+
// register(proj4);
|
|
172
|
+
// return getProjection(code);
|
|
173
|
+
// } catch (err) {
|
|
174
|
+
// error('Fehler bei der Registrierung der Projektion:', err);
|
|
175
|
+
// return null;
|
|
176
|
+
// }
|
|
177
|
+
// }
|
|
178
|
+
/**
|
|
179
|
+
* Registriert die Proj4-Projektion in OpenLayers, falls sie noch nicht existiert.
|
|
180
|
+
* @returns Die OpenLayers-Projektion oder `null`, falls die Registrierung fehlschlägt.
|
|
181
|
+
*/
|
|
182
|
+
async registerProjectionIfNeeded() {
|
|
183
|
+
try {
|
|
184
|
+
//const { getProjection, register } = await loadProjectionHelpers();
|
|
185
|
+
const proj4String = await this.getProj4String();
|
|
186
|
+
const code = this.getProjection()?.getCode();
|
|
187
|
+
const existingProjection = get(code);
|
|
188
|
+
if (existingProjection) {
|
|
189
|
+
return existingProjection;
|
|
190
|
+
}
|
|
191
|
+
if (proj4String === null) {
|
|
192
|
+
warn(`Can not get proj string for code: ${code}`);
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
proj4.defs(code, proj4String);
|
|
196
|
+
register(proj4);
|
|
197
|
+
return get(code);
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
error('Fehler bei der Registrierung der Projektion:', err);
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
class OpenLayersProvider {
|
|
208
|
+
map;
|
|
209
|
+
layers = [];
|
|
210
|
+
baseLayers = [];
|
|
211
|
+
googleLogoAdded = false;
|
|
212
|
+
projection = 'EPSG:3857';
|
|
213
|
+
layerErrorCallbacks = new globalThis.Map();
|
|
214
|
+
layerErrorCleanups = new globalThis.Map();
|
|
215
|
+
async init(options) {
|
|
216
|
+
await injectOlCss(options.shadowRoot);
|
|
217
|
+
Object.assign(options.target.style, {
|
|
218
|
+
width: '100%',
|
|
219
|
+
height: '100%',
|
|
220
|
+
position: 'relative',
|
|
221
|
+
background: '#fff',
|
|
222
|
+
});
|
|
223
|
+
this.map = new Map({
|
|
224
|
+
target: options.target,
|
|
225
|
+
// layers: [new TileLayer({ source: new OSM() })],
|
|
226
|
+
layers: [],
|
|
227
|
+
view: new View({
|
|
228
|
+
projection: this.projection,
|
|
229
|
+
center: fromLonLat(options?.mapInitOptions?.center ?? [0, 0]),
|
|
230
|
+
zoom: options?.mapInitOptions?.zoom ?? 2,
|
|
231
|
+
}),
|
|
232
|
+
});
|
|
233
|
+
new ResizeObserver(() => this.map?.updateSize()).observe(options.target);
|
|
234
|
+
}
|
|
235
|
+
async destroy() {
|
|
236
|
+
this.map?.setTarget(undefined);
|
|
237
|
+
this.map = undefined;
|
|
238
|
+
}
|
|
239
|
+
async updateLayer(layerId, update) {
|
|
240
|
+
const layer = await this._getLayerById(layerId);
|
|
241
|
+
switch (update.type) {
|
|
242
|
+
case 'geojson':
|
|
243
|
+
await this.updateGeoJSONLayer(layer, update.data);
|
|
244
|
+
break;
|
|
245
|
+
case 'osm':
|
|
246
|
+
await this.updateOSMLayer(layer, update.data);
|
|
247
|
+
break;
|
|
248
|
+
case 'wms':
|
|
249
|
+
await this.updateWMSLayer(layer, update.data);
|
|
250
|
+
break;
|
|
251
|
+
case 'wfs':
|
|
252
|
+
await this.updateWFSLayer(layer, update.data);
|
|
253
|
+
break;
|
|
254
|
+
case 'wcs':
|
|
255
|
+
await this.updateWCSLayer(layer, update.data);
|
|
256
|
+
break;
|
|
257
|
+
case 'arcgis':
|
|
258
|
+
await this.updateArcGISLayer(layer, update.data);
|
|
259
|
+
break;
|
|
260
|
+
case 'wkt':
|
|
261
|
+
await this.updateWKTLayer(layer, update.data);
|
|
262
|
+
break;
|
|
263
|
+
case 'geotiff':
|
|
264
|
+
await this.updateGeoTIFFLayer(layer, update.data);
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
async ensureGroup(groupId, visible, _opts) {
|
|
269
|
+
await this._ensureGroup(groupId, visible);
|
|
270
|
+
}
|
|
271
|
+
async _ensureGroup(groupId, visible) {
|
|
272
|
+
if (!this.map) {
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
let group = this.layers.find(l => l.get?.('groupId') === groupId);
|
|
276
|
+
if (!group) {
|
|
277
|
+
group = new LayerGroup({
|
|
278
|
+
layers: [],
|
|
279
|
+
properties: {
|
|
280
|
+
groupId: groupId,
|
|
281
|
+
visible: typeof visible !== undefined ? visible : true,
|
|
282
|
+
},
|
|
283
|
+
});
|
|
284
|
+
this.map.addLayer(group);
|
|
285
|
+
this.layers.push(group);
|
|
286
|
+
}
|
|
287
|
+
return group;
|
|
288
|
+
}
|
|
289
|
+
async setBaseLayer(groupId, layerElementId) {
|
|
290
|
+
if (layerElementId === null) {
|
|
291
|
+
log('ol - setBaseLayer - layerElementId is null.');
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
const group = this.layers.find(l => l.get?.('groupId') === groupId);
|
|
295
|
+
const layer = this.baseLayers.find(l => l.get('layerElementId') === layerElementId);
|
|
296
|
+
if (layer === undefined) {
|
|
297
|
+
log('ol - setBaseLayer - layer not found. layerElementId: ' +
|
|
298
|
+
layerElementId);
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
group.getLayers().clear();
|
|
302
|
+
group.getLayers().push(layer);
|
|
303
|
+
//group.set('layerId', layerId, false);
|
|
304
|
+
}
|
|
305
|
+
async addBaseLayer(layerConfig, basemapid, layerElementId) {
|
|
306
|
+
if (layerElementId === undefined || layerElementId === null) {
|
|
307
|
+
log('ol - addBaseLayer - layerElementId not set.');
|
|
308
|
+
return null;
|
|
309
|
+
}
|
|
310
|
+
if (basemapid === undefined || basemapid === null) {
|
|
311
|
+
log('ol - addBaseLayer - basemapid not set.');
|
|
312
|
+
}
|
|
313
|
+
const group = await this._ensureGroup(layerConfig.groupId, layerConfig.groupVisible);
|
|
314
|
+
if (group == null) {
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
317
|
+
group.set('basemap', true, false);
|
|
318
|
+
const layer = await this.createLayer(layerConfig);
|
|
319
|
+
if (layer == null) {
|
|
320
|
+
return null;
|
|
321
|
+
}
|
|
322
|
+
layer.set('group', group);
|
|
323
|
+
this.baseLayers.push(layer);
|
|
324
|
+
let layerId = null;
|
|
325
|
+
if (layer) {
|
|
326
|
+
layerId = crypto.randomUUID();
|
|
327
|
+
layer.set('id', layerId, false);
|
|
328
|
+
layer.set('layerElementId', layerElementId, false);
|
|
329
|
+
const common = layerConfig;
|
|
330
|
+
if (common.opacity !== undefined) {
|
|
331
|
+
layer.setOpacity(common.opacity);
|
|
332
|
+
}
|
|
333
|
+
if (common.zIndex !== undefined) {
|
|
334
|
+
layer.setZIndex(common.zIndex);
|
|
335
|
+
}
|
|
336
|
+
if (common.visible) {
|
|
337
|
+
layer.setVisible(true);
|
|
338
|
+
}
|
|
339
|
+
else if (common.visible === false) {
|
|
340
|
+
layer.setVisible(false);
|
|
341
|
+
}
|
|
342
|
+
if (basemapid === layerElementId) {
|
|
343
|
+
group.getLayers().clear();
|
|
344
|
+
group.getLayers().push(layer);
|
|
345
|
+
//group.set('layerId', layerId, false);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return layerId;
|
|
349
|
+
}
|
|
350
|
+
async addLayerToGroup(layerConfig) {
|
|
351
|
+
const group = await this._ensureGroup(layerConfig.groupId, layerConfig.groupVisible);
|
|
352
|
+
if (group == null) {
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
const layer = await this.createLayer(layerConfig);
|
|
356
|
+
if (layer === null) {
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
layer.set('group', group);
|
|
360
|
+
group.getLayers().push(layer);
|
|
361
|
+
const layerId = crypto.randomUUID();
|
|
362
|
+
layer.set('id', layerId, false);
|
|
363
|
+
const common = layerConfig;
|
|
364
|
+
if (common.opacity !== undefined) {
|
|
365
|
+
layer.setOpacity(common.opacity);
|
|
366
|
+
}
|
|
367
|
+
if (common.zIndex !== undefined) {
|
|
368
|
+
layer.setZIndex(common.zIndex);
|
|
369
|
+
}
|
|
370
|
+
if (common.visible) {
|
|
371
|
+
layer.setVisible(true);
|
|
372
|
+
}
|
|
373
|
+
else if (common.visible === false) {
|
|
374
|
+
layer.setVisible(false);
|
|
375
|
+
}
|
|
376
|
+
return layerId;
|
|
377
|
+
}
|
|
378
|
+
async createLayer(layerConfig) {
|
|
379
|
+
switch (layerConfig.type) {
|
|
380
|
+
case 'geojson':
|
|
381
|
+
return this.createGeoJSONLayer(layerConfig);
|
|
382
|
+
case 'xyz':
|
|
383
|
+
return this.createXYZLayer(layerConfig);
|
|
384
|
+
case 'google':
|
|
385
|
+
return this.createGoogleLayer(layerConfig);
|
|
386
|
+
case 'osm':
|
|
387
|
+
return this.createOSMLayer(layerConfig);
|
|
388
|
+
case 'wms':
|
|
389
|
+
return this.createWMSLayer(layerConfig);
|
|
390
|
+
case 'wfs':
|
|
391
|
+
return this.createWFSLayer(layerConfig);
|
|
392
|
+
case 'wcs':
|
|
393
|
+
return this.createWCSLayer(layerConfig);
|
|
394
|
+
case 'arcgis':
|
|
395
|
+
return this.createArcGISLayer(layerConfig);
|
|
396
|
+
case 'wkt':
|
|
397
|
+
return this.createWKTLayer(layerConfig);
|
|
398
|
+
case 'geotiff':
|
|
399
|
+
return this.createGeoTIFFLayer(layerConfig);
|
|
400
|
+
default:
|
|
401
|
+
throw new Error(`Unsupported layer type: ${layerConfig.type}`);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
async updateWMSLayer(layer, data) {
|
|
405
|
+
layer.setSource(new TileWMS({
|
|
406
|
+
url: data.url,
|
|
407
|
+
params: {
|
|
408
|
+
LAYERS: data.layers,
|
|
409
|
+
TILED: true,
|
|
410
|
+
...(data.extraParams ?? {}),
|
|
411
|
+
},
|
|
412
|
+
}));
|
|
413
|
+
}
|
|
414
|
+
async updateOSMLayer(layer, data) {
|
|
415
|
+
let url = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png';
|
|
416
|
+
if (data.url) {
|
|
417
|
+
url = data.url + '/{z}/{x}/{y}.png';
|
|
418
|
+
}
|
|
419
|
+
layer.setSource(new OSM({
|
|
420
|
+
url: url,
|
|
421
|
+
}));
|
|
422
|
+
}
|
|
423
|
+
async updateGeoJSONLayer(layer, data) {
|
|
424
|
+
let vectorSource = null;
|
|
425
|
+
const geojsonOptions = {
|
|
426
|
+
featureProjection: this.projection,
|
|
427
|
+
};
|
|
428
|
+
if (data.geojson) {
|
|
429
|
+
const geojsonObject = JSON.parse(data.geojson);
|
|
430
|
+
vectorSource = new VectorSource({
|
|
431
|
+
features: new GeoJSON(geojsonOptions).readFeatures(geojsonObject),
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
else {
|
|
435
|
+
vectorSource = new VectorSource({
|
|
436
|
+
url: data.url,
|
|
437
|
+
format: new GeoJSON(geojsonOptions),
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
layer.setSource(vectorSource);
|
|
441
|
+
let layerStyle;
|
|
442
|
+
if (data.geostylerStyle) {
|
|
443
|
+
layerStyle = await this.createGeostylerStyleFunction(data.geostylerStyle);
|
|
444
|
+
}
|
|
445
|
+
else if (data.style) {
|
|
446
|
+
layerStyle = await this.createEnhancedStyleFunction(data.style);
|
|
447
|
+
}
|
|
448
|
+
if (layerStyle) {
|
|
449
|
+
layer.setStyle(layerStyle);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
async updateWFSLayer(layer, data) {
|
|
453
|
+
const merged = this.mergeLayerConfig(layer, 'wfsConfig', data);
|
|
454
|
+
const vectorSource = await this.createWFSSpource(merged);
|
|
455
|
+
layer.setSource(vectorSource);
|
|
456
|
+
// Apply style if provided
|
|
457
|
+
let layerStyle;
|
|
458
|
+
if (merged.geostylerStyle) {
|
|
459
|
+
layerStyle = await this.createGeostylerStyleFunction(merged.geostylerStyle);
|
|
460
|
+
}
|
|
461
|
+
else if (merged.style) {
|
|
462
|
+
layerStyle = await this.createEnhancedStyleFunction(merged.style);
|
|
463
|
+
}
|
|
464
|
+
if (layerStyle) {
|
|
465
|
+
layer.setStyle(layerStyle);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
async updateWCSLayer(layer, data) {
|
|
469
|
+
const merged = this.mergeLayerConfig(layer, 'wcsConfig', data);
|
|
470
|
+
const source = await this.createWcsSource(merged);
|
|
471
|
+
layer.setSource(source);
|
|
472
|
+
}
|
|
473
|
+
async updateArcGISLayer(layer, data) {
|
|
474
|
+
const tileLayer = layer;
|
|
475
|
+
const currentSource = tileLayer.getSource();
|
|
476
|
+
const params = {
|
|
477
|
+
...(currentSource?.getParams?.() ?? {}),
|
|
478
|
+
...(data?.params ?? {}),
|
|
479
|
+
};
|
|
480
|
+
if (data?.token) {
|
|
481
|
+
params.token = data.token;
|
|
482
|
+
}
|
|
483
|
+
const sourceOptions = {
|
|
484
|
+
url: data?.url ??
|
|
485
|
+
currentSource?.getUrls?.()?.[0],
|
|
486
|
+
params,
|
|
487
|
+
...(data?.options ?? {}),
|
|
488
|
+
};
|
|
489
|
+
const arcgisSource = new TileArcGISRest(sourceOptions);
|
|
490
|
+
tileLayer.setSource(arcgisSource);
|
|
491
|
+
}
|
|
492
|
+
async createEnhancedStyleFunction(style) {
|
|
493
|
+
// Helper method to apply opacity to colors
|
|
494
|
+
function applyOpacity(color, opacity) {
|
|
495
|
+
if (color.startsWith('rgba')) {
|
|
496
|
+
// Extract rgb values and apply new opacity
|
|
497
|
+
const rgbMatch = color.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
|
|
498
|
+
if (rgbMatch) {
|
|
499
|
+
const [, r, g, b] = rgbMatch;
|
|
500
|
+
return `rgba(${r}, ${g}, ${b}, ${opacity})`;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
else if (color.startsWith('rgb')) {
|
|
504
|
+
const rgbMatch = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
|
|
505
|
+
if (rgbMatch) {
|
|
506
|
+
const [, r, g, b] = rgbMatch;
|
|
507
|
+
return `rgba(${r}, ${g}, ${b}, ${opacity})`;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
else if (color.startsWith('#')) {
|
|
511
|
+
// Convert hex to rgba
|
|
512
|
+
const hex = color.slice(1);
|
|
513
|
+
const r = parseInt(hex.slice(0, 2), 16);
|
|
514
|
+
const g = parseInt(hex.slice(2, 4), 16);
|
|
515
|
+
const b = parseInt(hex.slice(4, 6), 16);
|
|
516
|
+
return `rgba(${r}, ${g}, ${b}, ${opacity})`;
|
|
517
|
+
}
|
|
518
|
+
return color; // Return original if can't parse
|
|
519
|
+
}
|
|
520
|
+
return (feature) => {
|
|
521
|
+
const styles = [];
|
|
522
|
+
const geometry = feature.getGeometry();
|
|
523
|
+
const geometryType = geometry.getType();
|
|
524
|
+
// Create fill style
|
|
525
|
+
const fillColor = style.fillColor ?? 'rgba(0,100,255,0.3)';
|
|
526
|
+
const fillOpacity = style.fillOpacity ?? 0.3;
|
|
527
|
+
const fill = new OlFill({
|
|
528
|
+
color: applyOpacity(fillColor, fillOpacity),
|
|
529
|
+
});
|
|
530
|
+
// Create stroke style
|
|
531
|
+
const strokeColor = style.strokeColor ?? 'rgba(0,100,255,1)';
|
|
532
|
+
const strokeOpacity = style.strokeOpacity ?? 1;
|
|
533
|
+
const strokeWidth = style.strokeWidth ?? 2;
|
|
534
|
+
const stroke = new OlStroke({
|
|
535
|
+
color: applyOpacity(strokeColor, strokeOpacity),
|
|
536
|
+
width: strokeWidth,
|
|
537
|
+
lineDash: style.strokeDashArray,
|
|
538
|
+
});
|
|
539
|
+
// Point styling
|
|
540
|
+
if (geometryType === 'Point') {
|
|
541
|
+
if (style.iconUrl) {
|
|
542
|
+
// Icon style for points
|
|
543
|
+
styles.push(new OlStyle({
|
|
544
|
+
image: new OlIcon({
|
|
545
|
+
src: style.iconUrl,
|
|
546
|
+
size: style.iconSize || [32, 32],
|
|
547
|
+
anchor: style.iconAnchor || [0.5, 1],
|
|
548
|
+
}),
|
|
549
|
+
}));
|
|
550
|
+
}
|
|
551
|
+
else {
|
|
552
|
+
// Circle style for points
|
|
553
|
+
const pointColor = style.pointColor ?? 'rgba(0,100,255,1)';
|
|
554
|
+
const pointOpacity = style.pointOpacity ?? 1;
|
|
555
|
+
const pointRadius = style.pointRadius ?? 6;
|
|
556
|
+
styles.push(new OlStyle({
|
|
557
|
+
image: new OlCircle({
|
|
558
|
+
radius: pointRadius,
|
|
559
|
+
fill: new OlFill({
|
|
560
|
+
color: applyOpacity(pointColor, pointOpacity),
|
|
561
|
+
}),
|
|
562
|
+
stroke: stroke,
|
|
563
|
+
}),
|
|
564
|
+
}));
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
else {
|
|
568
|
+
// Polygon and line styling
|
|
569
|
+
styles.push(new OlStyle({
|
|
570
|
+
fill: geometryType.includes('Polygon') ? fill : undefined,
|
|
571
|
+
stroke: stroke,
|
|
572
|
+
}));
|
|
573
|
+
}
|
|
574
|
+
// Text labeling
|
|
575
|
+
if (style.textProperty && feature.get(style.textProperty)) {
|
|
576
|
+
const textColor = style.textColor ?? '#000000';
|
|
577
|
+
const textSize = style.textSize ?? 12;
|
|
578
|
+
const textHaloColor = style.textHaloColor;
|
|
579
|
+
const textHaloWidth = style.textHaloWidth ?? 2;
|
|
580
|
+
const textOffset = style.textOffset || [0, 0];
|
|
581
|
+
styles.push(new OlStyle({
|
|
582
|
+
text: new OlText({
|
|
583
|
+
text: String(feature.get(style.textProperty)),
|
|
584
|
+
font: `${textSize}px Arial`,
|
|
585
|
+
fill: new OlFill({ color: textColor }),
|
|
586
|
+
stroke: textHaloColor
|
|
587
|
+
? new OlStroke({
|
|
588
|
+
color: textHaloColor,
|
|
589
|
+
width: textHaloWidth,
|
|
590
|
+
})
|
|
591
|
+
: undefined,
|
|
592
|
+
offsetX: textOffset[0],
|
|
593
|
+
offsetY: textOffset[1],
|
|
594
|
+
}),
|
|
595
|
+
}));
|
|
596
|
+
}
|
|
597
|
+
return styles;
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
async createGeoJSONLayer(config) {
|
|
601
|
+
let vectorSource = null;
|
|
602
|
+
const geojsonOptions = {
|
|
603
|
+
featureProjection: this.projection,
|
|
604
|
+
};
|
|
605
|
+
if (config.geojson) {
|
|
606
|
+
const geojsonObject = JSON.parse(config.geojson);
|
|
607
|
+
vectorSource = new VectorSource({
|
|
608
|
+
features: new GeoJSON(geojsonOptions).readFeatures(geojsonObject),
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
else {
|
|
612
|
+
vectorSource = new VectorSource({
|
|
613
|
+
url: config.url,
|
|
614
|
+
format: new GeoJSON(geojsonOptions),
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
// // Create enhanced style function
|
|
618
|
+
// const styleFunction = (feature: any) => {
|
|
619
|
+
// const styles = [];
|
|
620
|
+
// const geometry = feature.getGeometry();
|
|
621
|
+
// const geometryType = geometry.getType();
|
|
622
|
+
// // Base style configuration
|
|
623
|
+
// const style = config.style || {};
|
|
624
|
+
// // Create fill style
|
|
625
|
+
// const fillColor = style.fillColor ?? 'rgba(0,100,255,0.3)';
|
|
626
|
+
// const fillOpacity = style.fillOpacity ?? 0.3;
|
|
627
|
+
// const fill = new Fill({
|
|
628
|
+
// color: this.applyOpacity(fillColor, fillOpacity),
|
|
629
|
+
// });
|
|
630
|
+
// // Create stroke style
|
|
631
|
+
// const strokeColor = style.strokeColor ?? 'rgba(0,100,255,1)';
|
|
632
|
+
// const strokeOpacity = style.strokeOpacity ?? 1;
|
|
633
|
+
// const strokeWidth = style.strokeWidth ?? 2;
|
|
634
|
+
// const stroke = new Stroke({
|
|
635
|
+
// color: this.applyOpacity(strokeColor, strokeOpacity),
|
|
636
|
+
// width: strokeWidth,
|
|
637
|
+
// lineDash: style.strokeDashArray,
|
|
638
|
+
// });
|
|
639
|
+
// // Point styling
|
|
640
|
+
// if (geometryType === 'Point') {
|
|
641
|
+
// if (style.iconUrl) {
|
|
642
|
+
// // Icon style for points
|
|
643
|
+
// styles.push(
|
|
644
|
+
// new Style({
|
|
645
|
+
// image: new Icon({
|
|
646
|
+
// src: style.iconUrl,
|
|
647
|
+
// size: style.iconSize || [32, 32],
|
|
648
|
+
// anchor: style.iconAnchor || [0.5, 1],
|
|
649
|
+
// }),
|
|
650
|
+
// }),
|
|
651
|
+
// );
|
|
652
|
+
// } else {
|
|
653
|
+
// // Circle style for points
|
|
654
|
+
// const pointColor = style.pointColor ?? 'rgba(0,100,255,1)';
|
|
655
|
+
// const pointOpacity = style.pointOpacity ?? 1;
|
|
656
|
+
// const pointRadius = style.pointRadius ?? 6;
|
|
657
|
+
// styles.push(
|
|
658
|
+
// new Style({
|
|
659
|
+
// image: new Circle({
|
|
660
|
+
// radius: pointRadius,
|
|
661
|
+
// fill: new Fill({
|
|
662
|
+
// color: this.applyOpacity(pointColor, pointOpacity),
|
|
663
|
+
// }),
|
|
664
|
+
// stroke: stroke,
|
|
665
|
+
// }),
|
|
666
|
+
// }),
|
|
667
|
+
// );
|
|
668
|
+
// }
|
|
669
|
+
// } else {
|
|
670
|
+
// // Polygon and line styling
|
|
671
|
+
// styles.push(
|
|
672
|
+
// new Style({
|
|
673
|
+
// fill: geometryType.includes('Polygon') ? fill : undefined,
|
|
674
|
+
// stroke: stroke,
|
|
675
|
+
// }),
|
|
676
|
+
// );
|
|
677
|
+
// }
|
|
678
|
+
// // Text labeling
|
|
679
|
+
// if (style.textProperty && feature.get(style.textProperty)) {
|
|
680
|
+
// const textColor = style.textColor ?? '#000000';
|
|
681
|
+
// const textSize = style.textSize ?? 12;
|
|
682
|
+
// const textHaloColor = style.textHaloColor;
|
|
683
|
+
// const textHaloWidth = style.textHaloWidth ?? 2;
|
|
684
|
+
// const textOffset = style.textOffset || [0, 0];
|
|
685
|
+
// styles.push(
|
|
686
|
+
// new Style({
|
|
687
|
+
// text: new Text({
|
|
688
|
+
// text: String(feature.get(style.textProperty)),
|
|
689
|
+
// font: `${textSize}px Arial`,
|
|
690
|
+
// fill: new Fill({ color: textColor }),
|
|
691
|
+
// stroke: textHaloColor
|
|
692
|
+
// ? new Stroke({
|
|
693
|
+
// color: textHaloColor,
|
|
694
|
+
// width: textHaloWidth,
|
|
695
|
+
// })
|
|
696
|
+
// : undefined,
|
|
697
|
+
// offsetX: textOffset[0],
|
|
698
|
+
// offsetY: textOffset[1],
|
|
699
|
+
// }),
|
|
700
|
+
// }),
|
|
701
|
+
// );
|
|
702
|
+
// }
|
|
703
|
+
// return styles;
|
|
704
|
+
// };
|
|
705
|
+
// Use geostyler style if available, otherwise use default style function
|
|
706
|
+
let layerStyle;
|
|
707
|
+
if (config.geostylerStyle) {
|
|
708
|
+
layerStyle = await this.createGeostylerStyleFunction(config.geostylerStyle);
|
|
709
|
+
}
|
|
710
|
+
else {
|
|
711
|
+
const style = config.style
|
|
712
|
+
? { ...DEFAULT_STYLE, ...config.style }
|
|
713
|
+
: DEFAULT_STYLE;
|
|
714
|
+
layerStyle = await this.createEnhancedStyleFunction(style);
|
|
715
|
+
}
|
|
716
|
+
const layer = new VectorLayer({
|
|
717
|
+
source: vectorSource,
|
|
718
|
+
style: layerStyle,
|
|
719
|
+
});
|
|
720
|
+
return layer;
|
|
721
|
+
}
|
|
722
|
+
async createWFSSpource(config) {
|
|
723
|
+
const outputFormat = (config.outputFormat ?? 'application/json').toLowerCase();
|
|
724
|
+
let format = new GeoJSON();
|
|
725
|
+
switch (outputFormat) {
|
|
726
|
+
case 'gml2':
|
|
727
|
+
format = new GML2();
|
|
728
|
+
break;
|
|
729
|
+
case 'gml3':
|
|
730
|
+
format = new GML3();
|
|
731
|
+
break;
|
|
732
|
+
case 'gml32':
|
|
733
|
+
format = new GML32();
|
|
734
|
+
break;
|
|
735
|
+
}
|
|
736
|
+
const urlFunction = this.getWFSGetFeatureUrl(config);
|
|
737
|
+
const vectorSource = new VectorSource({
|
|
738
|
+
format: format,
|
|
739
|
+
url: urlFunction,
|
|
740
|
+
strategy: bbox,
|
|
741
|
+
});
|
|
742
|
+
return vectorSource;
|
|
743
|
+
}
|
|
744
|
+
async createWFSLayer(config) {
|
|
745
|
+
const vectorSource = await this.createWFSSpource(config);
|
|
746
|
+
// Use geostyler style if available, otherwise use default style function
|
|
747
|
+
let layerStyle;
|
|
748
|
+
if (config.geostylerStyle) {
|
|
749
|
+
layerStyle = await this.createGeostylerStyleFunction(config.geostylerStyle);
|
|
750
|
+
}
|
|
751
|
+
else {
|
|
752
|
+
const style = config.style
|
|
753
|
+
? { ...DEFAULT_STYLE, ...config.style }
|
|
754
|
+
: DEFAULT_STYLE;
|
|
755
|
+
layerStyle = await this.createEnhancedStyleFunction(style);
|
|
756
|
+
}
|
|
757
|
+
const layer = new VectorLayer({
|
|
758
|
+
source: vectorSource,
|
|
759
|
+
style: layerStyle,
|
|
760
|
+
});
|
|
761
|
+
layer.set('wfsConfig', config, false);
|
|
762
|
+
return layer;
|
|
763
|
+
}
|
|
764
|
+
// private async createWFSLayer2(
|
|
765
|
+
// config: Extract<LayerConfig, { type: 'wfs' }>,
|
|
766
|
+
// ): Promise<Layer> {
|
|
767
|
+
// const [{ default: VectorLayer }] = await Promise.all([
|
|
768
|
+
// import('ol/layer/Vector'),
|
|
769
|
+
// ]);
|
|
770
|
+
// const geojson = await this.fetchWFSFromUrl(config);
|
|
771
|
+
// const vectorSource = await this.createVectorSourceFromGeoJSON(geojson);
|
|
772
|
+
// // Use geostyler style if available, otherwise use default style function
|
|
773
|
+
// let layerStyle;
|
|
774
|
+
// if (config.geostylerStyle) {
|
|
775
|
+
// layerStyle = await this.createGeostylerStyleFunction(
|
|
776
|
+
// config.geostylerStyle,
|
|
777
|
+
// );
|
|
778
|
+
// } else {
|
|
779
|
+
// const style = config.style
|
|
780
|
+
// ? { ...DEFAULT_STYLE, ...config.style }
|
|
781
|
+
// : DEFAULT_STYLE;
|
|
782
|
+
// layerStyle = await this.createEnhancedStyleFunction(style);
|
|
783
|
+
// }
|
|
784
|
+
// const layer = new VectorLayer({
|
|
785
|
+
// source: vectorSource,
|
|
786
|
+
// style: layerStyle,
|
|
787
|
+
// visible: config.visible ?? true,
|
|
788
|
+
// });
|
|
789
|
+
// layer.set('wfsConfig', config, false);
|
|
790
|
+
// return layer as unknown as Layer;
|
|
791
|
+
// }
|
|
792
|
+
/**
|
|
793
|
+
* Convert a GeoStyler style to an OpenLayers style function.
|
|
794
|
+
*
|
|
795
|
+
* TODO: Replace this hand-rolled conversion (~200 lines) with
|
|
796
|
+
* geostyler-openlayers-parser's writeStyle(). The official parser
|
|
797
|
+
* covers more symbolizer types, handles filters, and stays in sync
|
|
798
|
+
* with the GeoStyler spec. See:
|
|
799
|
+
* https://github.com/geostyler/geostyler-openlayers-parser
|
|
800
|
+
*/
|
|
801
|
+
async createGeostylerStyleFunction(geostylerStyle) {
|
|
802
|
+
// Helper to extract static value from GeoStyler property (could be function or value)
|
|
803
|
+
const getValue = (prop, defaultValue = undefined) => {
|
|
804
|
+
if (prop === undefined || prop === null)
|
|
805
|
+
return defaultValue;
|
|
806
|
+
// If it's a GeoStyler function object, we can't evaluate it here - return default
|
|
807
|
+
if (typeof prop === 'object' && prop.name)
|
|
808
|
+
return defaultValue;
|
|
809
|
+
return prop;
|
|
810
|
+
};
|
|
811
|
+
return (feature) => {
|
|
812
|
+
const styles = [];
|
|
813
|
+
const geometry = feature.getGeometry();
|
|
814
|
+
const geometryType = geometry.getType();
|
|
815
|
+
// Process each rule in the geostyler style
|
|
816
|
+
if (geostylerStyle.rules) {
|
|
817
|
+
for (const rule of geostylerStyle.rules) {
|
|
818
|
+
// TODO: Add filter evaluation for rule.filter
|
|
819
|
+
if (rule.symbolizers) {
|
|
820
|
+
for (const symbolizer of rule.symbolizers) {
|
|
821
|
+
switch (symbolizer.kind) {
|
|
822
|
+
case 'Fill':
|
|
823
|
+
if (geometryType.includes('Polygon')) {
|
|
824
|
+
const fillColor = getValue(symbolizer.color, 'rgba(0,100,255,0.3)');
|
|
825
|
+
const outlineColor = getValue(symbolizer.outlineColor);
|
|
826
|
+
const outlineWidth = getValue(symbolizer.outlineWidth, 1);
|
|
827
|
+
styles.push(new OlStyle({
|
|
828
|
+
fill: new OlFill({
|
|
829
|
+
color: fillColor,
|
|
830
|
+
}),
|
|
831
|
+
stroke: outlineColor
|
|
832
|
+
? new OlStroke({
|
|
833
|
+
color: outlineColor,
|
|
834
|
+
width: outlineWidth,
|
|
835
|
+
})
|
|
836
|
+
: undefined,
|
|
837
|
+
}));
|
|
838
|
+
}
|
|
839
|
+
break;
|
|
840
|
+
case 'Line':
|
|
841
|
+
{
|
|
842
|
+
const lineColor = getValue(symbolizer.color, 'rgba(0,100,255,1)');
|
|
843
|
+
const lineWidth = getValue(symbolizer.width, 1);
|
|
844
|
+
const dashArray = symbolizer.dasharray
|
|
845
|
+
? Array.isArray(symbolizer.dasharray)
|
|
846
|
+
? symbolizer.dasharray.map(v => getValue(v, 0))
|
|
847
|
+
: undefined
|
|
848
|
+
: undefined;
|
|
849
|
+
styles.push(new OlStyle({
|
|
850
|
+
stroke: new OlStroke({
|
|
851
|
+
color: lineColor,
|
|
852
|
+
width: lineWidth,
|
|
853
|
+
lineDash: dashArray,
|
|
854
|
+
}),
|
|
855
|
+
}));
|
|
856
|
+
}
|
|
857
|
+
break;
|
|
858
|
+
case 'Mark':
|
|
859
|
+
if (geometryType === 'Point') {
|
|
860
|
+
const markColor = getValue(symbolizer.color, 'rgba(0,100,255,1)');
|
|
861
|
+
const markRadius = getValue(symbolizer.radius, 6);
|
|
862
|
+
const strokeColor = getValue(symbolizer.strokeColor);
|
|
863
|
+
const strokeWidth = getValue(symbolizer.strokeWidth, 1);
|
|
864
|
+
styles.push(new OlStyle({
|
|
865
|
+
image: new OlCircle({
|
|
866
|
+
radius: markRadius,
|
|
867
|
+
fill: new OlFill({
|
|
868
|
+
color: markColor,
|
|
869
|
+
}),
|
|
870
|
+
stroke: strokeColor
|
|
871
|
+
? new OlStroke({
|
|
872
|
+
color: strokeColor,
|
|
873
|
+
width: strokeWidth,
|
|
874
|
+
})
|
|
875
|
+
: undefined,
|
|
876
|
+
}),
|
|
877
|
+
}));
|
|
878
|
+
}
|
|
879
|
+
break;
|
|
880
|
+
case 'Icon':
|
|
881
|
+
if (geometryType === 'Point') {
|
|
882
|
+
const iconSrc = getValue(symbolizer.image);
|
|
883
|
+
const iconSize = getValue(symbolizer.size, 32);
|
|
884
|
+
const iconOpacity = getValue(symbolizer.opacity, 1);
|
|
885
|
+
if (iconSrc && typeof iconSrc === 'string') {
|
|
886
|
+
styles.push(new OlStyle({
|
|
887
|
+
image: new OlIcon({
|
|
888
|
+
src: iconSrc,
|
|
889
|
+
size: [iconSize, iconSize],
|
|
890
|
+
opacity: iconOpacity,
|
|
891
|
+
}),
|
|
892
|
+
}));
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
break;
|
|
896
|
+
case 'Text':
|
|
897
|
+
{
|
|
898
|
+
const textSym = symbolizer;
|
|
899
|
+
const labelProp = getValue(textSym.label);
|
|
900
|
+
if (labelProp && feature.get(labelProp)) {
|
|
901
|
+
const textColor = getValue(textSym.color, '#000000');
|
|
902
|
+
const textSize = getValue(textSym.size, 12);
|
|
903
|
+
const textFont = getValue(textSym.font?.[0], 'Arial');
|
|
904
|
+
const haloColor = getValue(textSym.haloColor);
|
|
905
|
+
const haloWidth = getValue(textSym.haloWidth, 1);
|
|
906
|
+
const offset = textSym.offset;
|
|
907
|
+
const offsetX = offset && Array.isArray(offset)
|
|
908
|
+
? getValue(offset[0], 0)
|
|
909
|
+
: 0;
|
|
910
|
+
const offsetY = offset && Array.isArray(offset)
|
|
911
|
+
? getValue(offset[1], 0)
|
|
912
|
+
: 0;
|
|
913
|
+
styles.push(new OlStyle({
|
|
914
|
+
text: new OlText({
|
|
915
|
+
text: String(feature.get(labelProp)),
|
|
916
|
+
font: `${textSize}px ${textFont}`,
|
|
917
|
+
fill: new OlFill({
|
|
918
|
+
color: textColor,
|
|
919
|
+
}),
|
|
920
|
+
stroke: haloColor
|
|
921
|
+
? new OlStroke({
|
|
922
|
+
color: haloColor,
|
|
923
|
+
width: haloWidth,
|
|
924
|
+
})
|
|
925
|
+
: undefined,
|
|
926
|
+
offsetX: offsetX,
|
|
927
|
+
offsetY: offsetY,
|
|
928
|
+
}),
|
|
929
|
+
}));
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
break;
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
return styles.length > 0 ? styles : undefined;
|
|
939
|
+
};
|
|
940
|
+
}
|
|
941
|
+
async createXYZLayer(config) {
|
|
942
|
+
return new TileLayer({
|
|
943
|
+
source: new XYZ({
|
|
944
|
+
url: config.url,
|
|
945
|
+
attributions: config.attributions,
|
|
946
|
+
maxZoom: config.maxZoom ?? 19,
|
|
947
|
+
...(config.options ?? {}),
|
|
948
|
+
}),
|
|
949
|
+
});
|
|
950
|
+
}
|
|
951
|
+
async createGoogleLayer(config) {
|
|
952
|
+
if (!config.apiKey) {
|
|
953
|
+
throw new Error("Google-Layer benötigt 'apiKey' (Google Maps Platform).");
|
|
954
|
+
}
|
|
955
|
+
// Optionen auf ol/source/Google abbilden
|
|
956
|
+
const source = new Google({
|
|
957
|
+
key: config.apiKey,
|
|
958
|
+
mapType: config.mapType ?? 'roadmap', // roadmap | satellite | terrain | hybrid
|
|
959
|
+
// optional:
|
|
960
|
+
scale: config.scale ?? 'scaleFactor2x', // 'scaleFactor1x' | 'scaleFactor2x' | 'scaleFactor4x'
|
|
961
|
+
highDpi: config.highDpi ?? true,
|
|
962
|
+
language: config.language,
|
|
963
|
+
region: config.region,
|
|
964
|
+
imageFormat: config.imageFormat,
|
|
965
|
+
styles: config.styles,
|
|
966
|
+
layerTypes: config.layerTypes,
|
|
967
|
+
});
|
|
968
|
+
source.on('change', () => {
|
|
969
|
+
if (source.getState() === 'error') {
|
|
970
|
+
// Fehler transparent machen (z.B. ungültiger Key / Billing)
|
|
971
|
+
const err = source.getError();
|
|
972
|
+
error('Google source error', err);
|
|
973
|
+
this.map.getTargetElement()?.dispatchEvent(new CustomEvent('google-source-error', {
|
|
974
|
+
detail: { message: err ?? 'Google source error' },
|
|
975
|
+
bubbles: true,
|
|
976
|
+
composed: true,
|
|
977
|
+
}));
|
|
978
|
+
}
|
|
979
|
+
});
|
|
980
|
+
const layer = new TileLayer({ source });
|
|
981
|
+
// Google Logo/Branding: als Control ergänzen (unten links)
|
|
982
|
+
if (!this.googleLogoAdded) {
|
|
983
|
+
class GoogleLogoControl extends Control {
|
|
984
|
+
constructor() {
|
|
985
|
+
const el = document.createElement('img');
|
|
986
|
+
el.style.pointerEvents = 'none';
|
|
987
|
+
el.style.position = 'absolute';
|
|
988
|
+
el.style.bottom = '5px';
|
|
989
|
+
el.style.left = '5px';
|
|
990
|
+
el.style.height = '18px';
|
|
991
|
+
el.alt = 'Google';
|
|
992
|
+
el.src =
|
|
993
|
+
'https://developers.google.com/static/maps/documentation/images/google_on_white.png';
|
|
994
|
+
super({ element: el });
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
this.map.addControl(new GoogleLogoControl());
|
|
998
|
+
this.googleLogoAdded = true;
|
|
999
|
+
}
|
|
1000
|
+
return layer;
|
|
1001
|
+
}
|
|
1002
|
+
async createOSMLayer(config) {
|
|
1003
|
+
let url = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png';
|
|
1004
|
+
if (config.url) {
|
|
1005
|
+
url = config.url + '/{z}/{x}/{y}.png';
|
|
1006
|
+
}
|
|
1007
|
+
const layer = new TileLayer({
|
|
1008
|
+
source: new OSM({
|
|
1009
|
+
url: url,
|
|
1010
|
+
}),
|
|
1011
|
+
});
|
|
1012
|
+
return layer;
|
|
1013
|
+
}
|
|
1014
|
+
async createWMSLayer(config) {
|
|
1015
|
+
return new TileLayer({
|
|
1016
|
+
source: new TileWMS({
|
|
1017
|
+
url: config.url,
|
|
1018
|
+
params: {
|
|
1019
|
+
LAYERS: config.layers,
|
|
1020
|
+
TILED: true,
|
|
1021
|
+
...(config.extraParams ?? {}),
|
|
1022
|
+
},
|
|
1023
|
+
}),
|
|
1024
|
+
});
|
|
1025
|
+
}
|
|
1026
|
+
// ── Runtime error listeners ──────────────────────────────────────
|
|
1027
|
+
onLayerError(layerId, callback) {
|
|
1028
|
+
this.layerErrorCallbacks.set(layerId, callback);
|
|
1029
|
+
this._getLayerById(layerId).then(layer => {
|
|
1030
|
+
if (!layer)
|
|
1031
|
+
return;
|
|
1032
|
+
this.attachSourceErrorListeners(layerId, layer);
|
|
1033
|
+
});
|
|
1034
|
+
}
|
|
1035
|
+
offLayerError(layerId) {
|
|
1036
|
+
this.layerErrorCleanups.get(layerId)?.();
|
|
1037
|
+
this.layerErrorCleanups.delete(layerId);
|
|
1038
|
+
this.layerErrorCallbacks.delete(layerId);
|
|
1039
|
+
}
|
|
1040
|
+
attachSourceErrorListeners(layerId, layer) {
|
|
1041
|
+
// Clean up previous listeners for this layer (e.g. after source replacement)
|
|
1042
|
+
this.layerErrorCleanups.get(layerId)?.();
|
|
1043
|
+
const cb = this.layerErrorCallbacks.get(layerId);
|
|
1044
|
+
if (!cb)
|
|
1045
|
+
return;
|
|
1046
|
+
const source = layer.getSource?.();
|
|
1047
|
+
if (!source)
|
|
1048
|
+
return;
|
|
1049
|
+
const cleanups = [];
|
|
1050
|
+
// Tile sources (OSM, XYZ, WMS, ArcGIS, Google)
|
|
1051
|
+
if ('getTile' in source || source instanceof TileWMS || source instanceof OSM || source instanceof XYZ || source instanceof Google || source instanceof TileArcGISRest) {
|
|
1052
|
+
const handler = () => { cb({ type: 'network', message: 'Tile load error' }); };
|
|
1053
|
+
source.on('tileloaderror', handler);
|
|
1054
|
+
cleanups.push(() => source.un('tileloaderror', handler));
|
|
1055
|
+
}
|
|
1056
|
+
// Vector sources (GeoJSON URL, WFS)
|
|
1057
|
+
if (source instanceof VectorSource) {
|
|
1058
|
+
const handler = () => { cb({ type: 'network', message: 'Feature load error' }); };
|
|
1059
|
+
source.on('featuresloaderror', handler);
|
|
1060
|
+
cleanups.push(() => source.un('featuresloaderror', handler));
|
|
1061
|
+
}
|
|
1062
|
+
// Image sources (WCS)
|
|
1063
|
+
if (source instanceof ImageSource) {
|
|
1064
|
+
const handler = () => { cb({ type: 'network', message: 'Image load error' }); };
|
|
1065
|
+
source.on('imageloaderror', handler);
|
|
1066
|
+
cleanups.push(() => source.un('imageloaderror', handler));
|
|
1067
|
+
}
|
|
1068
|
+
// Re-attach on source replacement (e.g. updateWMSLayer)
|
|
1069
|
+
const sourceChangeHandler = () => {
|
|
1070
|
+
this.attachSourceErrorListeners(layerId, layer);
|
|
1071
|
+
};
|
|
1072
|
+
layer.on('change:source', sourceChangeHandler);
|
|
1073
|
+
cleanups.push(() => layer.un('change:source', sourceChangeHandler));
|
|
1074
|
+
this.layerErrorCleanups.set(layerId, () => cleanups.forEach(fn => fn()));
|
|
1075
|
+
}
|
|
1076
|
+
async setView(center, zoom) {
|
|
1077
|
+
if (!this.map)
|
|
1078
|
+
return;
|
|
1079
|
+
this.map
|
|
1080
|
+
.getView()
|
|
1081
|
+
.animate({ center: fromLonLat(center), zoom, duration: 0 });
|
|
1082
|
+
}
|
|
1083
|
+
async _forEachLayer(layerOrGroup, callback) {
|
|
1084
|
+
// Wenn das aktuelle Objekt eine LayerGroup ist, rufen wir die Funktion für jedes Kind erneut auf
|
|
1085
|
+
if (layerOrGroup instanceof LayerGroup) {
|
|
1086
|
+
const layers = layerOrGroup.getLayers().getArray(); // Array der Unter‑Layer
|
|
1087
|
+
for (const child of layers) {
|
|
1088
|
+
if (await this._forEachLayer(child, callback)) {
|
|
1089
|
+
return true;
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
else {
|
|
1094
|
+
// Es handelt sich um einen normalen Layer → Callback ausführen
|
|
1095
|
+
if (callback(layerOrGroup)) {
|
|
1096
|
+
return true;
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
return false;
|
|
1100
|
+
}
|
|
1101
|
+
async _getLayerById(layerId) {
|
|
1102
|
+
if (!this.map) {
|
|
1103
|
+
return null;
|
|
1104
|
+
}
|
|
1105
|
+
let layerFound = null;
|
|
1106
|
+
await this._forEachLayer(this.map.getLayerGroup(), layer => {
|
|
1107
|
+
if (layer.get('id') === layerId) {
|
|
1108
|
+
layerFound = layer;
|
|
1109
|
+
return true;
|
|
1110
|
+
}
|
|
1111
|
+
});
|
|
1112
|
+
if (layerFound)
|
|
1113
|
+
return layerFound;
|
|
1114
|
+
layerFound = this.baseLayers.find(l => l.get('id') === layerId);
|
|
1115
|
+
if (layerFound === undefined)
|
|
1116
|
+
return null;
|
|
1117
|
+
return layerFound;
|
|
1118
|
+
}
|
|
1119
|
+
async _getLayerGroupById(groupId) {
|
|
1120
|
+
if (!this.map) {
|
|
1121
|
+
return null;
|
|
1122
|
+
}
|
|
1123
|
+
const group = this.layers.find(l => l.get?.('groupId') === groupId);
|
|
1124
|
+
if (group !== undefined)
|
|
1125
|
+
return group;
|
|
1126
|
+
return null;
|
|
1127
|
+
}
|
|
1128
|
+
async removeLayer(layerId) {
|
|
1129
|
+
if (!layerId) {
|
|
1130
|
+
return;
|
|
1131
|
+
}
|
|
1132
|
+
this.offLayerError(layerId);
|
|
1133
|
+
const layer = await this._getLayerById(layerId);
|
|
1134
|
+
if (layer) {
|
|
1135
|
+
const group = layer.get('group');
|
|
1136
|
+
if (group)
|
|
1137
|
+
group.getLayers().remove(layer);
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
async setOpacity(layerId, opacity) {
|
|
1141
|
+
if (!layerId) {
|
|
1142
|
+
return;
|
|
1143
|
+
}
|
|
1144
|
+
const layer = await this._getLayerById(layerId);
|
|
1145
|
+
if (layer) {
|
|
1146
|
+
layer.setOpacity(opacity);
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
async setZIndex(layerId, zIndex) {
|
|
1150
|
+
if (!layerId) {
|
|
1151
|
+
return;
|
|
1152
|
+
}
|
|
1153
|
+
const layer = await this._getLayerById(layerId);
|
|
1154
|
+
if (layer) {
|
|
1155
|
+
layer.setZIndex(zIndex);
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
async setVisible(layerId, visible) {
|
|
1159
|
+
const layer = await this._getLayerById(layerId);
|
|
1160
|
+
if (layer) {
|
|
1161
|
+
layer.setVisible(visible);
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
async setGroupVisible(groupId, visible) {
|
|
1165
|
+
const layer = await this._getLayerGroupById(groupId);
|
|
1166
|
+
if (layer) {
|
|
1167
|
+
layer.setVisible(visible);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
async updateWKTLayer(layer, data) {
|
|
1171
|
+
const wktFormat = new WKT();
|
|
1172
|
+
let vectorSource = null;
|
|
1173
|
+
// Get the view's projection to ensure correct coordinate transformation
|
|
1174
|
+
const viewProjection = this.map?.getView()?.getProjection();
|
|
1175
|
+
if (data.wkt) {
|
|
1176
|
+
// Parse WKT string directly
|
|
1177
|
+
const feature = wktFormat.readFeature(data.wkt, {
|
|
1178
|
+
dataProjection: 'EPSG:4326',
|
|
1179
|
+
featureProjection: viewProjection,
|
|
1180
|
+
});
|
|
1181
|
+
vectorSource = new VectorSource({
|
|
1182
|
+
features: [feature],
|
|
1183
|
+
});
|
|
1184
|
+
}
|
|
1185
|
+
else if (data.url) {
|
|
1186
|
+
// Fetch WKT from URL
|
|
1187
|
+
const response = await fetch(data.url);
|
|
1188
|
+
if (!response.ok)
|
|
1189
|
+
throw new Error(`Failed to fetch WKT: ${response.status}`);
|
|
1190
|
+
const wktText = await response.text();
|
|
1191
|
+
const feature = wktFormat.readFeature(wktText, {
|
|
1192
|
+
dataProjection: 'EPSG:4326',
|
|
1193
|
+
featureProjection: viewProjection,
|
|
1194
|
+
});
|
|
1195
|
+
vectorSource = new VectorSource({
|
|
1196
|
+
features: [feature],
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
1199
|
+
if (vectorSource) {
|
|
1200
|
+
layer.setSource(vectorSource);
|
|
1201
|
+
}
|
|
1202
|
+
let layerStyle;
|
|
1203
|
+
if (data.geostylerStyle) {
|
|
1204
|
+
layerStyle = await this.createGeostylerStyleFunction(data.geostylerStyle);
|
|
1205
|
+
}
|
|
1206
|
+
else if (data.style) {
|
|
1207
|
+
layerStyle = await this.createEnhancedStyleFunction(data.style);
|
|
1208
|
+
}
|
|
1209
|
+
if (layerStyle) {
|
|
1210
|
+
layer.setStyle(layerStyle);
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
async createWKTLayer(config) {
|
|
1214
|
+
const wktFormat = new WKT();
|
|
1215
|
+
let vectorSource = null;
|
|
1216
|
+
// Get the view's projection to ensure correct coordinate transformation
|
|
1217
|
+
const viewProjection = this.map?.getView()?.getProjection();
|
|
1218
|
+
if (config.wkt) {
|
|
1219
|
+
// Parse WKT string directly
|
|
1220
|
+
try {
|
|
1221
|
+
const feature = wktFormat.readFeature(config.wkt, {
|
|
1222
|
+
dataProjection: 'EPSG:4326',
|
|
1223
|
+
featureProjection: viewProjection,
|
|
1224
|
+
});
|
|
1225
|
+
vectorSource = new VectorSource({
|
|
1226
|
+
features: [feature],
|
|
1227
|
+
});
|
|
1228
|
+
}
|
|
1229
|
+
catch (e) {
|
|
1230
|
+
error('Failed to parse WKT:', e);
|
|
1231
|
+
vectorSource = new VectorSource({ features: [] });
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
else if (config.url) {
|
|
1235
|
+
// Fetch WKT from URL
|
|
1236
|
+
try {
|
|
1237
|
+
const response = await fetch(config.url);
|
|
1238
|
+
if (!response.ok)
|
|
1239
|
+
throw new Error(`Failed to fetch WKT: ${response.status}`);
|
|
1240
|
+
const wktText = await response.text();
|
|
1241
|
+
const feature = wktFormat.readFeature(wktText, {
|
|
1242
|
+
dataProjection: 'EPSG:4326',
|
|
1243
|
+
featureProjection: viewProjection,
|
|
1244
|
+
});
|
|
1245
|
+
vectorSource = new VectorSource({
|
|
1246
|
+
features: [feature],
|
|
1247
|
+
});
|
|
1248
|
+
}
|
|
1249
|
+
catch (e) {
|
|
1250
|
+
error('Failed to load WKT from URL:', e);
|
|
1251
|
+
vectorSource = new VectorSource({ features: [] });
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
else {
|
|
1255
|
+
vectorSource = new VectorSource({ features: [] });
|
|
1256
|
+
}
|
|
1257
|
+
// Use geostyler style if available, otherwise use default style function
|
|
1258
|
+
let layerStyle;
|
|
1259
|
+
if (config.geostylerStyle) {
|
|
1260
|
+
layerStyle = await this.createGeostylerStyleFunction(config.geostylerStyle);
|
|
1261
|
+
}
|
|
1262
|
+
else {
|
|
1263
|
+
const style = config.style
|
|
1264
|
+
? { ...DEFAULT_STYLE, ...config.style }
|
|
1265
|
+
: DEFAULT_STYLE;
|
|
1266
|
+
layerStyle = await this.createEnhancedStyleFunction(style);
|
|
1267
|
+
}
|
|
1268
|
+
const layer = new VectorLayer({
|
|
1269
|
+
source: vectorSource,
|
|
1270
|
+
style: layerStyle,
|
|
1271
|
+
opacity: config.opacity ?? 1,
|
|
1272
|
+
visible: config.visible ?? true,
|
|
1273
|
+
zIndex: config.zIndex ?? 1000,
|
|
1274
|
+
});
|
|
1275
|
+
return layer;
|
|
1276
|
+
}
|
|
1277
|
+
async createGeoTIFFLayer(config) {
|
|
1278
|
+
if (!config.url) {
|
|
1279
|
+
throw new Error('GeoTIFF layer requires a URL');
|
|
1280
|
+
}
|
|
1281
|
+
const srcInfo = {
|
|
1282
|
+
url: config.url,
|
|
1283
|
+
};
|
|
1284
|
+
if (config.nodata !== null && !isNaN(config.nodata)) {
|
|
1285
|
+
srcInfo.nodata = config.nodata;
|
|
1286
|
+
}
|
|
1287
|
+
const CustomGeoTiff = await createCustomGeoTiff({
|
|
1288
|
+
sources: [srcInfo],
|
|
1289
|
+
wrapX: false, // Prevent rendering tiles beyond extent
|
|
1290
|
+
});
|
|
1291
|
+
const source = new CustomGeoTiff();
|
|
1292
|
+
await source.registerProjectionIfNeeded();
|
|
1293
|
+
const layer = new WebGLTileLayer({
|
|
1294
|
+
source,
|
|
1295
|
+
opacity: config.opacity ?? 1,
|
|
1296
|
+
visible: config.visible ?? true,
|
|
1297
|
+
zIndex: config.zIndex ?? 100,
|
|
1298
|
+
});
|
|
1299
|
+
return layer;
|
|
1300
|
+
}
|
|
1301
|
+
// private async createGeoTIFFLayer(
|
|
1302
|
+
// config: Extract<LayerConfig, { type: 'geotiff' }>,
|
|
1303
|
+
// ): Promise<Layer> {
|
|
1304
|
+
// if (!config.url) {
|
|
1305
|
+
// throw new Error('GeoTIFF layer requires a URL');
|
|
1306
|
+
// }
|
|
1307
|
+
// createCustomGeoTiff;
|
|
1308
|
+
// const source = new GeoTIFF({
|
|
1309
|
+
// sources: [
|
|
1310
|
+
// {
|
|
1311
|
+
// url: config.url,
|
|
1312
|
+
// },
|
|
1313
|
+
// ],
|
|
1314
|
+
// });
|
|
1315
|
+
// const layer = new TileLayer({
|
|
1316
|
+
// source,
|
|
1317
|
+
// opacity: config.opacity ?? 1,
|
|
1318
|
+
// visible: config.visible ?? true,
|
|
1319
|
+
// zIndex: config.zIndex ?? 1000,
|
|
1320
|
+
// });
|
|
1321
|
+
// return layer;
|
|
1322
|
+
// }
|
|
1323
|
+
async createWCSLayer(config) {
|
|
1324
|
+
const source = await this.createWcsSource(config);
|
|
1325
|
+
const layer = new ImageLayer({
|
|
1326
|
+
source,
|
|
1327
|
+
visible: config.visible ?? true,
|
|
1328
|
+
opacity: config.opacity ?? 1,
|
|
1329
|
+
});
|
|
1330
|
+
layer.set('wcsConfig', config, false);
|
|
1331
|
+
return layer;
|
|
1332
|
+
}
|
|
1333
|
+
getWFSGetFeatureUrl(config) {
|
|
1334
|
+
return (extent) => {
|
|
1335
|
+
const wfsVersion = config.version ?? '1.1.0';
|
|
1336
|
+
const baseParams = {
|
|
1337
|
+
service: 'WFS',
|
|
1338
|
+
request: 'GetFeature',
|
|
1339
|
+
version: wfsVersion,
|
|
1340
|
+
typeName: config.typeName,
|
|
1341
|
+
outputFormat: config.outputFormat ?? 'application/json',
|
|
1342
|
+
bbox: extent.join(','),
|
|
1343
|
+
srsName: config.srsName ?? this.projection,
|
|
1344
|
+
};
|
|
1345
|
+
const params = { ...baseParams, ...(config.params ?? {}) };
|
|
1346
|
+
const requestUrl = this.appendParams(config.url, params);
|
|
1347
|
+
return requestUrl;
|
|
1348
|
+
};
|
|
1349
|
+
}
|
|
1350
|
+
/**
|
|
1351
|
+
* Erstellt eine WCS GetCoverage URL mit dynamischem BBOX für WCS 2.0.1 und 1.x.x
|
|
1352
|
+
*/
|
|
1353
|
+
getWCSGetCoverageUrl(config, resolution) {
|
|
1354
|
+
return (extent) => {
|
|
1355
|
+
const wcsVersion = config.version ?? '2.0.1';
|
|
1356
|
+
const format = config.format ?? 'image/tiff';
|
|
1357
|
+
const projection = config.projection ?? this.projection;
|
|
1358
|
+
const params = {
|
|
1359
|
+
SERVICE: 'WCS',
|
|
1360
|
+
REQUEST: 'GetCoverage',
|
|
1361
|
+
VERSION: wcsVersion,
|
|
1362
|
+
FORMAT: format,
|
|
1363
|
+
};
|
|
1364
|
+
// WCS 2.0.1 verwendet andere Parameter als 1.x.x
|
|
1365
|
+
if (wcsVersion.startsWith('2.0')) {
|
|
1366
|
+
// WCS 2.0.1: coverageId und subset Parameter
|
|
1367
|
+
params.coverageId = config.coverageName;
|
|
1368
|
+
// BBOX als subset Parameter für WCS 2.0.1
|
|
1369
|
+
// subset=X(minx,maxx)&subset=Y(miny,maxy)
|
|
1370
|
+
const [minx, miny, maxx, maxy] = extent;
|
|
1371
|
+
params['subset'] = `X(${minx},${maxx})`;
|
|
1372
|
+
params['subset2'] = `Y(${miny},${maxy})`;
|
|
1373
|
+
// Ausgabeformat-Optionen für GeoTIFF FLOAT32
|
|
1374
|
+
if (format.includes('tiff') || format.includes('geotiff')) {
|
|
1375
|
+
// Für GeoTIFF können wir geotiff:compression etc. in params übergeben
|
|
1376
|
+
params['geotiff:compression'] = 'LZW';
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
else {
|
|
1380
|
+
// WCS 1.x.x: COVERAGE und BBOX Parameter
|
|
1381
|
+
params.COVERAGE = config.coverageName;
|
|
1382
|
+
params.BBOX = extent.join(',');
|
|
1383
|
+
params.CRS = projection;
|
|
1384
|
+
// Width und Height für 1.x.x berechnen
|
|
1385
|
+
const width = Math.round((extent[2] - extent[0]) / resolution);
|
|
1386
|
+
const height = Math.round((extent[3] - extent[1]) / resolution);
|
|
1387
|
+
params.WIDTH = width;
|
|
1388
|
+
params.HEIGHT = height;
|
|
1389
|
+
}
|
|
1390
|
+
// Zusätzliche Parameter aus config hinzufügen (nur string/number)
|
|
1391
|
+
if (config.params) {
|
|
1392
|
+
Object.entries(config.params).forEach(([key, value]) => {
|
|
1393
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
1394
|
+
params[key] = value;
|
|
1395
|
+
}
|
|
1396
|
+
});
|
|
1397
|
+
}
|
|
1398
|
+
// Für WCS 2.0.1 müssen subset Parameter speziell behandelt werden
|
|
1399
|
+
if (wcsVersion.startsWith('2.0')) {
|
|
1400
|
+
const subset2 = params['subset2'];
|
|
1401
|
+
delete params['subset2'];
|
|
1402
|
+
const query = new URLSearchParams();
|
|
1403
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
1404
|
+
if (value !== undefined && value !== null) {
|
|
1405
|
+
query.append(key, String(value));
|
|
1406
|
+
}
|
|
1407
|
+
});
|
|
1408
|
+
// Zweiten subset Parameter hinzufügen
|
|
1409
|
+
if (subset2) {
|
|
1410
|
+
query.append('subset', String(subset2));
|
|
1411
|
+
}
|
|
1412
|
+
const baseUrl = config.url;
|
|
1413
|
+
return `${baseUrl}${baseUrl.includes('?') ? '&' : '?'}${query.toString()}`;
|
|
1414
|
+
}
|
|
1415
|
+
else {
|
|
1416
|
+
return this.appendParams(config.url, params);
|
|
1417
|
+
}
|
|
1418
|
+
};
|
|
1419
|
+
}
|
|
1420
|
+
// private async fetchWFSFromUrl(
|
|
1421
|
+
// config: Extract<LayerConfig, { type: 'wfs' }>,
|
|
1422
|
+
// ): Promise<any> {
|
|
1423
|
+
// const wfsVersion = config.version ?? '1.1.0';
|
|
1424
|
+
// const baseParams = {
|
|
1425
|
+
// service: 'WFS',
|
|
1426
|
+
// request: 'GetFeature',
|
|
1427
|
+
// version: wfsVersion,
|
|
1428
|
+
// typeName: config.typeName,
|
|
1429
|
+
// outputFormat: config.outputFormat ?? 'application/json',
|
|
1430
|
+
// srsName: config.srsName ?? (this.projection as string),
|
|
1431
|
+
// };
|
|
1432
|
+
// const params = { ...baseParams, ...(config.params ?? {}) };
|
|
1433
|
+
// const requestUrl = this.appendParams(config.url, params);
|
|
1434
|
+
// const response = await fetch(requestUrl);
|
|
1435
|
+
// if (!response.ok) {
|
|
1436
|
+
// throw new Error(
|
|
1437
|
+
// `WFS request failed (${response.status} ${response.statusText})`,
|
|
1438
|
+
// );
|
|
1439
|
+
// }
|
|
1440
|
+
// const outputFormat = (
|
|
1441
|
+
// config.outputFormat ?? 'application/json'
|
|
1442
|
+
// ).toLowerCase();
|
|
1443
|
+
// // Handle JSON formats
|
|
1444
|
+
// if (
|
|
1445
|
+
// outputFormat.includes('json') ||
|
|
1446
|
+
// outputFormat.includes('geojson') ||
|
|
1447
|
+
// outputFormat === 'application/json'
|
|
1448
|
+
// ) {
|
|
1449
|
+
// return await response.json();
|
|
1450
|
+
// }
|
|
1451
|
+
// // Handle GML formats using OpenLayers WFS parser
|
|
1452
|
+
// if (outputFormat.includes('gml') || outputFormat.includes('xml')) {
|
|
1453
|
+
// const text = await response.text();
|
|
1454
|
+
// const [
|
|
1455
|
+
// { default: WFS },
|
|
1456
|
+
// { default: GeoJSON },
|
|
1457
|
+
// { default: GML2 },
|
|
1458
|
+
// { default: GML3 },
|
|
1459
|
+
// { default: GML32 },
|
|
1460
|
+
// ] = await Promise.all([
|
|
1461
|
+
// import('ol/format/WFS'),
|
|
1462
|
+
// import('ol/format/GeoJSON'),
|
|
1463
|
+
// import('ol/format/GML2'),
|
|
1464
|
+
// import('ol/format/GML3'),
|
|
1465
|
+
// import('ol/format/GML32'),
|
|
1466
|
+
// ]);
|
|
1467
|
+
// const wfsOptions: any = {};
|
|
1468
|
+
// wfsOptions.version = wfsVersion;
|
|
1469
|
+
// switch (outputFormat) {
|
|
1470
|
+
// case 'gml2':
|
|
1471
|
+
// wfsOptions.gmlFormat = new GML2();
|
|
1472
|
+
// break;
|
|
1473
|
+
// case 'gml3':
|
|
1474
|
+
// wfsOptions.gmlFormat = new GML3();
|
|
1475
|
+
// break;
|
|
1476
|
+
// case 'gml32':
|
|
1477
|
+
// wfsOptions.gmlFormat = new GML32();
|
|
1478
|
+
// break;
|
|
1479
|
+
// }
|
|
1480
|
+
// const wfsFormat = new WFS(wfsOptions);
|
|
1481
|
+
// const features = wfsFormat.readFeatures(text);
|
|
1482
|
+
// // Convert features to GeoJSON
|
|
1483
|
+
// const geojsonFormat = new GeoJSON();
|
|
1484
|
+
// const geojson = JSON.parse(
|
|
1485
|
+
// geojsonFormat.writeFeatures(features, {
|
|
1486
|
+
// featureProjection: this.projection,
|
|
1487
|
+
// dataProjection: config.srsName ?? (this.projection as string),
|
|
1488
|
+
// }),
|
|
1489
|
+
// );
|
|
1490
|
+
// return geojson;
|
|
1491
|
+
// }
|
|
1492
|
+
// // Default: try to parse as JSON
|
|
1493
|
+
// return await response.json();
|
|
1494
|
+
// }
|
|
1495
|
+
// private async createVectorSourceFromGeoJSON(
|
|
1496
|
+
// geojson: any,
|
|
1497
|
+
// ): Promise<VectorSource> {
|
|
1498
|
+
// const [{ default: VectorSource }, { default: GeoJSON }] = await Promise.all(
|
|
1499
|
+
// [import('ol/source/Vector'), import('ol/format/GeoJSON')],
|
|
1500
|
+
// );
|
|
1501
|
+
// const format = new GeoJSON({ featureProjection: this.projection });
|
|
1502
|
+
// return new VectorSource({
|
|
1503
|
+
// features: format.readFeatures(geojson),
|
|
1504
|
+
// });
|
|
1505
|
+
// }
|
|
1506
|
+
mergeLayerConfig(layer, key, data) {
|
|
1507
|
+
const previous = layer.get(key) ?? {};
|
|
1508
|
+
const merged = { ...previous, ...data };
|
|
1509
|
+
layer.set(key, merged, false);
|
|
1510
|
+
return merged;
|
|
1511
|
+
}
|
|
1512
|
+
appendParams(baseUrl, params) {
|
|
1513
|
+
const query = new URLSearchParams();
|
|
1514
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
1515
|
+
if (value !== undefined && value !== null) {
|
|
1516
|
+
query.set(key, String(value));
|
|
1517
|
+
}
|
|
1518
|
+
});
|
|
1519
|
+
if (!query.toString())
|
|
1520
|
+
return baseUrl;
|
|
1521
|
+
return `${baseUrl}${baseUrl.includes('?') ? '&' : '?'}${query.toString()}`;
|
|
1522
|
+
}
|
|
1523
|
+
/**
|
|
1524
|
+
* Erstellt eine WCS Image Source mit dynamischem BBOX-basierten Loading
|
|
1525
|
+
* Unterstützt WCS 2.0.1 und 1.x.x mit GeoTIFF FLOAT32
|
|
1526
|
+
*/
|
|
1527
|
+
async createWcsSource(config) {
|
|
1528
|
+
const projection = config.projection ?? this.projection;
|
|
1529
|
+
const resolution = this.map?.getView()?.getResolution() ?? 1;
|
|
1530
|
+
const urlFunction = this.getWCSGetCoverageUrl(config, resolution);
|
|
1531
|
+
// Custom Image Source für WCS mit dynamischem BBOX
|
|
1532
|
+
class WCSImageSource extends ImageSource {
|
|
1533
|
+
urlFunction_;
|
|
1534
|
+
constructor(urlFunction) {
|
|
1535
|
+
super({
|
|
1536
|
+
projection: projection,
|
|
1537
|
+
resolutions: config.resolutions,
|
|
1538
|
+
// imageLoadFunction wird automatisch verwendet wenn url() implementiert ist
|
|
1539
|
+
});
|
|
1540
|
+
this.urlFunction_ = urlFunction;
|
|
1541
|
+
}
|
|
1542
|
+
// Überschreibe url()-Methode für dynamische URL-Generierung
|
|
1543
|
+
getImageInternal(extent, resolution, pixelRatio, _projection) {
|
|
1544
|
+
const url = this.urlFunction_(extent);
|
|
1545
|
+
// Erstelle Image mit der generierten URL
|
|
1546
|
+
const image = new OlImageWrapper(extent, resolution, pixelRatio, url);
|
|
1547
|
+
// Setze Custom Loader für CORS
|
|
1548
|
+
image.load = () => {
|
|
1549
|
+
const img = image.getImage();
|
|
1550
|
+
if (img.src !== url) {
|
|
1551
|
+
img.crossOrigin = 'anonymous';
|
|
1552
|
+
img.src = url;
|
|
1553
|
+
}
|
|
1554
|
+
};
|
|
1555
|
+
return image;
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
return new WCSImageSource(urlFunction);
|
|
1559
|
+
}
|
|
1560
|
+
async createArcGISLayer(config) {
|
|
1561
|
+
const params = {
|
|
1562
|
+
...(config.params ?? {}),
|
|
1563
|
+
};
|
|
1564
|
+
if (config.token) {
|
|
1565
|
+
params.token = config.token;
|
|
1566
|
+
}
|
|
1567
|
+
const sourceOptions = {
|
|
1568
|
+
url: config.url,
|
|
1569
|
+
params,
|
|
1570
|
+
...(config.options ?? {}),
|
|
1571
|
+
};
|
|
1572
|
+
const layer = new TileLayer({
|
|
1573
|
+
source: new TileArcGISRest(sourceOptions),
|
|
1574
|
+
visible: config.visible ?? true,
|
|
1575
|
+
});
|
|
1576
|
+
return layer;
|
|
1577
|
+
}
|
|
1578
|
+
async updateGeoTIFFLayer(layer, data) {
|
|
1579
|
+
if (!data.url) {
|
|
1580
|
+
throw new Error('GeoTIFF update requires a URL');
|
|
1581
|
+
}
|
|
1582
|
+
const srcInfo = {
|
|
1583
|
+
url: data.url,
|
|
1584
|
+
};
|
|
1585
|
+
if (data.nodata !== null && data.nodata !== undefined && !isNaN(data.nodata)) {
|
|
1586
|
+
srcInfo.nodata = data.nodata;
|
|
1587
|
+
}
|
|
1588
|
+
const CustomGeoTiff = await createCustomGeoTiff({
|
|
1589
|
+
sources: [srcInfo],
|
|
1590
|
+
wrapX: false, // Prevent rendering tiles beyond extent
|
|
1591
|
+
});
|
|
1592
|
+
const source = new CustomGeoTiff();
|
|
1593
|
+
await source.registerProjectionIfNeeded();
|
|
1594
|
+
// Update source on the layer
|
|
1595
|
+
layer.setSource(source);
|
|
1596
|
+
}
|
|
1597
|
+
getMap() {
|
|
1598
|
+
return this.map;
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
export { OpenLayersProvider };
|