@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.
Files changed (438) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +185 -0
  3. package/dist/cjs/_commonjsHelpers-B83fTs8d.js +36 -0
  4. package/dist/cjs/app-globals-V2Kpy_OQ.js +5 -0
  5. package/dist/cjs/cesium-provider-BiFFyAl9.js +2598 -0
  6. package/dist/cjs/deck-provider-Ctq3Q8a1.js +47824 -0
  7. package/dist/cjs/geotiff-CEwvF9cG.js +47 -0
  8. package/dist/cjs/geotiff-source-RaNzzWkC.js +1522 -0
  9. package/dist/cjs/index-B1oGO1g-.js +10658 -0
  10. package/dist/cjs/index-B8LHqjyg.js +1765 -0
  11. package/dist/cjs/index-BIL4VsgP.js +310 -0
  12. package/dist/cjs/index-Blku2QY8.js +167 -0
  13. package/dist/cjs/index-CJvvX4yx.js +21 -0
  14. package/dist/cjs/index-CbVT-Con.js +699 -0
  15. package/dist/cjs/index-ISOEpMC3.js +20478 -0
  16. package/dist/cjs/index-JSwBbvGA.js +1621 -0
  17. package/dist/cjs/index.browser-DQhD8Jwl.js +6873 -0
  18. package/dist/cjs/index.cjs.js +2 -0
  19. package/dist/cjs/layer-extension-B_olS0rc.js +65 -0
  20. package/dist/cjs/leaflet-provider-DOqfs7g5.js +1815 -0
  21. package/dist/cjs/loader.cjs.js +13 -0
  22. package/dist/cjs/main-dist-7TykwFci.js +2655 -0
  23. package/dist/cjs/messages-D7h4m8Tx.js +186 -0
  24. package/dist/cjs/openlayers-provider-Dfeg6L4n.js +1604 -0
  25. package/dist/cjs/polygon-layer-B9PrN7vr.js +1300 -0
  26. package/dist/cjs/scenegraph-layer-DwNoxQdi.js +2530 -0
  27. package/dist/cjs/styleconfig-CVRqArk-.js +23 -0
  28. package/dist/cjs/v-map-builder.cjs.entry.js +3786 -0
  29. package/dist/cjs/v-map-layer-geojson_12.cjs.entry.js +40894 -0
  30. package/dist/cjs/v-map-layer-helper-iAzxAg9I.js +285 -0
  31. package/dist/cjs/v-map-layer-terrain-geotiff.cjs.entry.js +258 -0
  32. package/dist/cjs/v-map-layercontrol.cjs.entry.js +247 -0
  33. package/dist/cjs/v-map.cjs.js +25 -0
  34. package/dist/cjs/v-map.v-map-layer-osm.v-map-layergroup-BsXp3BoL.js +582 -0
  35. package/dist/cjs/v-map_3.cjs.entry.js +12 -0
  36. package/dist/collection/collection-manifest.json +30 -0
  37. package/dist/collection/components/v-map/v-map.css +3 -0
  38. package/dist/collection/components/v-map/v-map.js +467 -0
  39. package/dist/collection/components/v-map/v-map.test.js +33 -0
  40. package/dist/collection/components/v-map-builder/v-map-builder.css +1 -0
  41. package/dist/collection/components/v-map-builder/v-map-builder.js +913 -0
  42. package/dist/collection/components/v-map-builder/v-map-builder.test.js +56 -0
  43. package/dist/collection/components/v-map-layer-geojson/v-map-layer-geojson.js +862 -0
  44. package/dist/collection/components/v-map-layer-geojson/v-map-layer-geojson.test.js +42 -0
  45. package/dist/collection/components/v-map-layer-geotiff/v-map-layer-geotiff.css +4 -0
  46. package/dist/collection/components/v-map-layer-geotiff/v-map-layer-geotiff.js +500 -0
  47. package/dist/collection/components/v-map-layer-geotiff/v-map-layer-geotiff.test.js +38 -0
  48. package/dist/collection/components/v-map-layer-google/v-map-layer-google.css +1 -0
  49. package/dist/collection/components/v-map-layer-google/v-map-layer-google.js +442 -0
  50. package/dist/collection/components/v-map-layer-osm/error-api.test.js +108 -0
  51. package/dist/collection/components/v-map-layer-osm/v-map-layer-osm.css +4 -0
  52. package/dist/collection/components/v-map-layer-osm/v-map-layer-osm.js +311 -0
  53. package/dist/collection/components/v-map-layer-osm/v-map-layer-osm.test.js +36 -0
  54. package/dist/collection/components/v-map-layer-scatterplot/v-map-layer-scatterplot.css +1 -0
  55. package/dist/collection/components/v-map-layer-scatterplot/v-map-layer-scatterplot.js +305 -0
  56. package/dist/collection/components/v-map-layer-terrain/v-map-layer-terrain.css +3 -0
  57. package/dist/collection/components/v-map-layer-terrain/v-map-layer-terrain.js +548 -0
  58. package/dist/collection/components/v-map-layer-terrain/v-map-layer-terrain.test.js +36 -0
  59. package/dist/collection/components/v-map-layer-terrain-geotiff/v-map-layer-terrain-geotiff.css +3 -0
  60. package/dist/collection/components/v-map-layer-terrain-geotiff/v-map-layer-terrain-geotiff.js +735 -0
  61. package/dist/collection/components/v-map-layer-terrain-geotiff/v-map-layer-terrain-geotiff.test.js +42 -0
  62. package/dist/collection/components/v-map-layer-tile3d/v-map-layer-tile3d.css +3 -0
  63. package/dist/collection/components/v-map-layer-tile3d/v-map-layer-tile3d.js +449 -0
  64. package/dist/collection/components/v-map-layer-tile3d/v-map-layer-tile3d.test.js +50 -0
  65. package/dist/collection/components/v-map-layer-wcs/v-map-layer-wcs.css +1 -0
  66. package/dist/collection/components/v-map-layer-wcs/v-map-layer-wcs.js +448 -0
  67. package/dist/collection/components/v-map-layer-wcs/v-map-layer-wcs.test.js +39 -0
  68. package/dist/collection/components/v-map-layer-wfs/v-map-layer-wfs.css +1 -0
  69. package/dist/collection/components/v-map-layer-wfs/v-map-layer-wfs.js +489 -0
  70. package/dist/collection/components/v-map-layer-wfs/v-map-layer-wfs.test.js +43 -0
  71. package/dist/collection/components/v-map-layer-wkt/v-map-layer-wkt.css +1 -0
  72. package/dist/collection/components/v-map-layer-wkt/v-map-layer-wkt.js +811 -0
  73. package/dist/collection/components/v-map-layer-wkt/v-map-layer-wkt.test.js +34 -0
  74. package/dist/collection/components/v-map-layer-wms/v-map-layer-wms.css +1 -0
  75. package/dist/collection/components/v-map-layer-wms/v-map-layer-wms.js +453 -0
  76. package/dist/collection/components/v-map-layer-wms/v-map-layer-wms.test.js +36 -0
  77. package/dist/collection/components/v-map-layer-xyz/v-map-layer-xyz.css +1 -0
  78. package/dist/collection/components/v-map-layer-xyz/v-map-layer-xyz.js +331 -0
  79. package/dist/collection/components/v-map-layer-xyz/v-map-layer-xyz.test.js +28 -0
  80. package/dist/collection/components/v-map-layercontrol/v-map-layercontrol.css +74 -0
  81. package/dist/collection/components/v-map-layercontrol/v-map-layercontrol.js +277 -0
  82. package/dist/collection/components/v-map-layercontrol/v-map-layercontrol.test.js +134 -0
  83. package/dist/collection/components/v-map-layergroup/v-map-layergroup.css +4 -0
  84. package/dist/collection/components/v-map-layergroup/v-map-layergroup.js +212 -0
  85. package/dist/collection/components/v-map-layergroup/v-map-layergroup.test.js +39 -0
  86. package/dist/collection/components/v-map-style/v-map-style.css +38 -0
  87. package/dist/collection/components/v-map-style/v-map-style.js +492 -0
  88. package/dist/collection/components/v-map-style/v-map-style.unit.js +62 -0
  89. package/dist/collection/index.js +1 -0
  90. package/dist/collection/layer/v-map-layer-helper.js +281 -0
  91. package/dist/collection/layer/v-map-layer-helper.unit.js +234 -0
  92. package/dist/collection/lib/cesium-loader.js +58 -0
  93. package/dist/collection/lib/ensure-importmap.js +12 -0
  94. package/dist/collection/lib/ensure-importmap.unit.js +57 -0
  95. package/dist/collection/lib/versions.gen.js +6 -0
  96. package/dist/collection/lib/vstyle.js +8 -0
  97. package/dist/collection/map-provider/cesium/CesiumGeoTIFFTerrainProvider.js +285 -0
  98. package/dist/collection/map-provider/cesium/CesiumLayerGroups.js +159 -0
  99. package/dist/collection/map-provider/cesium/GeoTIFFImageryProvider.js +192 -0
  100. package/dist/collection/map-provider/cesium/GeoTIFFImageryProvider.test.js +57 -0
  101. package/dist/collection/map-provider/cesium/cesium-provider.js +1408 -0
  102. package/dist/collection/map-provider/cesium/i-layer.js +1 -0
  103. package/dist/collection/map-provider/cesium/layer-manager.js +467 -0
  104. package/dist/collection/map-provider/deck/DeckGLGeoTIFFLayer.js +483 -0
  105. package/dist/collection/map-provider/deck/DeckGLGeoTIFFTerrainLayer.js +410 -0
  106. package/dist/collection/map-provider/deck/LayerGroupWithModel.js +169 -0
  107. package/dist/collection/map-provider/deck/LayerGroups.js +192 -0
  108. package/dist/collection/map-provider/deck/LayerModel.js +1 -0
  109. package/dist/collection/map-provider/deck/RenderableGroup.js +1 -0
  110. package/dist/collection/map-provider/deck/deck-provider.js +1563 -0
  111. package/dist/collection/map-provider/geotiff/geotiff-source.js +172 -0
  112. package/dist/collection/map-provider/geotiff/utils/AABB2D.js +24 -0
  113. package/dist/collection/map-provider/geotiff/utils/BVHNode2D.js +166 -0
  114. package/dist/collection/map-provider/geotiff/utils/GeoTIFFTileProcessor.js +484 -0
  115. package/dist/collection/map-provider/geotiff/utils/Triangle.js +1 -0
  116. package/dist/collection/map-provider/geotiff/utils/Triangulation.js +321 -0
  117. package/dist/collection/map-provider/geotiff/utils/colormap-utils.js +190 -0
  118. package/dist/collection/map-provider/geotiff/utils/normalization-utils.js +122 -0
  119. package/dist/collection/map-provider/geotiff/utils/sampling-utils.js +108 -0
  120. package/dist/collection/map-provider/leaflet/GeoTIFFGridLayer.js +147 -0
  121. package/dist/collection/map-provider/leaflet/WCSGridLayer.js +124 -0
  122. package/dist/collection/map-provider/leaflet/google-map-tiles-layer.js +352 -0
  123. package/dist/collection/map-provider/leaflet/leaflet-helpers.js +94 -0
  124. package/dist/collection/map-provider/leaflet/leaflet-provider.js +1095 -0
  125. package/dist/collection/map-provider/ol/CustomGeoTiff.js +145 -0
  126. package/dist/collection/map-provider/ol/openlayers-helper.js +26 -0
  127. package/dist/collection/map-provider/ol/openlayers-provider.js +1427 -0
  128. package/dist/collection/map-provider/provider-factory.js +44 -0
  129. package/dist/collection/map-provider/provider-factory.unit.js +66 -0
  130. package/dist/collection/testing/browser-test-utils.js +49 -0
  131. package/dist/collection/testing/e2e-testing.js +122 -0
  132. package/dist/collection/testing/e2e-utils.js +70 -0
  133. package/dist/collection/testing/geotiff-test-server.js +100 -0
  134. package/dist/collection/testing/mocks/geostyler-lyrx-parser.js +12 -0
  135. package/dist/collection/testing/mocks/geostyler-mapbox-parser.js +12 -0
  136. package/dist/collection/testing/mocks/geostyler-qgis-parser.js +12 -0
  137. package/dist/collection/testing/mocks/geostyler-sld-parser.js +13 -0
  138. package/dist/collection/testing/mocks/geostyler-style.js +5 -0
  139. package/dist/collection/testing/setupTests.browser.js +1 -0
  140. package/dist/collection/testing/setupTests.stencil.js +20 -0
  141. package/dist/collection/testing/setupTests.vitest.js +59 -0
  142. package/dist/collection/testing/stencil-testing-wrapper.js +43 -0
  143. package/dist/collection/testing/styleMock.js +1 -0
  144. package/dist/collection/types/color.js +1 -0
  145. package/dist/collection/types/cssmode.js +1 -0
  146. package/dist/collection/types/flavour.js +1 -0
  147. package/dist/collection/types/layerconfig.js +1 -0
  148. package/dist/collection/types/lonlat.js +1 -0
  149. package/dist/collection/types/mapinitoptions.js +1 -0
  150. package/dist/collection/types/mapprovider.js +1 -0
  151. package/dist/collection/types/provideroptions.js +1 -0
  152. package/dist/collection/types/styleconfig.js +19 -0
  153. package/dist/collection/types/styling.js +13 -0
  154. package/dist/collection/types/styling.unit.js +37 -0
  155. package/dist/collection/types/vmaplayer.js +1 -0
  156. package/dist/collection/utils/async-mutex.js +28 -0
  157. package/dist/collection/utils/diff.js +142 -0
  158. package/dist/collection/utils/diff.unit.js +59 -0
  159. package/dist/collection/utils/dom-env.js +43 -0
  160. package/dist/collection/utils/dom-env.unit.js +92 -0
  161. package/dist/collection/utils/events.js +8 -0
  162. package/dist/collection/utils/logger.js +183 -0
  163. package/dist/collection/utils/logger.unit.js +98 -0
  164. package/dist/collection/utils/messages.js +12 -0
  165. package/dist/collection/utils/spatial-utils.js +27 -0
  166. package/dist/collection/utils/spatial-utils.unit.js +24 -0
  167. package/dist/components/_commonjsHelpers.js +1 -0
  168. package/dist/components/cesium-provider.js +1 -0
  169. package/dist/components/deck-provider.js +1 -0
  170. package/dist/components/events.js +1 -0
  171. package/dist/components/geotiff-source.js +1 -0
  172. package/dist/components/geotiff.js +4 -0
  173. package/dist/components/index.browser.js +15 -0
  174. package/dist/components/index.d.ts +35 -0
  175. package/dist/components/index.js +1 -0
  176. package/dist/components/index2.js +1 -0
  177. package/dist/components/index3.js +1 -0
  178. package/dist/components/index4.js +1 -0
  179. package/dist/components/index5.js +1 -0
  180. package/dist/components/index6.js +1 -0
  181. package/dist/components/index7.js +1 -0
  182. package/dist/components/index8.js +7 -0
  183. package/dist/components/layer-extension.js +1 -0
  184. package/dist/components/leaflet-provider.js +1 -0
  185. package/dist/components/main-dist.js +1 -0
  186. package/dist/components/messages.js +1 -0
  187. package/dist/components/openlayers-provider.js +1 -0
  188. package/dist/components/polygon-layer.js +1 -0
  189. package/dist/components/scenegraph-layer.js +1 -0
  190. package/dist/components/styleconfig.js +1 -0
  191. package/dist/components/styling.js +1 -0
  192. package/dist/components/v-map-builder.d.ts +11 -0
  193. package/dist/components/v-map-builder.js +2 -0
  194. package/dist/components/v-map-layer-geojson.d.ts +11 -0
  195. package/dist/components/v-map-layer-geojson.js +1 -0
  196. package/dist/components/v-map-layer-geojson2.js +1 -0
  197. package/dist/components/v-map-layer-geotiff.d.ts +11 -0
  198. package/dist/components/v-map-layer-geotiff.js +1 -0
  199. package/dist/components/v-map-layer-geotiff2.js +1 -0
  200. package/dist/components/v-map-layer-google.d.ts +11 -0
  201. package/dist/components/v-map-layer-google.js +1 -0
  202. package/dist/components/v-map-layer-google2.js +1 -0
  203. package/dist/components/v-map-layer-helper.js +1 -0
  204. package/dist/components/v-map-layer-osm.d.ts +11 -0
  205. package/dist/components/v-map-layer-osm.js +1 -0
  206. package/dist/components/v-map-layer-osm2.js +1 -0
  207. package/dist/components/v-map-layer-scatterplot.d.ts +11 -0
  208. package/dist/components/v-map-layer-scatterplot.js +1 -0
  209. package/dist/components/v-map-layer-scatterplot2.js +1 -0
  210. package/dist/components/v-map-layer-terrain-geotiff.d.ts +11 -0
  211. package/dist/components/v-map-layer-terrain-geotiff.js +1 -0
  212. package/dist/components/v-map-layer-terrain.d.ts +11 -0
  213. package/dist/components/v-map-layer-terrain.js +1 -0
  214. package/dist/components/v-map-layer-terrain2.js +1 -0
  215. package/dist/components/v-map-layer-tile3d.d.ts +11 -0
  216. package/dist/components/v-map-layer-tile3d.js +1 -0
  217. package/dist/components/v-map-layer-tile3d2.js +1 -0
  218. package/dist/components/v-map-layer-wcs.d.ts +11 -0
  219. package/dist/components/v-map-layer-wcs.js +1 -0
  220. package/dist/components/v-map-layer-wcs2.js +1 -0
  221. package/dist/components/v-map-layer-wfs.d.ts +11 -0
  222. package/dist/components/v-map-layer-wfs.js +1 -0
  223. package/dist/components/v-map-layer-wfs2.js +1 -0
  224. package/dist/components/v-map-layer-wkt.d.ts +11 -0
  225. package/dist/components/v-map-layer-wkt.js +1 -0
  226. package/dist/components/v-map-layer-wkt2.js +1 -0
  227. package/dist/components/v-map-layer-wms.d.ts +11 -0
  228. package/dist/components/v-map-layer-wms.js +1 -0
  229. package/dist/components/v-map-layer-wms2.js +1 -0
  230. package/dist/components/v-map-layer-xyz.d.ts +11 -0
  231. package/dist/components/v-map-layer-xyz.js +1 -0
  232. package/dist/components/v-map-layer-xyz2.js +1 -0
  233. package/dist/components/v-map-layercontrol.d.ts +11 -0
  234. package/dist/components/v-map-layercontrol.js +1 -0
  235. package/dist/components/v-map-layergroup.d.ts +11 -0
  236. package/dist/components/v-map-layergroup.js +1 -0
  237. package/dist/components/v-map-layergroup2.js +1 -0
  238. package/dist/components/v-map-style.d.ts +11 -0
  239. package/dist/components/v-map-style.js +1 -0
  240. package/dist/components/v-map-style2.js +10 -0
  241. package/dist/components/v-map.d.ts +11 -0
  242. package/dist/components/v-map.js +1 -0
  243. package/dist/components/v-map2.js +1 -0
  244. package/dist/esm/_commonjsHelpers-E-ZsRS8r.js +32 -0
  245. package/dist/esm/app-globals-DQuL1Twl.js +3 -0
  246. package/dist/esm/cesium-provider-BJfAup3w.js +2596 -0
  247. package/dist/esm/deck-provider-C7U9VDEq.js +47709 -0
  248. package/dist/esm/geotiff-BEWxTIfH.js +45 -0
  249. package/dist/esm/geotiff-source-esnDnC-u.js +1516 -0
  250. package/dist/esm/index-B1zwA4IC.js +685 -0
  251. package/dist/esm/index-BBpiaTpT.js +165 -0
  252. package/dist/esm/index-BIEmlzCf.js +1697 -0
  253. package/dist/esm/index-BUHa4Jj0.js +307 -0
  254. package/dist/esm/index-DbSdn93t.js +20461 -0
  255. package/dist/esm/index-RpJarvr_.js +10656 -0
  256. package/dist/esm/index-jN06TXUp.js +14 -0
  257. package/dist/esm/index-jzneDarq.js +1613 -0
  258. package/dist/esm/index.browser-DhQAXuA7.js +6860 -0
  259. package/dist/esm/index.js +1 -0
  260. package/dist/esm/layer-extension-CZXK5goK.js +63 -0
  261. package/dist/esm/leaflet-provider-Q41TB6ku.js +1794 -0
  262. package/dist/esm/loader.js +11 -0
  263. package/dist/esm/main-dist-CwnA7_Xn.js +2652 -0
  264. package/dist/esm/messages-CMKJzsgL.js +180 -0
  265. package/dist/esm/openlayers-provider-CMsDsQTQ.js +1602 -0
  266. package/dist/esm/polygon-layer-ByhxGhWC.js +1295 -0
  267. package/dist/esm/scenegraph-layer-09K_B6DT.js +2526 -0
  268. package/dist/esm/styleconfig-B-bAcABs.js +21 -0
  269. package/dist/esm/v-map-builder.entry.js +3784 -0
  270. package/dist/esm/v-map-layer-geojson_12.entry.js +40881 -0
  271. package/dist/esm/v-map-layer-helper-Dys44Cgo.js +283 -0
  272. package/dist/esm/v-map-layer-terrain-geotiff.entry.js +256 -0
  273. package/dist/esm/v-map-layercontrol.entry.js +245 -0
  274. package/dist/esm/v-map.js +21 -0
  275. package/dist/esm/v-map.v-map-layer-osm.v-map-layergroup-B4pFHuSf.js +572 -0
  276. package/dist/esm/v-map_3.entry.js +4 -0
  277. package/dist/index.cjs.js +1 -0
  278. package/dist/index.js +1 -0
  279. package/dist/types/cesium-augment.d.ts +5 -0
  280. package/dist/types/components/v-map/v-map.d.ts +70 -0
  281. package/dist/types/components/v-map/v-map.test.d.ts +1 -0
  282. package/dist/types/components/v-map-builder/v-map-builder.d.ts +48 -0
  283. package/dist/types/components/v-map-builder/v-map-builder.test.d.ts +1 -0
  284. package/dist/types/components/v-map-layer-geojson/v-map-layer-geojson.d.ts +129 -0
  285. package/dist/types/components/v-map-layer-geojson/v-map-layer-geojson.test.d.ts +1 -0
  286. package/dist/types/components/v-map-layer-geotiff/v-map-layer-geotiff.d.ts +74 -0
  287. package/dist/types/components/v-map-layer-geotiff/v-map-layer-geotiff.test.d.ts +1 -0
  288. package/dist/types/components/v-map-layer-google/v-map-layer-google.d.ts +78 -0
  289. package/dist/types/components/v-map-layer-osm/error-api.test.d.ts +1 -0
  290. package/dist/types/components/v-map-layer-osm/v-map-layer-osm.d.ts +50 -0
  291. package/dist/types/components/v-map-layer-osm/v-map-layer-osm.test.d.ts +1 -0
  292. package/dist/types/components/v-map-layer-scatterplot/v-map-layer-scatterplot.d.ts +54 -0
  293. package/dist/types/components/v-map-layer-terrain/v-map-layer-terrain.d.ts +74 -0
  294. package/dist/types/components/v-map-layer-terrain/v-map-layer-terrain.test.d.ts +1 -0
  295. package/dist/types/components/v-map-layer-terrain-geotiff/v-map-layer-terrain-geotiff.d.ts +117 -0
  296. package/dist/types/components/v-map-layer-terrain-geotiff/v-map-layer-terrain-geotiff.test.d.ts +1 -0
  297. package/dist/types/components/v-map-layer-tile3d/v-map-layer-tile3d.d.ts +69 -0
  298. package/dist/types/components/v-map-layer-tile3d/v-map-layer-tile3d.test.d.ts +1 -0
  299. package/dist/types/components/v-map-layer-wcs/v-map-layer-wcs.d.ts +47 -0
  300. package/dist/types/components/v-map-layer-wcs/v-map-layer-wcs.test.d.ts +1 -0
  301. package/dist/types/components/v-map-layer-wfs/v-map-layer-wfs.d.ts +59 -0
  302. package/dist/types/components/v-map-layer-wfs/v-map-layer-wfs.test.d.ts +1 -0
  303. package/dist/types/components/v-map-layer-wkt/v-map-layer-wkt.d.ts +132 -0
  304. package/dist/types/components/v-map-layer-wkt/v-map-layer-wkt.test.d.ts +1 -0
  305. package/dist/types/components/v-map-layer-wms/v-map-layer-wms.d.ts +76 -0
  306. package/dist/types/components/v-map-layer-wms/v-map-layer-wms.test.d.ts +1 -0
  307. package/dist/types/components/v-map-layer-xyz/v-map-layer-xyz.d.ts +59 -0
  308. package/dist/types/components/v-map-layer-xyz/v-map-layer-xyz.test.d.ts +1 -0
  309. package/dist/types/components/v-map-layercontrol/v-map-layercontrol.d.ts +44 -0
  310. package/dist/types/components/v-map-layercontrol/v-map-layercontrol.test.d.ts +1 -0
  311. package/dist/types/components/v-map-layergroup/v-map-layergroup.d.ts +31 -0
  312. package/dist/types/components/v-map-layergroup/v-map-layergroup.test.d.ts +1 -0
  313. package/dist/types/components/v-map-style/v-map-style.d.ts +75 -0
  314. package/dist/types/components/v-map-style/v-map-style.unit.d.ts +1 -0
  315. package/dist/types/components.d.ts +2391 -0
  316. package/dist/types/globals.d.ts +16 -0
  317. package/dist/types/index.d.ts +10 -0
  318. package/dist/types/layer/v-map-layer-helper.d.ts +45 -0
  319. package/dist/types/layer/v-map-layer-helper.unit.d.ts +1 -0
  320. package/dist/types/leaflet-augment.d.ts +15 -0
  321. package/dist/types/lib/cesium-loader.d.ts +3 -0
  322. package/dist/types/lib/ensure-importmap.d.ts +3 -0
  323. package/dist/types/lib/ensure-importmap.unit.d.ts +1 -0
  324. package/dist/types/lib/versions.gen.d.ts +5 -0
  325. package/dist/types/lib/vstyle.d.ts +44 -0
  326. package/dist/types/map-provider/cesium/CesiumGeoTIFFTerrainProvider.d.ts +92 -0
  327. package/dist/types/map-provider/cesium/CesiumLayerGroups.d.ts +64 -0
  328. package/dist/types/map-provider/cesium/GeoTIFFImageryProvider.d.ts +75 -0
  329. package/dist/types/map-provider/cesium/GeoTIFFImageryProvider.test.d.ts +1 -0
  330. package/dist/types/map-provider/cesium/cesium-provider.d.ts +87 -0
  331. package/dist/types/map-provider/cesium/i-layer.d.ts +11 -0
  332. package/dist/types/map-provider/cesium/layer-manager.d.ts +31 -0
  333. package/dist/types/map-provider/deck/DeckGLGeoTIFFLayer.d.ts +91 -0
  334. package/dist/types/map-provider/deck/DeckGLGeoTIFFTerrainLayer.d.ts +82 -0
  335. package/dist/types/map-provider/deck/LayerGroupWithModel.d.ts +55 -0
  336. package/dist/types/map-provider/deck/LayerGroups.d.ts +63 -0
  337. package/dist/types/map-provider/deck/LayerModel.d.ts +8 -0
  338. package/dist/types/map-provider/deck/RenderableGroup.d.ts +20 -0
  339. package/dist/types/map-provider/deck/deck-provider.d.ts +92 -0
  340. package/dist/types/map-provider/geotiff/geotiff-source.d.ts +30 -0
  341. package/dist/types/map-provider/geotiff/utils/AABB2D.d.ts +28 -0
  342. package/dist/types/map-provider/geotiff/utils/BVHNode2D.d.ts +36 -0
  343. package/dist/types/map-provider/geotiff/utils/GeoTIFFTileProcessor.d.ts +116 -0
  344. package/dist/types/map-provider/geotiff/utils/Triangle.d.ts +5 -0
  345. package/dist/types/map-provider/geotiff/utils/Triangulation.d.ts +94 -0
  346. package/dist/types/map-provider/geotiff/utils/colormap-utils.d.ts +47 -0
  347. package/dist/types/map-provider/geotiff/utils/normalization-utils.d.ts +39 -0
  348. package/dist/types/map-provider/geotiff/utils/sampling-utils.d.ts +13 -0
  349. package/dist/types/map-provider/leaflet/GeoTIFFGridLayer.d.ts +34 -0
  350. package/dist/types/map-provider/leaflet/WCSGridLayer.d.ts +38 -0
  351. package/dist/types/map-provider/leaflet/google-map-tiles-layer.d.ts +73 -0
  352. package/dist/types/map-provider/leaflet/leaflet-helpers.d.ts +6 -0
  353. package/dist/types/map-provider/leaflet/leaflet-provider.d.ts +73 -0
  354. package/dist/types/map-provider/ol/CustomGeoTiff.d.ts +14 -0
  355. package/dist/types/map-provider/ol/openlayers-helper.d.ts +2 -0
  356. package/dist/types/map-provider/ol/openlayers-provider.d.ts +80 -0
  357. package/dist/types/map-provider/provider-factory.d.ts +12 -0
  358. package/dist/types/map-provider/provider-factory.unit.d.ts +1 -0
  359. package/dist/types/namespaces.d.ts +3 -0
  360. package/dist/types/ol-augment.d.ts +3 -0
  361. package/dist/types/ol-override.d.ts +7 -0
  362. package/dist/types/ol.d.ts +10 -0
  363. package/dist/types/stencil-public-runtime.d.ts +1860 -0
  364. package/dist/types/testing/browser-test-utils.d.ts +6 -0
  365. package/dist/types/testing/e2e-testing.d.ts +5 -0
  366. package/dist/types/testing/e2e-utils.d.ts +4 -0
  367. package/dist/types/testing/geotiff-test-server.d.ts +5 -0
  368. package/dist/types/testing/mocks/geostyler-lyrx-parser.d.ts +11 -0
  369. package/dist/types/testing/mocks/geostyler-mapbox-parser.d.ts +11 -0
  370. package/dist/types/testing/mocks/geostyler-qgis-parser.d.ts +11 -0
  371. package/dist/types/testing/mocks/geostyler-sld-parser.d.ts +11 -0
  372. package/dist/types/testing/mocks/geostyler-style.d.ts +5 -0
  373. package/dist/types/testing/setupTests.browser.d.ts +1 -0
  374. package/dist/types/testing/setupTests.stencil.d.ts +1 -0
  375. package/dist/types/testing/setupTests.vitest.d.ts +1 -0
  376. package/dist/types/testing/stencil-testing-wrapper.d.ts +3 -0
  377. package/dist/types/types/color.d.ts +1 -0
  378. package/dist/types/types/cssmode.d.ts +1 -0
  379. package/dist/types/types/flavour.d.ts +1 -0
  380. package/dist/types/types/layerconfig.d.ts +207 -0
  381. package/dist/types/types/lonlat.d.ts +1 -0
  382. package/dist/types/types/mapinitoptions.d.ts +4 -0
  383. package/dist/types/types/mapprovider.d.ts +46 -0
  384. package/dist/types/types/provideroptions.d.ts +8 -0
  385. package/dist/types/types/styleconfig.d.ts +27 -0
  386. package/dist/types/types/styling.d.ts +24 -0
  387. package/dist/types/types/styling.unit.d.ts +1 -0
  388. package/dist/types/types/vmaplayer.d.ts +10 -0
  389. package/dist/types/utils/async-mutex.d.ts +7 -0
  390. package/dist/types/utils/diff.d.ts +64 -0
  391. package/dist/types/utils/diff.unit.d.ts +1 -0
  392. package/dist/types/utils/dom-env.d.ts +5 -0
  393. package/dist/types/utils/dom-env.unit.d.ts +1 -0
  394. package/dist/types/utils/events.d.ts +29 -0
  395. package/dist/types/utils/logger.d.ts +47 -0
  396. package/dist/types/utils/logger.unit.d.ts +1 -0
  397. package/dist/types/utils/messages.d.ts +12 -0
  398. package/dist/types/utils/spatial-utils.d.ts +6 -0
  399. package/dist/types/utils/spatial-utils.unit.d.ts +1 -0
  400. package/dist/types/versions.d.ts +7 -0
  401. package/dist/v-map/index.esm.js +0 -0
  402. package/dist/v-map/p--vVleK-M.js +1 -0
  403. package/dist/v-map/p-09d10db0.entry.js +1 -0
  404. package/dist/v-map/p-5eba6058.entry.js +10 -0
  405. package/dist/v-map/p-6b102336.entry.js +1 -0
  406. package/dist/v-map/p-B-bAcABs.js +1 -0
  407. package/dist/v-map/p-BBpiaTpT.js +1 -0
  408. package/dist/v-map/p-BdijL4Av.js +1 -0
  409. package/dist/v-map/p-Be3r33VF.js +4 -0
  410. package/dist/v-map/p-BeFu0ap4.js +1 -0
  411. package/dist/v-map/p-BxFJezdK.js +1 -0
  412. package/dist/v-map/p-CMKJzsgL.js +1 -0
  413. package/dist/v-map/p-CXfA_q8m.js +1 -0
  414. package/dist/v-map/p-CZqY0yW4.js +1 -0
  415. package/dist/v-map/p-CafTHT9i.js +1 -0
  416. package/dist/v-map/p-DCTHyf58.js +1 -0
  417. package/dist/v-map/p-DQuL1Twl.js +1 -0
  418. package/dist/v-map/p-DR9McdNX.js +1 -0
  419. package/dist/v-map/p-Dckgonw8.js +1 -0
  420. package/dist/v-map/p-DhQAXuA7.js +15 -0
  421. package/dist/v-map/p-DmICdG34.js +7 -0
  422. package/dist/v-map/p-DrOQ9V4h.js +1 -0
  423. package/dist/v-map/p-DvHXtWUg.js +1 -0
  424. package/dist/v-map/p-E-ZsRS8r.js +1 -0
  425. package/dist/v-map/p-MyTSFnEk.js +1 -0
  426. package/dist/v-map/p-RpJarvr_.js +1 -0
  427. package/dist/v-map/p-WaMDUuAz.js +1 -0
  428. package/dist/v-map/p-aa410e64.entry.js +2 -0
  429. package/dist/v-map/p-c21c93fe.entry.js +1 -0
  430. package/dist/v-map/p-jzneDarq.js +2 -0
  431. package/dist/v-map/p-uiIP-taz.js +1 -0
  432. package/dist/v-map/v-map.esm.js +1 -0
  433. package/loader/cdn.js +1 -0
  434. package/loader/index.cjs.js +1 -0
  435. package/loader/index.d.ts +24 -0
  436. package/loader/index.es2017.js +1 -0
  437. package/loader/index.js +2 -0
  438. package/package.json +193 -0
@@ -0,0 +1,2598 @@
1
+ 'use strict';
2
+
3
+ var messages = require('./messages-D7h4m8Tx.js');
4
+ var vMap_vMapLayerOsm_vMapLayergroup_entry = require('./v-map.v-map-layer-osm.v-map-layergroup-BsXp3BoL.js');
5
+ var geotiffSource = require('./geotiff-source-RaNzzWkC.js');
6
+ require('./index-JSwBbvGA.js');
7
+ require('./v-map-layer-helper-iAzxAg9I.js');
8
+
9
+ /**
10
+ * Eine Gruppe verwaltet Sichtbarkeit & Basemap-Filter ihrer Cesium-Layer.
11
+ * - group.visible = false => Alle Layer der Gruppe unsichtbar.
12
+ * - group.basemap = "X" => Nur Layer mit elementId==="X" in der Gruppe sichtbar.
13
+ * - Der ursprüngliche Sichtbarkeitszustand jedes Layers wird gemerkt und bei
14
+ * Re-Aktivierung wiederhergestellt.
15
+ */
16
+ class CesiumLayerGroup {
17
+ id;
18
+ _visible = true;
19
+ _basemap = null;
20
+ _layers = new Map();
21
+ _originalVisible = new Map();
22
+ _dirty = true;
23
+ constructor(id, visible = true) {
24
+ this.id = id;
25
+ this._visible = visible;
26
+ }
27
+ get visible() {
28
+ return this._visible;
29
+ }
30
+ set visible(v) {
31
+ if (this._visible === v)
32
+ return;
33
+ this._visible = v;
34
+ this._dirty = true;
35
+ }
36
+ get basemap() {
37
+ return this._basemap;
38
+ }
39
+ set basemap(b) {
40
+ if (this._basemap === b)
41
+ return;
42
+ this._basemap = b;
43
+ this._dirty = true;
44
+ }
45
+ isDirty() {
46
+ return this._dirty;
47
+ }
48
+ addLayer(ref) {
49
+ if (this._layers.has(ref.id))
50
+ return;
51
+ this._layers.set(ref.id, ref);
52
+ this._originalVisible.set(ref.id, ref.layer.getVisible());
53
+ this._dirty = true;
54
+ }
55
+ /** optional zum Nachziehen von elementId (z. B. wenn erst später bekannt) */
56
+ setLayerElementId(layerId, elementId) {
57
+ const r = this._layers.get(layerId);
58
+ if (!r)
59
+ return;
60
+ if (r.elementId === elementId)
61
+ return;
62
+ r.elementId = elementId ?? null;
63
+ this._dirty = true;
64
+ }
65
+ removeLayer(layerId) {
66
+ const had = this._layers.delete(layerId);
67
+ this._originalVisible.delete(layerId);
68
+ if (had)
69
+ this._dirty = true;
70
+ return had;
71
+ }
72
+ clear() {
73
+ this._layers.clear();
74
+ this._originalVisible.clear();
75
+ this._dirty = true;
76
+ }
77
+ /** zentrale Logik: Basemap/Visibility anwenden */
78
+ apply() {
79
+ if (!this._dirty)
80
+ return;
81
+ for (const [id, ref] of this._layers) {
82
+ const original = this._originalVisible.get(id) ?? true;
83
+ // effektive Sichtbarkeit nach Gruppenregeln
84
+ let effective = this._visible && original;
85
+ if (effective && this._basemap) {
86
+ // innerhalb der Gruppe nur Layer mit passender elementId anzeigen
87
+ effective = ref.elementId === this._basemap;
88
+ }
89
+ // Nur dann setzen, wenn sich etwas ändert
90
+ if (ref.layer.getVisible() !== effective) {
91
+ ref.layer.setVisible(effective);
92
+ }
93
+ }
94
+ this._dirty = false;
95
+ }
96
+ }
97
+ /**
98
+ * Root-Store für mehrere Cesium-Gruppen.
99
+ * - Ordnung/Z-Index übernimmst du weiterhin im LayerManager pro Layer.
100
+ * - Diese Klasse kümmert sich um Gruppensichtbarkeit & Basemap-Filter.
101
+ */
102
+ class CesiumLayerGroups {
103
+ _groups = [];
104
+ _dirty = true;
105
+ get groups() {
106
+ return [...this._groups];
107
+ }
108
+ getGroup(id) {
109
+ return this._groups.find(g => g.id === id);
110
+ }
111
+ hasGroup(id) {
112
+ return this._groups.some(g => g.id === id);
113
+ }
114
+ ensureGroup(id, visible = true) {
115
+ let g = this.getGroup(id);
116
+ if (g)
117
+ return g;
118
+ g = new CesiumLayerGroup(id, visible);
119
+ this._groups.push(g);
120
+ this._dirty = true;
121
+ return g;
122
+ }
123
+ addLayerToGroup(groupId, visible, ref) {
124
+ const g = this.ensureGroup(groupId, visible);
125
+ g.addLayer(ref);
126
+ this._dirty = true;
127
+ }
128
+ removeLayer(layerId, removeFromAll = true) {
129
+ let removed = false;
130
+ for (const g of this._groups) {
131
+ if (g.removeLayer(layerId)) {
132
+ removed = true;
133
+ if (!removeFromAll)
134
+ break;
135
+ }
136
+ }
137
+ if (removed)
138
+ this._dirty = true;
139
+ return removed;
140
+ }
141
+ setGroupVisible(groupId, visible) {
142
+ const g = this.getGroup(groupId);
143
+ if (!g)
144
+ throw new Error(`CesiumLayerGroup "${groupId}" nicht gefunden`);
145
+ g.visible = visible;
146
+ this._dirty = true;
147
+ }
148
+ setBasemap(groupId, basemap) {
149
+ const g = this.getGroup(groupId);
150
+ if (!g)
151
+ throw new Error(`CesiumLayerGroup "${groupId}" nicht gefunden`);
152
+ g.basemap = basemap;
153
+ this._dirty = true;
154
+ }
155
+ /** Wendet alle Gruppenregeln an (sichtbar/basemap). */
156
+ apply() {
157
+ if (!this._dirty && !this._groups.some(g => g.isDirty()))
158
+ return;
159
+ for (const g of this._groups)
160
+ g.apply();
161
+ this._dirty = false;
162
+ }
163
+ clear() {
164
+ this._groups = [];
165
+ this._dirty = true;
166
+ }
167
+ }
168
+
169
+ class LayerManager {
170
+ Cesium;
171
+ layers = new Map();
172
+ viewer;
173
+ //private imageryZMutex = new AsyncMutex();
174
+ constructor(Cesium, viewer) {
175
+ this.viewer = viewer;
176
+ this.Cesium = Cesium;
177
+ }
178
+ replaceLayer(id, oldlayer, layer) {
179
+ if (!this.Cesium) {
180
+ throw new Error('Cesium must be initialized first. Call init() method.');
181
+ }
182
+ const zIndex = oldlayer.getZIndex();
183
+ const visible = oldlayer.getVisible();
184
+ const opacity = oldlayer.getOpacity();
185
+ this.removeLayer(id);
186
+ const wrappedLayer = this.addLayer(id, layer);
187
+ wrappedLayer.setZIndex(zIndex);
188
+ wrappedLayer.setVisible(visible);
189
+ wrappedLayer.setOpacity(opacity);
190
+ return wrappedLayer;
191
+ }
192
+ addLayer(id, layer) {
193
+ if (!this.Cesium) {
194
+ throw new Error('Cesium must be initialized first. Call init() method.');
195
+ }
196
+ //add layer
197
+ if (layer instanceof this.Cesium.GeoJsonDataSource) {
198
+ this.viewer.dataSources.add(layer);
199
+ }
200
+ else if (layer instanceof this.Cesium.DataSource) {
201
+ this.viewer.dataSources.add(layer);
202
+ }
203
+ else if (layer instanceof this.Cesium.Cesium3DTileset) {
204
+ this.viewer.scene.primitives.add(layer);
205
+ if (!layer.style) {
206
+ layer.style = new this.Cesium.Cesium3DTileStyle();
207
+ }
208
+ }
209
+ else if (layer instanceof this.Cesium.ImageryLayer) {
210
+ this.viewer.imageryLayers.add(layer);
211
+ }
212
+ layer.id = id;
213
+ const wrapped = this.wrapLayer(layer);
214
+ this.layers.set(id, wrapped);
215
+ return wrapped;
216
+ }
217
+ addCustomLayer(id, layer) {
218
+ this.layers.set(id, layer);
219
+ return layer;
220
+ }
221
+ getLayer(layerId) {
222
+ const layer = this.layers.get(layerId);
223
+ if (!layer)
224
+ throw new Error(`Layer mit ID "${layerId}" nicht gefunden.`);
225
+ return layer;
226
+ }
227
+ getLayerById(layerId) {
228
+ return this.getLayer(layerId);
229
+ }
230
+ removeLayer(layerId) {
231
+ const layer = this.getLayer(layerId);
232
+ layer.remove();
233
+ this.layers.delete(layerId);
234
+ }
235
+ setVisible(layerId, visible) {
236
+ const layer = this.getLayer(layerId);
237
+ layer.setVisible(visible);
238
+ }
239
+ setOpacity(layerId, opacity) {
240
+ const layer = this.getLayer(layerId);
241
+ layer.setOpacity(opacity);
242
+ }
243
+ async setZIndex(layerId, zindex) {
244
+ const layer = this.getLayer(layerId);
245
+ await layer.setZIndex(zindex);
246
+ }
247
+ wrapLayer(layer) {
248
+ if (layer instanceof this.Cesium.ImageryLayer) {
249
+ return this.wrapImageryLayer(layer);
250
+ }
251
+ else if (layer instanceof this.Cesium.Cesium3DTileset) {
252
+ return this.wrapTilesetLayer(layer);
253
+ }
254
+ else {
255
+ return this.wrapDataSourceLayer(layer);
256
+ }
257
+ }
258
+ async sortImageryLayers(collection, layer, targetZ) {
259
+ const tempCollection = this.sort(collection, layer, targetZ);
260
+ // Collection leeren und neu befüllen
261
+ collection.removeAll(false);
262
+ tempCollection.forEach(ds => collection.add(ds));
263
+ }
264
+ async sort3DTileSets(collection, tileset, targetZ) {
265
+ const tempCollection = this.sort(collection, tileset, targetZ);
266
+ // Collection leeren und neu befüllen
267
+ collection.removeAll();
268
+ tempCollection.forEach(ds => collection.add(ds));
269
+ }
270
+ async sortDataSources(collection, dataSource, zIndex) {
271
+ const tempCollection = this.sort(collection, dataSource, zIndex);
272
+ // Collection leeren und neu befüllen
273
+ collection.removeAll(false);
274
+ tempCollection.forEach(async (ds) => await collection.add(ds));
275
+ }
276
+ sort(collection, dataSource, zIndex) {
277
+ // 1. Layer entfernen
278
+ collection.remove(dataSource, false);
279
+ // 2. Layer an der richtigen Position wieder hinzufügen
280
+ // Cesium hat keine direkte "setZIndex"-Methode für DataSources,
281
+ // also müssen wir die Reihenfolge manuell steuern.
282
+ // Da DataSourceCollection keine Z-Index-Unterstützung hat,
283
+ // müssen wir alle Layer neu sortieren.
284
+ // const dataSources: DataSource[] = [];
285
+ const tempDataSources = [];
286
+ // Alle Layer sammeln
287
+ for (let i = 0; i < collection.length; i++) {
288
+ tempDataSources.push(collection.get(i));
289
+ }
290
+ // Sortieren nach zIndex (falls vorhanden) oder Reihenfolge
291
+ tempDataSources.sort((a, b) => {
292
+ const aZIndex = a.zIndex || 0;
293
+ const bZIndex = b.zIndex || 0;
294
+ return aZIndex - bZIndex;
295
+ });
296
+ // Den Layer mit dem neuen zIndex einfügen
297
+ dataSource.zIndex = zIndex;
298
+ tempDataSources.push(dataSource);
299
+ // Neu sortieren
300
+ tempDataSources.sort((a, b) => {
301
+ const aZIndex = a.zIndex || 0;
302
+ const bZIndex = b.zIndex || 0;
303
+ return aZIndex - bZIndex;
304
+ });
305
+ return tempDataSources;
306
+ }
307
+ // /**
308
+ // * Verschiebt ein bereits vorhandenes ImageryLayer innerhalb seiner Collection
309
+ // * zu einem gewünschten zIndex und hält die Collection nach zIndex sortiert.
310
+ // *
311
+ // * @param collection Die Sammlung, in der sich das Layer befindet.
312
+ // * @param layer Das zu verschiebende Layer (ist bereits Teil der Collection).
313
+ // * @param targetZ Der gewünschte neue zIndex.
314
+ // */
315
+ // private moveImageryLayerToZIndex(
316
+ // collection: ImageryLayerCollection,
317
+ // layer: ImageryLayer,
318
+ // targetZ: number,
319
+ // ): void {
320
+ // // fire-and-forget; Thread-Sicherheit via Mutex
321
+ // void this.imageryZMutex.runExclusive(async () => {
322
+ // // -------------------------------------------------
323
+ // // 1️⃣ Neues zIndex setzen (überschreibt das alte)
324
+ // // -------------------------------------------------
325
+ // (layer as any).zIndex = targetZ;
326
+ // // -------------------------------------------------
327
+ // // 2️⃣ Aktuelle Position bestimmen
328
+ // // -------------------------------------------------
329
+ // const curIdx = collection.indexOf(layer);
330
+ // if (curIdx === -1) {
331
+ // throw new Error('Der übergebene Layer ist nicht Teil der Collection.');
332
+ // }
333
+ // // -------------------------------------------------
334
+ // // 3️⃣ Nach oben schieben, solange Vorgänger einen
335
+ // // größeren zIndex hat (stabile Sortierung)
336
+ // // -------------------------------------------------
337
+ // let idx = curIdx;
338
+ // while (
339
+ // idx > 0 && // nicht am Anfang
340
+ // collection[idx - 1].zIndex > targetZ // Vorgänger hat höheren zIndex
341
+ // ) {
342
+ // // `raise` vertauscht das aktuelle Element mit seinem Vorgänger
343
+ // collection.raise(collection[idx]);
344
+ // idx--;
345
+ // }
346
+ // // -------------------------------------------------
347
+ // // 4️⃣ Nach unten schieben, falls das neue zIndex
348
+ // // größer ist als das der nachfolgenden Elemente
349
+ // // -------------------------------------------------
350
+ // while (
351
+ // idx < collection.length - 1 && // nicht am Ende
352
+ // collection[idx + 1].zIndex < targetZ // Nachfolger hat kleineren zIndex
353
+ // ) {
354
+ // // `lower` vertauscht das aktuelle Element mit seinem Nachfolger
355
+ // collection.lower(collection[idx]);
356
+ // idx++;
357
+ // }
358
+ // });
359
+ // // -------------------------------------------------
360
+ // // 5️⃣ Optional: Guard‑Clause für extreme Werte
361
+ // // -------------------------------------------------
362
+ // // (Falls du Min/Max‑Grenzen definieren willst)
363
+ // // if (targetZ < MIN_Z) (layer as any).zIndex = MIN_Z;
364
+ // // if (targetZ > MAX_Z) (layer as any).zIndex = MAX_Z;
365
+ // }
366
+ // private moveTilesetToIndex(tileset: Cesium3DTileset, index: number): void {
367
+ // const primitives = this.viewer.scene.primitives;
368
+ // primitives.remove(tileset);
369
+ // if (index >= primitives.length) {
370
+ // primitives.add(tileset);
371
+ // } else {
372
+ // const tilesets = [];
373
+ // for (let i = 0; i < primitives.length; i++) {
374
+ // const current = primitives.get(i);
375
+ // if (i === index) tilesets.push(tileset);
376
+ // if (current !== tileset) tilesets.push(current);
377
+ // }
378
+ // primitives.removeAll();
379
+ // tilesets.forEach(t => primitives.add(t));
380
+ // }
381
+ // }
382
+ // private moveDataSourceToIndex(
383
+ // collection: DataSourceCollection,
384
+ // dataSource: DataSource,
385
+ // zIndex: number,
386
+ // ): void {
387
+ // // 1. Layer entfernen
388
+ // collection.remove(dataSource);
389
+ // // 2. Layer an der richtigen Position wieder hinzufügen
390
+ // // Cesium hat keine direkte "setZIndex"-Methode für DataSources,
391
+ // // also müssen wir die Reihenfolge manuell steuern.
392
+ // // Da DataSourceCollection keine Z-Index-Unterstützung hat,
393
+ // // müssen wir alle Layer neu sortieren.
394
+ // // const dataSources: DataSource[] = [];
395
+ // const tempDataSources: DataSource[] = [];
396
+ // // Alle Layer sammeln
397
+ // for (let i = 0; i < collection.length; i++) {
398
+ // tempDataSources.push(collection.get(i));
399
+ // }
400
+ // // Sortieren nach zIndex (falls vorhanden) oder Reihenfolge
401
+ // tempDataSources.sort((a, b) => {
402
+ // const aZIndex = (a as any).zIndex || 0;
403
+ // const bZIndex = (b as any).zIndex || 0;
404
+ // return aZIndex - bZIndex;
405
+ // });
406
+ // // Den Layer mit dem neuen zIndex einfügen
407
+ // (dataSource as any).zIndex = zIndex;
408
+ // tempDataSources.push(dataSource);
409
+ // // Neu sortieren
410
+ // tempDataSources.sort((a, b) => {
411
+ // const aZIndex = (a as any).zIndex || 0;
412
+ // const bZIndex = (b as any).zIndex || 0;
413
+ // return aZIndex - bZIndex;
414
+ // });
415
+ // // Collection leeren und neu befüllen
416
+ // collection.removeAll();
417
+ // tempDataSources.forEach(ds => collection.add(ds));
418
+ // }
419
+ wrapImageryLayer(layer) {
420
+ const collection = this.viewer.imageryLayers;
421
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- matches ILayer interface contract
422
+ let iLOptions = {};
423
+ return {
424
+ getOptions: () => {
425
+ return iLOptions;
426
+ },
427
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- matches ILayer interface contract
428
+ setOptions(options) {
429
+ iLOptions = options;
430
+ },
431
+ getVisible: () => {
432
+ return layer.show;
433
+ },
434
+ setVisible: (value) => {
435
+ layer.show = value;
436
+ },
437
+ getOpacity: () => layer.alpha,
438
+ setOpacity: (value) => {
439
+ layer.alpha = value;
440
+ },
441
+ getZIndex: () => {
442
+ for (let i = 0; i < collection.length; i++) {
443
+ if (collection.get(i) === layer)
444
+ return i;
445
+ }
446
+ return -1;
447
+ },
448
+ setZIndex: async (zIndex) => {
449
+ if (zIndex !== undefined) {
450
+ await this.sortImageryLayers(collection, layer, zIndex);
451
+ }
452
+ },
453
+ remove: () => collection.remove(layer),
454
+ };
455
+ }
456
+ wrapTilesetLayer(layer) {
457
+ const collection = this.viewer.scene.primitives;
458
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- matches ILayer interface contract
459
+ let c3dTSOptions = {};
460
+ return {
461
+ getOptions: () => {
462
+ return c3dTSOptions;
463
+ },
464
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- matches ILayer interface contract
465
+ setOptions(options) {
466
+ c3dTSOptions = options;
467
+ },
468
+ getVisible: () => {
469
+ return layer.show;
470
+ },
471
+ setVisible: (value) => {
472
+ layer.show = value;
473
+ },
474
+ getOpacity: () => {
475
+ const style = layer.style;
476
+ if (style.color && typeof style.color === 'string') {
477
+ const colorStr = style.color;
478
+ const match = colorStr.match(/color\(.*?,([\d.]+)\)/);
479
+ return match ? parseFloat(match[1]) : 1.0;
480
+ }
481
+ return 1.0;
482
+ },
483
+ setOpacity: (value) => {
484
+ const currentColor = layer.style.color;
485
+ let colorExpr;
486
+ if (typeof currentColor === 'string') {
487
+ const colorStr = currentColor;
488
+ const colorPart = colorStr.replace(/color\((.*?),[\d.]+\)/, `color($1, ${value})`);
489
+ colorExpr = colorPart.includes('color')
490
+ ? colorPart
491
+ : `color('white', ${value})`;
492
+ }
493
+ else {
494
+ colorExpr = `color('white', ${value})`;
495
+ }
496
+ layer.style = new this.Cesium.Cesium3DTileStyle({
497
+ color: colorExpr,
498
+ colorBlendMode: this.Cesium.ColorBlendMode.MIX,
499
+ });
500
+ },
501
+ getZIndex: () => {
502
+ const primitives = this.viewer.scene.primitives;
503
+ for (let i = 0; i < primitives.length; i++) {
504
+ if (primitives.get(i) === layer)
505
+ return i;
506
+ }
507
+ return -1;
508
+ },
509
+ setZIndex: async (zIndex) => {
510
+ if (zIndex !== undefined) {
511
+ this.sort3DTileSets(collection, layer, zIndex);
512
+ //this.moveTilesetToIndex(layer, zIndex);
513
+ }
514
+ },
515
+ setColor: (color, opacity = 1.0) => {
516
+ const cssColor = color instanceof this.Cesium.Color
517
+ ? color.toCssHexString()
518
+ : color.replace(/[#\s]/g, '');
519
+ layer.style = new this.Cesium.Cesium3DTileStyle({
520
+ color: `color('${cssColor}', ${opacity})`,
521
+ colorBlendMode: this.Cesium.ColorBlendMode.MIX,
522
+ });
523
+ },
524
+ setStyle: (style) => {
525
+ layer.style =
526
+ style instanceof this.Cesium.Cesium3DTileStyle
527
+ ? style
528
+ : new this.Cesium.Cesium3DTileStyle(style);
529
+ },
530
+ remove: () => this.viewer.scene.primitives.remove(layer),
531
+ };
532
+ }
533
+ wrapDataSourceLayer(layer) {
534
+ const collection = this.viewer.dataSources;
535
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- matches ILayer interface contract
536
+ let dsOptions = {};
537
+ return {
538
+ getOptions: () => {
539
+ return dsOptions;
540
+ },
541
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- matches ILayer interface contract
542
+ setOptions(options) {
543
+ dsOptions = options;
544
+ },
545
+ getVisible: () => {
546
+ return layer.show;
547
+ },
548
+ setVisible: (value) => {
549
+ layer.show = value;
550
+ },
551
+ getOpacity: () => 1.0, //todo
552
+ setOpacity: (value) => {
553
+ if (layer.__vmapLockOpacity)
554
+ return;
555
+ layer.entities.values.forEach((entity) => {
556
+ // Helper-Funktion zum Setzen der Opacity
557
+ const setColorOpacity = (colorProperty, defaultColor) => {
558
+ const { Color: CesiumColor, JulianDate } = this.Cesium;
559
+ const applyAlpha = (color) => CesiumColor.fromAlpha(color ?? defaultColor, value, new CesiumColor());
560
+ if (!colorProperty) {
561
+ return new this.Cesium.ConstantProperty(applyAlpha(defaultColor));
562
+ }
563
+ const maybeProperty = colorProperty;
564
+ if (maybeProperty && typeof maybeProperty.getValue === 'function') {
565
+ const currentColor = maybeProperty.getValue(this.viewer?.clock?.currentTime ?? new JulianDate(), new CesiumColor());
566
+ const nextColor = applyAlpha(currentColor);
567
+ if (typeof maybeProperty.setValue === 'function') {
568
+ maybeProperty.setValue(nextColor);
569
+ return maybeProperty;
570
+ }
571
+ return new this.Cesium.ConstantProperty(nextColor);
572
+ }
573
+ if (colorProperty instanceof this.Cesium.Color) {
574
+ return new this.Cesium.ConstantProperty(applyAlpha(colorProperty));
575
+ }
576
+ return new this.Cesium.ConstantProperty(applyAlpha(defaultColor));
577
+ };
578
+ // Polygone
579
+ if (entity.polygon) {
580
+ const material = entity.polygon.material;
581
+ if (material instanceof Cesium.ColorMaterialProperty) {
582
+ const color = material.color;
583
+ material.color = setColorOpacity(color, Cesium.Color.WHITE);
584
+ }
585
+ else if (material instanceof Cesium.ImageMaterialProperty) {
586
+ material.color = setColorOpacity(material.color, Cesium.Color.WHITE);
587
+ }
588
+ }
589
+ // Polylinien
590
+ if (entity.polyline) {
591
+ const material = entity.polyline.material;
592
+ if (material instanceof Cesium.ColorMaterialProperty) {
593
+ material.color = setColorOpacity(material.color, Cesium.Color.WHITE);
594
+ }
595
+ else if (material instanceof Cesium.PolylineOutlineMaterialProperty) {
596
+ material.color = setColorOpacity(material.color, Cesium.Color.WHITE);
597
+ }
598
+ }
599
+ // Punkte
600
+ if (entity.point) {
601
+ entity.point.color = setColorOpacity(entity.point.color, Cesium.Color.WHITE);
602
+ }
603
+ // Billboards
604
+ if (entity.billboard) {
605
+ entity.billboard.color = setColorOpacity(entity.billboard.color, Cesium.Color.WHITE);
606
+ }
607
+ // Labels
608
+ if (entity.label) {
609
+ entity.label.fillColor = setColorOpacity(entity.label.fillColor, Cesium.Color.BLACK);
610
+ if (entity.label.outlineColor) {
611
+ entity.label.outlineColor = setColorOpacity(entity.label.outlineColor, Cesium.Color.BLACK);
612
+ }
613
+ }
614
+ // 3D-Modelle (falls vorhanden)
615
+ if (entity.model) {
616
+ entity.model.color = setColorOpacity(entity.model.color, Cesium.Color.WHITE);
617
+ }
618
+ });
619
+ },
620
+ getZIndex: () => {
621
+ for (let i = 0; i < collection.length; i++) {
622
+ if (collection.get(i) === layer)
623
+ return i;
624
+ }
625
+ return -1;
626
+ },
627
+ setZIndex: async (zIndex) => {
628
+ if (zIndex !== undefined) {
629
+ await this.sortDataSources(collection, layer, zIndex);
630
+ }
631
+ },
632
+ remove: () => collection.remove(layer),
633
+ };
634
+ }
635
+ }
636
+
637
+ // utils/async-mutex.ts
638
+ class AsyncMutex {
639
+ locked = false;
640
+ queue = [];
641
+ async runExclusive(fn) {
642
+ await this.acquire();
643
+ try {
644
+ return await fn();
645
+ }
646
+ finally {
647
+ this.release();
648
+ }
649
+ }
650
+ acquire() {
651
+ if (!this.locked) {
652
+ this.locked = true;
653
+ return Promise.resolve();
654
+ }
655
+ return new Promise(resolve => this.queue.push(resolve));
656
+ }
657
+ release() {
658
+ const next = this.queue.shift();
659
+ if (next)
660
+ next();
661
+ else
662
+ this.locked = false;
663
+ }
664
+ }
665
+
666
+ function assert(cond, msg) {
667
+ if (!cond)
668
+ throw new Error(msg);
669
+ }
670
+ const sameMM = (exp, act) => exp.match(/^\d+\.\d+/)?.[0] === act.match(/^\d+\.\d+/)?.[0];
671
+ const loadCesiumMutex = new AsyncMutex();
672
+ async function loadCesium(version = vMap_vMapLayerOsm_vMapLayergroup_entry.CESIUM_VERSION) {
673
+ const v = version.replace(/^[^\d]*/, '');
674
+ const base = `https://cdn.jsdelivr.net/npm/cesium@${v}/Build/Cesium`;
675
+ const url = `${base}/Cesium.js`;
676
+ await loadCesiumMutex.runExclusive(async () => {
677
+ if (!globalThis.Cesium) {
678
+ await new Promise((resolve, reject) => {
679
+ const id = 'cesium-cdn-script';
680
+ if (document.getElementById(id))
681
+ return resolve();
682
+ const s = document.createElement('script');
683
+ s.id = id;
684
+ s.async = true;
685
+ s.src = url;
686
+ s.addEventListener('load', () => resolve(), { once: true });
687
+ s.addEventListener('error', () => reject(new Error(`Laden fehlgeschlagen: ${url}`)), { once: true });
688
+ document.head.appendChild(s);
689
+ });
690
+ }
691
+ });
692
+ const Cesium = globalThis.Cesium;
693
+ assert(Cesium, 'globalThis.Cesium nicht verfügbar.');
694
+ const actual = Cesium.VERSION; // z.B. "1.133"
695
+ assert(sameMM(String(version), actual), // Major.Minor muss passen
696
+ `Cesium-Version abweichend: erwartet ~${version}, geladen ${actual}`);
697
+ globalThis.CESIUM_BASE_URL = base;
698
+ return Cesium;
699
+ }
700
+ async function injectWidgetsCss(shadowRoot) {
701
+ const v = vMap_vMapLayerOsm_vMapLayergroup_entry.CESIUM_VERSION.replace(/^[^\d]*/, '');
702
+ const base = `https://cdn.jsdelivr.net/npm/cesium@${v}/Build/Cesium`;
703
+ const cssUrl = `${base}/Widgets/widgets.css`;
704
+ const cssText = await (await fetch(cssUrl)).text();
705
+ const absolutized = cssText.replace(/url\((?!['"]?data:)(['"]?)([^'")]+)\1\)/g, (_m, _q, rel) => `url(${base}/Widgets/${rel.replace(/^\.?\//, '')})`);
706
+ if (!shadowRoot)
707
+ return;
708
+ if ('adoptedStyleSheets' in Document.prototype) {
709
+ const sheet = new CSSStyleSheet();
710
+ await sheet.replace(absolutized);
711
+ shadowRoot.adoptedStyleSheets = [
712
+ ...(shadowRoot.adoptedStyleSheets ?? []),
713
+ sheet,
714
+ ];
715
+ }
716
+ else {
717
+ const style = document.createElement('style');
718
+ style.textContent = absolutized;
719
+ shadowRoot.appendChild(style);
720
+ }
721
+ }
722
+
723
+ /**
724
+ * Custom ImageryProvider that renders GeoTIFF tiles on demand using
725
+ * the shared GeoTIFFTileProcessor (triangulation-based reprojection).
726
+ */
727
+ class GeoTIFFImageryProvider {
728
+ tileWidth;
729
+ tileHeight;
730
+ tilingScheme;
731
+ rectangle;
732
+ errorEvent;
733
+ credit = undefined;
734
+ tileDiscardPolicy = undefined;
735
+ proxy = undefined;
736
+ hasAlphaChannel = true;
737
+ minimumLevel;
738
+ maximumLevel;
739
+ Cesium;
740
+ tileProcessor;
741
+ resolution;
742
+ resampleMethod;
743
+ colorStops;
744
+ readyPromiseInternal;
745
+ ready = false;
746
+ constructor(options) {
747
+ const { Cesium, rectangleDegrees, tileProcessor, tileSize, resolution, resampleMethod, colorStops, minimumLevel, maximumLevel, } = options;
748
+ this.Cesium = Cesium;
749
+ this.tileProcessor = tileProcessor;
750
+ this.tileWidth = tileSize;
751
+ this.tileHeight = tileSize;
752
+ this.resolution = resolution;
753
+ this.resampleMethod = resampleMethod;
754
+ this.colorStops = colorStops;
755
+ this.minimumLevel = minimumLevel ?? 0;
756
+ this.maximumLevel = maximumLevel;
757
+ this.rectangle = Cesium.Rectangle.fromDegrees(rectangleDegrees[0], rectangleDegrees[1], rectangleDegrees[2], rectangleDegrees[3]);
758
+ // Always use WebMercatorTilingScheme because the GeoTIFFTileProcessor
759
+ // interprets (x,y,z) as Web Mercator tile coordinates.
760
+ this.tilingScheme = new Cesium.WebMercatorTilingScheme();
761
+ this.errorEvent = new Cesium.Event();
762
+ this.ready = true;
763
+ this.readyPromiseInternal = Promise.resolve(true);
764
+ }
765
+ get tilingSchemeName() {
766
+ // Expose helper for debugging if needed.
767
+ return this.tilingScheme instanceof this.Cesium.WebMercatorTilingScheme
768
+ ? 'WebMercator'
769
+ : undefined;
770
+ }
771
+ get readyPromise() {
772
+ return this.readyPromiseInternal;
773
+ }
774
+ get tileCredits() {
775
+ return undefined;
776
+ }
777
+ getTileCredits(_x, _y, _level) {
778
+ return undefined;
779
+ }
780
+ get url() {
781
+ return undefined;
782
+ }
783
+ /**
784
+ * Flips a canvas vertically (Y-axis inversion) for Cesium.
785
+ * Creates a new canvas with the flipped content.
786
+ *
787
+ * @param sourceCanvas - The canvas to flip
788
+ * @param width - Width of the canvas
789
+ * @param height - Height of the canvas
790
+ * @returns A new canvas with vertically flipped content, or the source canvas if flipping fails
791
+ */
792
+ flipCanvasVertically(sourceCanvas, width, height) {
793
+ const flippedCanvas = document.createElement('canvas');
794
+ flippedCanvas.width = width;
795
+ flippedCanvas.height = height;
796
+ const flippedCtx = flippedCanvas.getContext('2d');
797
+ if (!flippedCtx) {
798
+ messages.warn('v-map - cesium - failed to get 2d context for flip');
799
+ return sourceCanvas; // Fallback to source canvas
800
+ }
801
+ flippedCtx.translate(0, height);
802
+ flippedCtx.scale(1, -1);
803
+ flippedCtx.drawImage(sourceCanvas, 0, 0);
804
+ return flippedCanvas;
805
+ }
806
+ /**
807
+ * Creates a flipped ImageBitmap from RGBA data.
808
+ * Uses ImageBitmap for better performance when available.
809
+ *
810
+ * @param rgbaData - The RGBA pixel data
811
+ * @param sampleSize - Size of the tile (width and height)
812
+ * @returns A flipped ImageBitmap, or undefined if creation fails
813
+ */
814
+ async createFlippedImageBitmap(rgbaData, sampleSize) {
815
+ if (typeof createImageBitmap !== 'function') {
816
+ return undefined;
817
+ }
818
+ try {
819
+ // Create temporary canvas for Y-axis flip
820
+ const tempCanvas = document.createElement('canvas');
821
+ tempCanvas.width = sampleSize;
822
+ tempCanvas.height = sampleSize;
823
+ const tempCtx = tempCanvas.getContext('2d');
824
+ if (!tempCtx) {
825
+ throw new Error('Failed to get 2d context');
826
+ }
827
+ const imageData = tempCtx.createImageData(sampleSize, sampleSize);
828
+ imageData.data.set(rgbaData);
829
+ tempCtx.putImageData(imageData, 0, 0);
830
+ // Flip vertically for Cesium
831
+ const flippedCanvas = this.flipCanvasVertically(tempCanvas, sampleSize, sampleSize);
832
+ return await createImageBitmap(flippedCanvas);
833
+ }
834
+ catch (err) {
835
+ messages.warn('v-map - cesium - createImageBitmap failed, falling back', err);
836
+ return undefined;
837
+ }
838
+ }
839
+ /**
840
+ * Creates a flipped image (ImageBitmap or Canvas) from RGBA data.
841
+ * Prefers ImageBitmap for better performance, falls back to Canvas.
842
+ *
843
+ * @param rgbaData - The RGBA pixel data
844
+ * @returns A flipped ImageBitmap or Canvas, or undefined if creation fails
845
+ */
846
+ async createFlippedImageFromRGBA(rgbaData) {
847
+ // Calculate actual sample size (may differ from tileWidth due to resolution)
848
+ const sampleSize = Math.ceil(this.tileWidth * this.resolution);
849
+ // Prefer ImageBitmap when available for better performance
850
+ const imageBitmap = await this.createFlippedImageBitmap(rgbaData, sampleSize);
851
+ if (imageBitmap) {
852
+ return imageBitmap;
853
+ }
854
+ // Fallback to Canvas
855
+ const canvas = document.createElement('canvas');
856
+ canvas.width = sampleSize;
857
+ canvas.height = sampleSize;
858
+ const ctx = canvas.getContext('2d');
859
+ if (!ctx) {
860
+ messages.warn('v-map - cesium - unable to acquire canvas 2d context');
861
+ return undefined;
862
+ }
863
+ const imageData = ctx.createImageData(sampleSize, sampleSize);
864
+ imageData.data.set(rgbaData);
865
+ ctx.putImageData(imageData, 0, 0);
866
+ // Flip the canvas vertically for Cesium (Y-axis inversion)
867
+ return this.flipCanvasVertically(canvas, sampleSize, sampleSize);
868
+ }
869
+ async requestImage(x, y, level) {
870
+ if (!this.ready)
871
+ return undefined;
872
+ if (level < this.minimumLevel ||
873
+ (this.maximumLevel !== undefined && level > this.maximumLevel)) {
874
+ return undefined;
875
+ }
876
+ const params = {
877
+ x,
878
+ y,
879
+ z: level,
880
+ tileSize: this.tileWidth,
881
+ resolution: this.resolution,
882
+ resampleMethod: this.resampleMethod,
883
+ colorStops: this.colorStops,
884
+ };
885
+ let rgbaData = null;
886
+ try {
887
+ rgbaData = await this.tileProcessor.getTileData(params);
888
+ if (!rgbaData) {
889
+ messages.log(`v-map - cesium - geotiff - requestImage(${x},${y},${level}): no data returned`);
890
+ return undefined;
891
+ }
892
+ messages.log(`v-map - cesium - geotiff - requestImage(${x},${y},${level}): rgba ${rgbaData.length} bytes, sampleSize=${Math.ceil(this.tileWidth * this.resolution)}`);
893
+ }
894
+ catch (err) {
895
+ this.errorEvent.raiseEvent(err);
896
+ messages.warn('v-map - cesium - getTileData - GeoTIFF tile request failed', err);
897
+ return undefined;
898
+ }
899
+ try {
900
+ const result = await this.createFlippedImageFromRGBA(rgbaData);
901
+ messages.log(`v-map - cesium - geotiff - requestImage(${x},${y},${level}): result=${result?.constructor?.name ?? 'undefined'}, size=${result instanceof HTMLCanvasElement ? `${result.width}x${result.height}` : result instanceof ImageBitmap ? `${result.width}x${result.height}` : 'n/a'}`);
902
+ return result;
903
+ }
904
+ catch (err) {
905
+ this.errorEvent.raiseEvent(err);
906
+ messages.warn('v-map - cesium - createFlippedImageFromRGBA - GeoTIFF tile request failed', err);
907
+ return undefined;
908
+ }
909
+ }
910
+ pickFeatures() {
911
+ return undefined;
912
+ }
913
+ }
914
+
915
+ const LOG_PREFIX = 'v-map - cesium - terrain-geotiff - ';
916
+ /**
917
+ * Custom Cesium Terrain Provider for GeoTIFF elevation data
918
+ *
919
+ * This provider loads a GeoTIFF file containing elevation data and provides
920
+ * it to Cesium's terrain system as a heightmap.
921
+ */
922
+ class CesiumGeoTIFFTerrainProvider {
923
+ Cesium;
924
+ image;
925
+ fromProjection = 'EPSG:4326';
926
+ sourceBounds = [0, 0, 0, 0];
927
+ wgs84Bounds = [0, 0, 0, 0];
928
+ width = 0;
929
+ height = 0;
930
+ noDataValue = 0;
931
+ ready = false;
932
+ _readyPromise;
933
+ heightmapWidth = 65;
934
+ heightmapHeight = 65;
935
+ proj4;
936
+ tilingScheme;
937
+ constructor(options) {
938
+ this.Cesium = options.Cesium;
939
+ // Initialize with GeographicTilingScheme (WGS84)
940
+ this.tilingScheme = new this.Cesium.GeographicTilingScheme();
941
+ // Start loading the GeoTIFF
942
+ this._readyPromise = this.initialize(options);
943
+ }
944
+ async initialize(options) {
945
+ try {
946
+ messages.log(`${LOG_PREFIX}loadGeoTIFF: url=${options.url}`);
947
+ const [geotiffModule, { default: proj4 }, geokeysModule] = await Promise.all([
948
+ Promise.resolve().then(function () { return require('./geotiff-CEwvF9cG.js'); }).then(function (n) { return n.geotiff; }),
949
+ Promise.resolve().then(function () { return require('./index-B1oGO1g-.js'); }),
950
+ Promise.resolve().then(function () { return require('./main-dist-7TykwFci.js'); }).then(function (n) { return n.mainDist; }),
951
+ ]);
952
+ const source = await geotiffSource.loadGeoTIFFSource(options.url, {
953
+ projection: options.projection,
954
+ forceProjection: options.forceProjection ?? false,
955
+ nodata: options.nodata,
956
+ }, {
957
+ geotiff: geotiffModule,
958
+ proj4,
959
+ geokeysToProj4: geokeysModule,
960
+ });
961
+ this.image = source.baseImage;
962
+ this.fromProjection = source.fromProjection;
963
+ this.sourceBounds = source.sourceBounds;
964
+ this.wgs84Bounds = source.wgs84Bounds;
965
+ this.width = source.width;
966
+ this.height = source.height;
967
+ this.noDataValue = source.noDataValue ?? 0;
968
+ this.proj4 = source.proj4; // Store proj4 instance with registered projections
969
+ messages.log(`${LOG_PREFIX}loaded: projection=${this.fromProjection}, bounds=[${this.sourceBounds.map(v => v.toFixed(0)).join(',')}], wgs84=[${this.wgs84Bounds.map(v => v.toFixed(4)).join(',')}], size=${this.width}x${this.height}`);
970
+ this.ready = true;
971
+ return true;
972
+ }
973
+ catch (err) {
974
+ messages.error(`${LOG_PREFIX}failed to load GeoTIFF:`, err);
975
+ this.ready = false;
976
+ return false;
977
+ }
978
+ }
979
+ /**
980
+ * Get the coverage rectangle in WGS84 coordinates
981
+ */
982
+ get rectangle() {
983
+ if (!this.ready || !this.wgs84Bounds) {
984
+ return this.Cesium.Rectangle.MAX_VALUE;
985
+ }
986
+ const [west, south, east, north] = this.wgs84Bounds;
987
+ return this.Cesium.Rectangle.fromDegrees(west, south, east, north);
988
+ }
989
+ /**
990
+ * Request tile geometry for a specific tile
991
+ */
992
+ async requestTileGeometry(x, y, level) {
993
+ if (!this.ready || !this.image) {
994
+ return undefined;
995
+ }
996
+ try {
997
+ // Get tile bounds in WGS84
998
+ const rectangle = this.tilingScheme.tileXYToRectangle(x, y, level);
999
+ let west = this.Cesium.Math.toDegrees(rectangle.west);
1000
+ let south = this.Cesium.Math.toDegrees(rectangle.south);
1001
+ let east = this.Cesium.Math.toDegrees(rectangle.east);
1002
+ let north = this.Cesium.Math.toDegrees(rectangle.north);
1003
+ // Get GeoTIFF bounds in WGS84
1004
+ const [geoWest, geoSouth, geoEast, geoNorth] = this.wgs84Bounds;
1005
+ // Check if tile intersects with GeoTIFF bounds
1006
+ if (east < geoWest ||
1007
+ west > geoEast ||
1008
+ north < geoSouth ||
1009
+ south > geoNorth) {
1010
+ // Tile is completely outside GeoTIFF bounds, return flat heightmap
1011
+ return this.createFlatHeightmap();
1012
+ }
1013
+ // Clamp tile bounds to GeoTIFF coverage area
1014
+ // This prevents transformation errors when the GeoTIFF projection
1015
+ // doesn't support the full WGS84 range (e.g., Mercator and poles)
1016
+ west = Math.max(geoWest, Math.min(geoEast, west));
1017
+ east = Math.max(geoWest, Math.min(geoEast, east));
1018
+ south = Math.max(geoSouth, Math.min(geoNorth, south));
1019
+ north = Math.max(geoSouth, Math.min(geoNorth, north));
1020
+ // Transform tile bounds to source projection
1021
+ // Use the stored proj4 instance that has the projection definitions
1022
+ const transformToSource = (coord) => {
1023
+ try {
1024
+ return this.proj4('EPSG:4326', this.fromProjection, coord);
1025
+ }
1026
+ catch (err) {
1027
+ messages.warn(`${LOG_PREFIX}transform failed:`, err);
1028
+ return coord;
1029
+ }
1030
+ };
1031
+ const swSource = transformToSource([west, south]);
1032
+ const neSource = transformToSource([east, north]);
1033
+ // Calculate pixel coordinates in GeoTIFF
1034
+ const [srcWest, srcSouth, srcEast, srcNorth] = this.sourceBounds;
1035
+ const srcWidth = this.width;
1036
+ const srcHeight = this.height;
1037
+ const pixelWidth = srcEast - srcWest;
1038
+ const pixelHeight = srcNorth - srcSouth;
1039
+ const x0 = Math.floor(((swSource[0] - srcWest) / pixelWidth) * srcWidth);
1040
+ const y0 = Math.floor(((srcNorth - neSource[1]) / pixelHeight) * srcHeight);
1041
+ const x1 = Math.ceil(((neSource[0] - srcWest) / pixelWidth) * srcWidth);
1042
+ const y1 = Math.ceil(((srcNorth - swSource[1]) / pixelHeight) * srcHeight);
1043
+ // Clamp to image bounds
1044
+ const windowX = Math.max(0, Math.min(x0, srcWidth));
1045
+ const windowY = Math.max(0, Math.min(y0, srcHeight));
1046
+ const windowWidth = Math.max(1, Math.min(x1 - x0, srcWidth - windowX));
1047
+ const windowHeight = Math.max(1, Math.min(y1 - y0, srcHeight - windowY));
1048
+ // Read elevation data from GeoTIFF
1049
+ const rasterData = await this.image.readRasters({
1050
+ window: [
1051
+ windowX,
1052
+ windowY,
1053
+ windowX + windowWidth,
1054
+ windowY + windowHeight,
1055
+ ],
1056
+ width: this.heightmapWidth,
1057
+ height: this.heightmapHeight,
1058
+ resampleMethod: 'bilinear',
1059
+ });
1060
+ // Convert to heightmap array (first band contains elevation)
1061
+ const elevationData = rasterData[0];
1062
+ const buffer = new Float32Array(this.heightmapWidth * this.heightmapHeight);
1063
+ for (let i = 0; i < buffer.length; i++) {
1064
+ let value = elevationData[i];
1065
+ // Replace nodata values with 0
1066
+ if (value === this.noDataValue || !isFinite(value)) {
1067
+ value = 0;
1068
+ }
1069
+ buffer[i] = value;
1070
+ }
1071
+ // Create Cesium HeightmapTerrainData
1072
+ return new this.Cesium.HeightmapTerrainData({
1073
+ buffer,
1074
+ width: this.heightmapWidth,
1075
+ height: this.heightmapHeight,
1076
+ childTileMask: 0,
1077
+ structure: {
1078
+ heightScale: 1.0,
1079
+ heightOffset: 0.0,
1080
+ elementsPerHeight: 1,
1081
+ stride: 1,
1082
+ elementMultiplier: 1.0,
1083
+ },
1084
+ });
1085
+ }
1086
+ catch (err) {
1087
+ messages.warn(`${LOG_PREFIX}failed to load tile geometry:`, err);
1088
+ return this.createFlatHeightmap();
1089
+ }
1090
+ }
1091
+ /**
1092
+ * Create a flat heightmap for tiles outside the GeoTIFF bounds
1093
+ */
1094
+ createFlatHeightmap() {
1095
+ const buffer = new Float32Array(this.heightmapWidth * this.heightmapHeight);
1096
+ buffer.fill(0);
1097
+ return new this.Cesium.HeightmapTerrainData({
1098
+ buffer,
1099
+ width: this.heightmapWidth,
1100
+ height: this.heightmapHeight,
1101
+ childTileMask: 0,
1102
+ });
1103
+ }
1104
+ /**
1105
+ * Get the availability of tiles
1106
+ */
1107
+ get availability() {
1108
+ // For now, we say all tiles are available
1109
+ // In a more sophisticated implementation, we'd track which tiles
1110
+ // intersect with the GeoTIFF bounds
1111
+ return undefined;
1112
+ }
1113
+ /**
1114
+ * Get the tiling scheme
1115
+ */
1116
+ getTilingScheme() {
1117
+ return this.tilingScheme;
1118
+ }
1119
+ /**
1120
+ * Get the maximum geometric error allowed at a specific level
1121
+ * Required by Cesium's TerrainProvider interface
1122
+ *
1123
+ * The geometric error is the difference (in meters) between the actual terrain
1124
+ * and the terrain approximation at this level. Higher levels have lower error.
1125
+ */
1126
+ getLevelMaximumGeometricError(level) {
1127
+ // Standard geometric error calculation for terrain providers
1128
+ // Based on Cesium's approach: error decreases exponentially with level
1129
+ // Formula: maximumRadius / (tileWidth * (2^level))
1130
+ const ellipsoid = this.tilingScheme.ellipsoid;
1131
+ const maximumRadius = ellipsoid.maximumRadius;
1132
+ const tileWidth = 65; // Standard heightmap width
1133
+ return maximumRadius / (tileWidth * Math.pow(2, level));
1134
+ }
1135
+ loadTileDataAvailability(_x, _y, _level) {
1136
+ return undefined;
1137
+ }
1138
+ /**
1139
+ * Check if tile data is available for a specific tile
1140
+ * Required by Cesium's TerrainProvider interface
1141
+ */
1142
+ getTileDataAvailable(x, y, level) {
1143
+ if (!this.ready) {
1144
+ return false;
1145
+ }
1146
+ // Check if tile intersects with GeoTIFF bounds
1147
+ const rectangle = this.tilingScheme.tileXYToRectangle(x, y, level);
1148
+ const west = this.Cesium.Math.toDegrees(rectangle.west);
1149
+ const south = this.Cesium.Math.toDegrees(rectangle.south);
1150
+ const east = this.Cesium.Math.toDegrees(rectangle.east);
1151
+ const north = this.Cesium.Math.toDegrees(rectangle.north);
1152
+ const [geoWest, geoSouth, geoEast, geoNorth] = this.wgs84Bounds;
1153
+ // Return true if tile intersects with GeoTIFF bounds
1154
+ return !(east < geoWest ||
1155
+ west > geoEast ||
1156
+ north < geoSouth ||
1157
+ south > geoNorth);
1158
+ }
1159
+ /**
1160
+ * Check if the provider is ready
1161
+ */
1162
+ get readyPromise() {
1163
+ return this._readyPromise;
1164
+ }
1165
+ /**
1166
+ * Get the credit to display
1167
+ */
1168
+ get credit() {
1169
+ return new this.Cesium.Credit('GeoTIFF Terrain');
1170
+ }
1171
+ /**
1172
+ * Check if the provider has water mask
1173
+ */
1174
+ get hasWaterMask() {
1175
+ return false;
1176
+ }
1177
+ /**
1178
+ * Check if the provider has vertex normals
1179
+ */
1180
+ get hasVertexNormals() {
1181
+ return false;
1182
+ }
1183
+ /**
1184
+ * Get the error event
1185
+ */
1186
+ get errorEvent() {
1187
+ return new this.Cesium.Event();
1188
+ }
1189
+ }
1190
+ /**
1191
+ * Factory function to create a CesiumGeoTIFFTerrainProvider
1192
+ */
1193
+ async function createCesiumGeoTIFFTerrainProvider(options) {
1194
+ const provider = new CesiumGeoTIFFTerrainProvider(options);
1195
+ await provider.readyPromise;
1196
+ return provider;
1197
+ }
1198
+
1199
+ // CesiumProvider.ts – relevante Ergänzungen
1200
+ const TERRAIN_GEOTIFF_LOG_PREFIX = 'v-map - cesium - terrain-geotiff - ';
1201
+ /**
1202
+ * Entfernt das von Cesium injectWidgetsCss() eingefügte CSS.
1203
+ * Funktioniert sowohl, wenn das Element eine ID hat,
1204
+ * als auch wenn es keine ID besitzt (neue Cesium‑Versionen).
1205
+ */
1206
+ function removeCesiumWidgetsCss(shadowRoot) {
1207
+ if (!shadowRoot)
1208
+ return;
1209
+ // NodeList → echtes Array konvertieren
1210
+ const styles = Array.from(shadowRoot.querySelectorAll('style'));
1211
+ for (const style of styles) {
1212
+ if (style.textContent?.includes('.cesium-credit-lightbox-overlay')) {
1213
+ style.remove(); // modernes DOM‑API
1214
+ // oder für sehr alte Browser:
1215
+ // style.parentNode?.removeChild(style);
1216
+ messages.log('v-map - provider - cesium - Cesium‑Widget‑CSS entfernt');
1217
+ break; // wir haben das gesuchte Style‑Tag gefunden
1218
+ }
1219
+ }
1220
+ }
1221
+ class CesiumTerrainLayer {
1222
+ Cesium;
1223
+ viewer;
1224
+ provider;
1225
+ options;
1226
+ opacity = 1;
1227
+ previousProvider;
1228
+ constructor(Cesium, viewer, provider, options) {
1229
+ this.Cesium = Cesium;
1230
+ this.viewer = viewer;
1231
+ this.provider = provider;
1232
+ this.options = options ?? {};
1233
+ this.previousProvider = viewer.terrainProvider;
1234
+ this.viewer.terrainProvider = this.provider;
1235
+ }
1236
+ getOptions() {
1237
+ return this.options;
1238
+ }
1239
+ setOptions(options) {
1240
+ this.options = options;
1241
+ }
1242
+ getVisible() {
1243
+ return this.viewer.scene.globe.show;
1244
+ }
1245
+ setVisible(value) {
1246
+ this.viewer.scene.globe.show = value;
1247
+ }
1248
+ getOpacity() {
1249
+ return this.opacity;
1250
+ }
1251
+ setOpacity(value) {
1252
+ this.opacity = value;
1253
+ const globe = this.viewer.scene.globe;
1254
+ if (!globe.translucency) {
1255
+ try {
1256
+ globe.translucency = new this.Cesium.GlobeTranslucency();
1257
+ globe.translucency.enabled = true;
1258
+ }
1259
+ catch (e) {
1260
+ messages.warn('Cesium terrain opacity not supported', e);
1261
+ return;
1262
+ }
1263
+ }
1264
+ globe.translucency.enabled = value < 1;
1265
+ globe.translucency.frontFaceAlpha = value;
1266
+ }
1267
+ getZIndex() {
1268
+ return 0;
1269
+ }
1270
+ async setZIndex(_zIndex) {
1271
+ return;
1272
+ }
1273
+ remove() {
1274
+ try {
1275
+ this.viewer.terrainProvider = this.previousProvider
1276
+ ? this.previousProvider
1277
+ : new this.Cesium.EllipsoidTerrainProvider();
1278
+ this.viewer.scene.globe.show = true;
1279
+ }
1280
+ catch (error) {
1281
+ messages.warn('Cesium terrain reset failed', error);
1282
+ }
1283
+ }
1284
+ }
1285
+ class CesiumProvider {
1286
+ viewer;
1287
+ Cesium;
1288
+ layerManager;
1289
+ shadowRoot;
1290
+ layerGroups = new CesiumLayerGroups();
1291
+ layerManagerMutex = new AsyncMutex();
1292
+ layerErrorCallbacks = new Map();
1293
+ layerErrorCleanups = new Map();
1294
+ async init(options) {
1295
+ this.shadowRoot = options.shadowRoot;
1296
+ const sr = options.target.getRootNode() instanceof ShadowRoot
1297
+ ? options.target.getRootNode()
1298
+ : undefined;
1299
+ await injectWidgetsCss(sr);
1300
+ this.Cesium = await loadCesium();
1301
+ /*
1302
+ this.viewer = new this.Cesium.Viewer(container, {
1303
+ terrainProvider: await this.Cesium.createWorldTerrainAsync(),
1304
+ ...options,
1305
+ });
1306
+ */
1307
+ Cesium.Ion.defaultAccessToken = null;
1308
+ this.viewer = new this.Cesium.Viewer(options.target, {
1309
+ baseLayer: false,
1310
+ baseLayerPicker: false, // Remove the base layer picker if you don’t need to switch layers
1311
+ terrainProvider: new Cesium.EllipsoidTerrainProvider(), // Use a simple ellipsoid terrain
1312
+ });
1313
+ //this.viewer.scene.terrainProvider..removeAll();
1314
+ this.viewer.scene.primitives.removeAll();
1315
+ this.viewer.scene.backgroundColor = this.Cesium.Color.WHITE;
1316
+ this.viewer.scene.globe.baseColor = this.Cesium.Color.WHITE;
1317
+ this.viewer.scene.globe.depthTestAgainstTerrain = false;
1318
+ // this.viewer.terrainProvider = null;
1319
+ /*
1320
+ if (options.center) {
1321
+ await this.viewer.camera.flyTo({
1322
+ destination: this.Cesium.Cartesian3.fromDegrees(
1323
+ options.center.longitude,
1324
+ options.center.latitude,
1325
+ 1000,
1326
+ ),
1327
+ });
1328
+ }
1329
+ */
1330
+ this.layerManager = new LayerManager(this.Cesium, this.viewer);
1331
+ }
1332
+ async destroy() {
1333
+ removeCesiumWidgetsCss(this.shadowRoot);
1334
+ this.viewer?.destroy();
1335
+ this.viewer = undefined;
1336
+ }
1337
+ async createLayer(layerConfig, layerId) {
1338
+ let wrapper = null;
1339
+ switch (layerConfig.type) {
1340
+ case 'geojson': {
1341
+ const options = {
1342
+ // clampToGround: true,
1343
+ //fill: Cesium.Color.RED,
1344
+ };
1345
+ const geojsonConfig = layerConfig;
1346
+ const ds = await this.createGeoJSONLayer(geojsonConfig, options);
1347
+ wrapper = this.layerManager.addLayer(layerId, ds);
1348
+ wrapper.setOptions(options);
1349
+ break;
1350
+ }
1351
+ case 'osm': {
1352
+ const iLayer = await this.createOSMLayer(layerConfig);
1353
+ wrapper = this.layerManager.addLayer(layerId, iLayer);
1354
+ break;
1355
+ }
1356
+ case 'google': {
1357
+ const iLayer = await this.createGoogleLayer(layerConfig);
1358
+ wrapper = this.layerManager.addLayer(layerId, iLayer);
1359
+ break;
1360
+ }
1361
+ case 'terrain': {
1362
+ const terrainLayer = await this.createTerrainLayer(layerConfig);
1363
+ wrapper = this.layerManager.addCustomLayer(layerId, terrainLayer);
1364
+ break;
1365
+ }
1366
+ case 'xyz': {
1367
+ const iLayer = await this.createXYZLayer(layerConfig);
1368
+ wrapper = this.layerManager.addLayer(layerId, iLayer);
1369
+ break;
1370
+ }
1371
+ case 'wms': {
1372
+ const iLayer = await this.addWMSLayer(layerConfig);
1373
+ wrapper = this.layerManager.addLayer(layerId, iLayer);
1374
+ break;
1375
+ }
1376
+ case 'wcs': {
1377
+ const iLayer = await this.createWCSLayer(layerConfig);
1378
+ wrapper = this.layerManager.addLayer(layerId, iLayer);
1379
+ break;
1380
+ }
1381
+ case 'arcgis': {
1382
+ await this.addArcGISLayer(layerConfig);
1383
+ //todo wrapper = this.layerManager.addLayer(layerId, iLayer);
1384
+ break;
1385
+ }
1386
+ case 'wfs': {
1387
+ const options = { clampToGround: true };
1388
+ const wfsConfig = layerConfig;
1389
+ const ds = await this.createWFSLayer(wfsConfig, options);
1390
+ wrapper = this.layerManager.addLayer(layerId, ds);
1391
+ wrapper.setOptions(options);
1392
+ break;
1393
+ }
1394
+ case 'wkt': {
1395
+ const options = { clampToGround: true };
1396
+ const wktConfig = layerConfig;
1397
+ const ds = await this.createWKTLayer(wktConfig, options);
1398
+ wrapper = this.layerManager.addLayer(layerId, ds);
1399
+ wrapper.setOptions(options);
1400
+ break;
1401
+ }
1402
+ case 'geotiff': {
1403
+ const iLayer = await this.createGeoTIFFLayer(layerConfig);
1404
+ wrapper = this.layerManager.addLayer(layerId, iLayer);
1405
+ break;
1406
+ }
1407
+ case 'tile3d': {
1408
+ const tileset = await this.createTile3DLayer(layerConfig);
1409
+ wrapper = this.layerManager.addLayer(layerId, tileset);
1410
+ const tile3dConfig = layerConfig;
1411
+ wrapper.setOptions(tile3dConfig.tilesetOptions ?? {});
1412
+ if (tile3dConfig.cesiumStyle && 'setStyle' in wrapper) {
1413
+ wrapper.setStyle(tile3dConfig.cesiumStyle);
1414
+ }
1415
+ break;
1416
+ }
1417
+ case 'terrain-geotiff': {
1418
+ const terrainLayer = await this.createGeoTIFFTerrainLayer(layerConfig);
1419
+ wrapper = this.layerManager.addCustomLayer(layerId, terrainLayer);
1420
+ break;
1421
+ }
1422
+ default:
1423
+ throw new Error(`Unsupported layer type: ${layerConfig.type}`);
1424
+ }
1425
+ if (!wrapper)
1426
+ return null;
1427
+ // zIndex/Opacity/Visible zuerst auf dem Layer anwenden (bleiben „Originalzustand“ der Gruppe)
1428
+ const commonProps = layerConfig;
1429
+ if (commonProps.zIndex !== undefined)
1430
+ await wrapper.setZIndex(commonProps.zIndex);
1431
+ if (commonProps.opacity !== undefined)
1432
+ wrapper.setOpacity(commonProps.opacity);
1433
+ if (commonProps.visible !== undefined)
1434
+ wrapper.setVisible(commonProps.visible);
1435
+ return wrapper;
1436
+ }
1437
+ // ---------- Layer anlegen (mit Group & Basemap-Key) ----------
1438
+ async addLayerToGroup(layerConfig) {
1439
+ return await this.layerManagerMutex.runExclusive(async () => {
1440
+ const layerId = crypto.randomUUID();
1441
+ const wrapper = await this.createLayer(layerConfig, layerId);
1442
+ // >>> In Gruppenverwaltung registrieren (inkl. Basemap-Key)
1443
+ const elementId = layerConfig.layerElementId ??
1444
+ layerConfig.elementId ??
1445
+ null;
1446
+ this.layerGroups.addLayerToGroup(layerConfig.groupId, typeof layerConfig.groupVisible !== undefined
1447
+ ? layerConfig.groupVisible
1448
+ : true, {
1449
+ id: layerId,
1450
+ elementId,
1451
+ layer: wrapper,
1452
+ });
1453
+ // Regeln anwenden (sichtbar/basemap)
1454
+ this.layerGroups.apply();
1455
+ return layerId;
1456
+ });
1457
+ }
1458
+ // ---------- Basemap-API analog deck ----------
1459
+ async setBaseLayer(groupId, layerElementId) {
1460
+ await this.layerManagerMutex.runExclusive(async () => {
1461
+ this.layerGroups.setBasemap(groupId, layerElementId ?? null);
1462
+ this.layerGroups.apply();
1463
+ });
1464
+ }
1465
+ // Optional: Helper wie in deck.addBaseLayer(...)
1466
+ async addBaseLayer(layerConfig, basemapid, layerElementId) {
1467
+ if (!layerElementId || !basemapid)
1468
+ return null;
1469
+ return await this.layerManagerMutex.runExclusive(async () => {
1470
+ const layerId = crypto.randomUUID();
1471
+ const wrapper = await this.createLayer(layerConfig, layerId);
1472
+ this.layerGroups.addLayerToGroup(layerConfig.groupId, typeof layerConfig.groupVisible !== undefined
1473
+ ? layerConfig.groupVisible
1474
+ : true, {
1475
+ id: layerId,
1476
+ elementId: layerElementId,
1477
+ layer: wrapper,
1478
+ });
1479
+ this.layerGroups.setBasemap(layerConfig.groupId ?? 'basemap', basemapid);
1480
+ this.layerGroups.apply();
1481
+ return layerId;
1482
+ });
1483
+ }
1484
+ async ensureGroup(groupId, visible, _opts) {
1485
+ this.layerGroups.ensureGroup(groupId, visible);
1486
+ }
1487
+ // ---------- Sichtbarkeit/Z-Index/Opacity bleiben wie gehabt ----------
1488
+ async setGroupVisible(groupId, visible) {
1489
+ this.layerGroups.setGroupVisible(groupId, visible);
1490
+ this.layerGroups.apply();
1491
+ }
1492
+ // ── Runtime error listeners ──────────────────────────────────────
1493
+ onLayerError(layerId, callback) {
1494
+ this.layerErrorCallbacks.set(layerId, callback);
1495
+ this.attachCesiumErrorListeners(layerId);
1496
+ }
1497
+ offLayerError(layerId) {
1498
+ this.layerErrorCleanups.get(layerId)?.();
1499
+ this.layerErrorCleanups.delete(layerId);
1500
+ this.layerErrorCallbacks.delete(layerId);
1501
+ }
1502
+ attachCesiumErrorListeners(layerId) {
1503
+ this.layerErrorCleanups.get(layerId)?.();
1504
+ const cb = this.layerErrorCallbacks.get(layerId);
1505
+ if (!cb)
1506
+ return;
1507
+ const iLayer = this.layerManager.getLayer(layerId);
1508
+ if (!iLayer)
1509
+ return;
1510
+ const cleanups = [];
1511
+ const handler = () => { cb({ type: 'network', message: 'Tile load error' }); };
1512
+ // ImageryLayer: access provider.errorEvent
1513
+ const nativeLayer = iLayer._imageryLayer;
1514
+ if (nativeLayer?.imageryProvider?.errorEvent) {
1515
+ const unsub = nativeLayer.imageryProvider.errorEvent.addEventListener(handler);
1516
+ cleanups.push(unsub);
1517
+ }
1518
+ // Cesium3DTileset: tileFailed event
1519
+ const tileset = iLayer._tileset;
1520
+ if (tileset?.tileFailed) {
1521
+ const unsub = tileset.tileFailed.addEventListener(handler);
1522
+ cleanups.push(unsub);
1523
+ }
1524
+ if (cleanups.length > 0) {
1525
+ this.layerErrorCleanups.set(layerId, () => cleanups.forEach(fn => fn()));
1526
+ }
1527
+ }
1528
+ async removeLayer(layerId) {
1529
+ if (!layerId)
1530
+ return;
1531
+ this.offLayerError(layerId);
1532
+ await this.layerManagerMutex.runExclusive(async () => {
1533
+ this.layerManager.removeLayer(layerId);
1534
+ this.layerGroups.removeLayer(layerId, true);
1535
+ this.layerGroups.apply();
1536
+ });
1537
+ }
1538
+ // updateLayer, setOpacity, setZIndex, setVisible bleiben – du änderst damit den
1539
+ // „Originalzustand“ der Layer. Danach LayerGroups.apply() aufrufen, damit
1540
+ // Gruppen-/Basemap-Regeln sofort wieder durchgesetzt werden:
1541
+ async setOpacity(layerId, opacity) {
1542
+ this.layerManager.setOpacity(layerId, opacity);
1543
+ this.layerGroups.apply();
1544
+ }
1545
+ async setVisible(layerId, visible) {
1546
+ this.layerManager.setVisible(layerId, visible);
1547
+ this.layerGroups.apply();
1548
+ }
1549
+ async setZIndex(layerId, zIndex) {
1550
+ // Note: layerManager.setZIndex calls layer.setZIndex which is async (returns Promise<void>)
1551
+ // even though the manager method itself is not marked as async. The await is kept here
1552
+ // for future compatibility when the manager method becomes properly async.
1553
+ await this.layerManager.setZIndex(layerId, zIndex);
1554
+ // Z-Order ist unabhängig von Basemap/Group-Visible, aber apply() schadet nicht
1555
+ this.layerGroups.apply();
1556
+ }
1557
+ // ========== Enhanced Styling Helper Methods ==========
1558
+ /**
1559
+ * Apply Geostyler styling to a GeoJsonDataSource
1560
+ */
1561
+ applyGeostylerStyling(dataSource, geostylerStyle) {
1562
+ dataSource.__vmapLockOpacity = true;
1563
+ // Helper to extract static value from GeoStyler property
1564
+ const getValue = (prop, defaultValue) => {
1565
+ if (prop === undefined || prop === null)
1566
+ return defaultValue;
1567
+ // If it's a GeoStyler function object, we can't evaluate it here - return default
1568
+ if (typeof prop === 'object' && prop !== null && 'name' in prop)
1569
+ return defaultValue;
1570
+ return prop;
1571
+ };
1572
+ const toNumber = (value, fallback) => {
1573
+ if (value == null)
1574
+ return fallback;
1575
+ if (typeof value === 'number')
1576
+ return value;
1577
+ const n = Number(value);
1578
+ return Number.isFinite(n) ? n : fallback;
1579
+ };
1580
+ const entities = dataSource.entities.values;
1581
+ if (geostylerStyle.rules) {
1582
+ for (const rule of geostylerStyle.rules) {
1583
+ if (rule.symbolizers) {
1584
+ for (const symbolizer of rule.symbolizers) {
1585
+ for (let i = 0; i < entities.length; i++) {
1586
+ const entity = entities[i];
1587
+ switch (symbolizer.kind) {
1588
+ case 'Fill':
1589
+ if (entity.polygon) {
1590
+ const fillColor = getValue(symbolizer.color, 'rgba(0,100,255,0.3)');
1591
+ const fillOpacity = toNumber(getValue(symbolizer.opacity, 0.3), 0.3);
1592
+ const outlineColor = getValue(symbolizer.outlineColor, 'rgba(0,100,255,1)');
1593
+ const outlineWidth = getValue(symbolizer.outlineWidth, 1);
1594
+ let polygonColor = this.parseCesiumColor(fillColor, this.Cesium.Color.BLUE.withAlpha(0.3));
1595
+ if (fillOpacity !== undefined && fillOpacity !== null) {
1596
+ polygonColor = this.applyCesiumOpacity(polygonColor, fillOpacity);
1597
+ }
1598
+ //outline color
1599
+ const outlineCesiumColor = this.parseCesiumColor(outlineColor, this.Cesium.Color.BLUE);
1600
+ messages.log('v-map - provider - cesium - applyGeostylerStyling: Fill', {
1601
+ fillColor,
1602
+ fillOpacity,
1603
+ computedFill: polygonColor?.toString?.(),
1604
+ outlineColor,
1605
+ outlineWidth,
1606
+ });
1607
+ //fill
1608
+ entity.polygon.fill = new this.Cesium.ConstantProperty(true);
1609
+ //fill color
1610
+ entity.polygon.material =
1611
+ new this.Cesium.ColorMaterialProperty(polygonColor);
1612
+ //outline
1613
+ entity.polygon.outline = new this.Cesium.ConstantProperty(true);
1614
+ entity.polygon.outlineColor =
1615
+ new this.Cesium.ConstantProperty(outlineCesiumColor);
1616
+ entity.polygon.outlineWidth =
1617
+ new this.Cesium.ConstantProperty(outlineWidth);
1618
+ //entity.polygon.height = new this.Cesium.ConstantProperty(0);
1619
+ //
1620
+ entity.polygon.extrudedHeight = undefined;
1621
+ entity.polygon.heightReference =
1622
+ new this.Cesium.ConstantProperty(this.Cesium.HeightReference.CLAMP_TO_GROUND);
1623
+ entity.polygon.perPositionHeight =
1624
+ new this.Cesium.ConstantProperty(false);
1625
+ entity.polygon.classificationType =
1626
+ new this.Cesium.ConstantProperty(this.Cesium.ClassificationType.BOTH);
1627
+ }
1628
+ break;
1629
+ case 'Line':
1630
+ if (entity.polyline) {
1631
+ const lineColor = getValue(symbolizer.color, 'rgba(0,100,255,1)');
1632
+ const lineWidth = toNumber(getValue(symbolizer.width, 2), 2);
1633
+ const lineOpacity = toNumber(getValue(symbolizer.opacity, 1), 1);
1634
+ let materialColor = this.parseCesiumColor(lineColor, this.Cesium.Color.BLUE);
1635
+ if (lineOpacity !== undefined && lineOpacity !== null) {
1636
+ materialColor = this.applyCesiumOpacity(materialColor, lineOpacity);
1637
+ }
1638
+ messages.log('v-map - provider - cesium - applyGeostylerStyling: Line', {
1639
+ lineColor,
1640
+ lineOpacity,
1641
+ computedColor: materialColor?.toString?.(),
1642
+ lineWidth,
1643
+ });
1644
+ entity.polyline.material =
1645
+ new this.Cesium.ColorMaterialProperty(materialColor);
1646
+ entity.polyline.width = new this.Cesium.ConstantProperty(lineWidth);
1647
+ }
1648
+ break;
1649
+ case 'Mark':
1650
+ if (entity.point) {
1651
+ const pointColor = getValue(symbolizer.color, 'rgba(0,100,255,1)');
1652
+ const pointRadius = toNumber(getValue(symbolizer.radius, 6), 6);
1653
+ const pointOpacity = toNumber(getValue(symbolizer.opacity, 1), 1);
1654
+ let materialColor = this.parseCesiumColor(pointColor, this.Cesium.Color.BLUE);
1655
+ if (pointOpacity !== undefined && pointOpacity !== null) {
1656
+ materialColor = this.applyCesiumOpacity(materialColor, pointOpacity);
1657
+ }
1658
+ messages.log('v-map - provider - cesium - applyGeostylerStyling: Mark', {
1659
+ pointColor,
1660
+ pointOpacity,
1661
+ computedColor: materialColor?.toString?.(),
1662
+ pointRadius,
1663
+ });
1664
+ entity.point.color = new this.Cesium.ConstantProperty(materialColor);
1665
+ entity.point.pixelSize = new this.Cesium.ConstantProperty(pointRadius);
1666
+ }
1667
+ break;
1668
+ case 'Icon':
1669
+ if (entity.point) {
1670
+ const iconSrc = getValue(symbolizer.image);
1671
+ const iconSize = toNumber(getValue(symbolizer.size, 32), 32);
1672
+ const iconOpacity = toNumber(getValue(symbolizer.opacity, 1), 1);
1673
+ if (iconSrc && typeof iconSrc === 'string') {
1674
+ entity.billboard = new this.Cesium.BillboardGraphics({
1675
+ image: new this.Cesium.ConstantProperty(iconSrc),
1676
+ width: new this.Cesium.ConstantProperty(iconSize),
1677
+ height: new this.Cesium.ConstantProperty(iconSize),
1678
+ verticalOrigin: new this.Cesium.ConstantProperty(this.Cesium.VerticalOrigin.BOTTOM),
1679
+ color: iconOpacity !== undefined && iconOpacity !== null
1680
+ ? new this.Cesium.ConstantProperty(this.Cesium.Color.WHITE.withAlpha(iconOpacity))
1681
+ : undefined,
1682
+ });
1683
+ entity.point.show = new this.Cesium.ConstantProperty(false);
1684
+ messages.log('v-map - provider - cesium - applyGeostylerStyling: Icon', {
1685
+ iconSrc,
1686
+ iconSize,
1687
+ iconOpacity,
1688
+ });
1689
+ }
1690
+ }
1691
+ break;
1692
+ case 'Text':
1693
+ const labelExpr = symbolizer.label;
1694
+ const labelProp = typeof labelExpr === 'string' ? labelExpr : undefined;
1695
+ if (labelProp &&
1696
+ entity.properties &&
1697
+ entity.properties[labelProp]) {
1698
+ const textColor = getValue(symbolizer.color, '#000000');
1699
+ const textSize = toNumber(getValue(symbolizer.size, 12), 12);
1700
+ const textOpacity = toNumber(getValue(symbolizer.opacity, 1), 1);
1701
+ let labelColor = this.parseCesiumColor(textColor, this.Cesium.Color.WHITE);
1702
+ if (textOpacity !== undefined && textOpacity !== null) {
1703
+ labelColor = this.applyCesiumOpacity(labelColor, textOpacity);
1704
+ }
1705
+ messages.log('v-map - provider - cesium - applyGeostylerStyling: Text', {
1706
+ labelProp,
1707
+ textColor,
1708
+ textOpacity,
1709
+ computedColor: labelColor?.toString?.(),
1710
+ textSize,
1711
+ });
1712
+ const textValue = entity.properties[labelProp]?.getValue?.(this.viewer.clock.currentTime) ??
1713
+ entity.properties[labelProp]?._value ??
1714
+ '';
1715
+ entity.label = new this.Cesium.LabelGraphics({
1716
+ text: new this.Cesium.ConstantProperty(String(textValue)),
1717
+ font: new this.Cesium.ConstantProperty(`${textSize}px Arial`),
1718
+ fillColor: new this.Cesium.ConstantProperty(labelColor),
1719
+ verticalOrigin: new this.Cesium.ConstantProperty(this.Cesium.VerticalOrigin.BOTTOM),
1720
+ });
1721
+ }
1722
+ break;
1723
+ }
1724
+ }
1725
+ }
1726
+ }
1727
+ }
1728
+ }
1729
+ }
1730
+ /**
1731
+ * Convert CSS color to Cesium Color
1732
+ */
1733
+ parseCesiumColor(color, defaultColor) {
1734
+ if (!color)
1735
+ return defaultColor;
1736
+ // Handle hex colors
1737
+ if (color.startsWith('#')) {
1738
+ return this.Cesium.Color.fromCssColorString(color);
1739
+ }
1740
+ // Handle rgba/rgb colors
1741
+ if (color.includes('rgb')) {
1742
+ return this.Cesium.Color.fromCssColorString(color);
1743
+ }
1744
+ // Try to parse as CSS color string
1745
+ try {
1746
+ return this.Cesium.Color.fromCssColorString(color);
1747
+ }
1748
+ catch {
1749
+ return defaultColor;
1750
+ }
1751
+ }
1752
+ /**
1753
+ * Apply opacity to Cesium color
1754
+ */
1755
+ applyCesiumOpacity(color, opacity) {
1756
+ if (!color)
1757
+ return color;
1758
+ return color.withAlpha(opacity);
1759
+ }
1760
+ /**
1761
+ * Create Cesium styling options from StyleConfig
1762
+ */
1763
+ createCesiumStyle(style = {}) {
1764
+ // Default colors
1765
+ const defaultFillColor = this.Cesium.Color.BLUE.withAlpha(0.3);
1766
+ const defaultStrokeColor = this.Cesium.Color.BLUE;
1767
+ const defaultPointColor = this.Cesium.Color.BLUE;
1768
+ // Parse colors
1769
+ const fillColor = this.parseCesiumColor(style.fillColor, defaultFillColor);
1770
+ const strokeColor = this.parseCesiumColor(style.strokeColor, defaultStrokeColor);
1771
+ const pointColor = this.parseCesiumColor(style.pointColor, defaultPointColor);
1772
+ // Apply opacity
1773
+ const finalFillColor = style.fillOpacity !== undefined
1774
+ ? this.applyCesiumOpacity(fillColor, style.fillOpacity)
1775
+ : fillColor;
1776
+ const finalStrokeColor = style.strokeOpacity !== undefined
1777
+ ? this.applyCesiumOpacity(strokeColor, style.strokeOpacity)
1778
+ : strokeColor;
1779
+ const finalPointColor = style.pointOpacity !== undefined
1780
+ ? this.applyCesiumOpacity(pointColor, style.pointOpacity)
1781
+ : pointColor;
1782
+ return {
1783
+ // Polygon styling
1784
+ fill: true,
1785
+ fillColor: finalFillColor,
1786
+ outline: true,
1787
+ outlineColor: finalStrokeColor,
1788
+ outlineWidth: style.strokeWidth ?? 2,
1789
+ extrudedHeight: style.extrudeHeight,
1790
+ heightReference: style.zOffset
1791
+ ? this.Cesium.HeightReference.RELATIVE_TO_GROUND
1792
+ : this.Cesium.HeightReference.CLAMP_TO_GROUND,
1793
+ // Point styling
1794
+ pixelSize: style.pointRadius ?? 8,
1795
+ color: finalPointColor,
1796
+ scaleByDistance: style.pointRadius
1797
+ ? new this.Cesium.NearFarScalar(1.5e2, 2.0, 1.5e7, 0.5)
1798
+ : undefined,
1799
+ // Line styling
1800
+ width: style.strokeWidth ?? 2,
1801
+ clampToGround: !style.zOffset,
1802
+ // Text/Label styling
1803
+ labelText: style.textProperty,
1804
+ labelFont: style.textSize
1805
+ ? `${style.textSize}pt monospace`
1806
+ : '12pt monospace',
1807
+ labelFillColor: style.textColor
1808
+ ? this.parseCesiumColor(style.textColor, this.Cesium.Color.WHITE)
1809
+ : this.Cesium.Color.WHITE,
1810
+ labelOutlineColor: style.textHaloColor
1811
+ ? this.parseCesiumColor(style.textHaloColor, this.Cesium.Color.BLACK)
1812
+ : this.Cesium.Color.BLACK,
1813
+ labelOutlineWidth: style.textHaloWidth ?? 1,
1814
+ labelPixelOffset: style.textOffset
1815
+ ? new this.Cesium.Cartesian2(style.textOffset[0], style.textOffset[1])
1816
+ : this.Cesium.Cartesian2.ZERO,
1817
+ // 3D specific
1818
+ height: style.zOffset ?? 0,
1819
+ };
1820
+ }
1821
+ /**
1822
+ * Apply enhanced styling to a GeoJsonDataSource
1823
+ */
1824
+ applyEnhancedStyling(dataSource, style = {}) {
1825
+ const cesiumStyle = this.createCesiumStyle(style);
1826
+ const entities = dataSource.entities.values;
1827
+ for (let i = 0; i < entities.length; i++) {
1828
+ const entity = entities[i];
1829
+ let finalStyle = cesiumStyle;
1830
+ if (style.styleFunction && entity.properties) {
1831
+ const feature = {
1832
+ properties: entity.properties._propertyNames.reduce((props, name) => {
1833
+ props[name] = entity.properties[name]?._value;
1834
+ return props;
1835
+ }, {}),
1836
+ geometry: entity,
1837
+ };
1838
+ const conditionalStyle = style.styleFunction(feature);
1839
+ if (conditionalStyle) {
1840
+ finalStyle = {
1841
+ ...cesiumStyle,
1842
+ ...this.createCesiumStyle(conditionalStyle),
1843
+ };
1844
+ }
1845
+ }
1846
+ if (entity.polygon) {
1847
+ entity.polygon.fill = new this.Cesium.ConstantProperty(finalStyle.fill);
1848
+ entity.polygon.material = new this.Cesium.ColorMaterialProperty(finalStyle.fillColor);
1849
+ entity.polygon.outline = new this.Cesium.ConstantProperty(finalStyle.outline);
1850
+ entity.polygon.outlineColor = new this.Cesium.ConstantProperty(finalStyle.outlineColor);
1851
+ entity.polygon.outlineWidth = new this.Cesium.ConstantProperty(finalStyle.outlineWidth);
1852
+ entity.polygon.height =
1853
+ finalStyle.height !== undefined
1854
+ ? new this.Cesium.ConstantProperty(finalStyle.height)
1855
+ : undefined;
1856
+ entity.polygon.extrudedHeight =
1857
+ finalStyle.extrudedHeight !== undefined
1858
+ ? new this.Cesium.ConstantProperty(finalStyle.extrudedHeight)
1859
+ : undefined;
1860
+ entity.polygon.heightReference =
1861
+ finalStyle.heightReference !== undefined
1862
+ ? new this.Cesium.ConstantProperty(finalStyle.heightReference)
1863
+ : undefined;
1864
+ }
1865
+ if (entity.polyline) {
1866
+ entity.polyline.material = new this.Cesium.ColorMaterialProperty(finalStyle.outlineColor);
1867
+ entity.polyline.width = new this.Cesium.ConstantProperty(finalStyle.width);
1868
+ entity.polyline.clampToGround = new this.Cesium.ConstantProperty(finalStyle.clampToGround);
1869
+ }
1870
+ if (entity.point) {
1871
+ entity.point.pixelSize = new this.Cesium.ConstantProperty(finalStyle.pixelSize);
1872
+ entity.point.color = new this.Cesium.ConstantProperty(finalStyle.color);
1873
+ const scaleByDistance = finalStyle.scaleByDistance;
1874
+ entity.point.scaleByDistance = scaleByDistance
1875
+ ? new this.Cesium.ConstantProperty(scaleByDistance)
1876
+ : undefined;
1877
+ if (style.iconUrl) {
1878
+ entity.billboard = new this.Cesium.BillboardGraphics({
1879
+ image: new this.Cesium.ConstantProperty(style.iconUrl),
1880
+ width: new this.Cesium.ConstantProperty(style.iconSize ? style.iconSize[0] : 32),
1881
+ height: new this.Cesium.ConstantProperty(style.iconSize ? style.iconSize[1] : 32),
1882
+ verticalOrigin: new this.Cesium.ConstantProperty(this.Cesium.VerticalOrigin.BOTTOM),
1883
+ scaleByDistance: scaleByDistance
1884
+ ? new this.Cesium.ConstantProperty(scaleByDistance)
1885
+ : undefined,
1886
+ });
1887
+ entity.point.show = new this.Cesium.ConstantProperty(false);
1888
+ }
1889
+ }
1890
+ if (style.textProperty &&
1891
+ entity.properties &&
1892
+ entity.properties[style.textProperty]) {
1893
+ const textValue = entity.properties[style.textProperty]?.getValue?.(this.viewer.clock.currentTime) ??
1894
+ entity.properties[style.textProperty]?._value ??
1895
+ '';
1896
+ entity.label = new this.Cesium.LabelGraphics({
1897
+ text: new this.Cesium.ConstantProperty(String(textValue)),
1898
+ font: new this.Cesium.ConstantProperty(finalStyle.labelFont),
1899
+ fillColor: new this.Cesium.ConstantProperty(finalStyle.labelFillColor),
1900
+ outlineColor: new this.Cesium.ConstantProperty(finalStyle.labelOutlineColor),
1901
+ outlineWidth: new this.Cesium.ConstantProperty(finalStyle.labelOutlineWidth),
1902
+ pixelOffset: new this.Cesium.ConstantProperty(finalStyle.labelPixelOffset),
1903
+ verticalOrigin: new this.Cesium.ConstantProperty(this.Cesium.VerticalOrigin.BOTTOM),
1904
+ });
1905
+ }
1906
+ }
1907
+ }
1908
+ async createWKTLayer(config, options) {
1909
+ const geoJsonData = await this.wktToGeoJSON(config);
1910
+ const dataSource = await this.Cesium.GeoJsonDataSource.load(geoJsonData, options);
1911
+ // Apply geostyler style if provided, otherwise use enhanced styling
1912
+ if (config.geostylerStyle) {
1913
+ this.applyGeostylerStyling(dataSource, config.geostylerStyle);
1914
+ }
1915
+ else if (config.style) {
1916
+ this.applyEnhancedStyling(dataSource, config.style);
1917
+ }
1918
+ return dataSource;
1919
+ }
1920
+ async wktToGeoJSON(config) {
1921
+ const wktText = await this.resolveWktText(config);
1922
+ const wellknownModule = await Promise.resolve().then(function () { return require('./index-BIL4VsgP.js'); }).then(function (n) { return n.index; });
1923
+ const parseFn = typeof wellknownModule.default === 'function'
1924
+ ? wellknownModule.default
1925
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- wellknown has inconsistent module exports across bundlers
1926
+ : wellknownModule.parse;
1927
+ if (typeof parseFn !== 'function') {
1928
+ throw new Error('wellknown parser not available');
1929
+ }
1930
+ const geometry = parseFn(wktText);
1931
+ if (!geometry) {
1932
+ throw new Error('Failed to parse WKT');
1933
+ }
1934
+ return {
1935
+ type: 'FeatureCollection',
1936
+ features: [
1937
+ {
1938
+ type: 'Feature',
1939
+ properties: {},
1940
+ geometry,
1941
+ },
1942
+ ],
1943
+ };
1944
+ }
1945
+ async resolveWktText(config) {
1946
+ if (config.wkt)
1947
+ return config.wkt;
1948
+ if (config.url) {
1949
+ const response = await fetch(config.url);
1950
+ if (!response.ok)
1951
+ throw new Error(`Failed to fetch WKT: ${response.status}`);
1952
+ return await response.text();
1953
+ }
1954
+ throw new Error('Either wkt or url must be provided');
1955
+ }
1956
+ async createGeoJSONLayer(config, options) {
1957
+ let geojson_or_url = null;
1958
+ if (config.geojson) {
1959
+ geojson_or_url = JSON.parse(config.geojson);
1960
+ }
1961
+ else {
1962
+ geojson_or_url = config.url;
1963
+ }
1964
+ //https://cesium.com/learn/ion-sdk/ref-doc/GeoJsonDataSource.html
1965
+ const dataSource = await this.Cesium.GeoJsonDataSource.load(geojson_or_url, options);
1966
+ // Apply geostyler style if provided, otherwise use enhanced styling
1967
+ if (config.geostylerStyle) {
1968
+ this.applyGeostylerStyling(dataSource, config.geostylerStyle);
1969
+ }
1970
+ else if (config.style) {
1971
+ this.applyEnhancedStyling(dataSource, config.style);
1972
+ }
1973
+ return dataSource;
1974
+ }
1975
+ async createWFSLayer(config, options) {
1976
+ // Fetch GeoJSON from WFS server
1977
+ const geojson = await this.fetchWFSFromUrl(config);
1978
+ // Load GeoJSON into Cesium DataSource
1979
+ const dataSource = await this.Cesium.GeoJsonDataSource.load(geojson, options);
1980
+ // Apply geostyler style if provided, otherwise use enhanced styling
1981
+ if (config.geostylerStyle) {
1982
+ this.applyGeostylerStyling(dataSource, config.geostylerStyle);
1983
+ }
1984
+ else if (config.style) {
1985
+ this.applyEnhancedStyling(dataSource, config.style);
1986
+ }
1987
+ return dataSource;
1988
+ }
1989
+ async createOSMLayer(cfg) {
1990
+ return new this.Cesium.ImageryLayer(new this.Cesium.OpenStreetMapImageryProvider({
1991
+ url: cfg.url || 'https://a.tile.openstreetmap.org',
1992
+ }));
1993
+ }
1994
+ async createGoogleLayer(config) {
1995
+ if (!config.apiKey) {
1996
+ throw new Error("Google-Layer benötigt 'apiKey' (Google Maps Platform).");
1997
+ }
1998
+ // Load Google Maps JavaScript API
1999
+ await this.loadGoogleMapsApi(config.apiKey, {
2000
+ language: config.language,
2001
+ region: config.region,
2002
+ libraries: config.libraries,
2003
+ });
2004
+ const mapType = config.mapType || 'roadmap';
2005
+ const googleMapTypeId = this.getGoogleMapTypeId(mapType);
2006
+ // Use a simpler approach with UrlTemplateImageryProvider and custom URL generator
2007
+ const Cesium = this.Cesium;
2008
+ // Create a custom URL template that we'll handle in the urlSchemeZeroPadding function
2009
+ const customUrlTemplate = 'https://maps.googleapis.com/maps/api/staticmap?template';
2010
+ const googleImageryProvider = new Cesium.UrlTemplateImageryProvider({
2011
+ url: customUrlTemplate,
2012
+ maximumLevel: config.maxZoom || 19,
2013
+ minimumLevel: 0,
2014
+ tilingScheme: new Cesium.WebMercatorTilingScheme(),
2015
+ credit: 'Google Maps',
2016
+ // Override URL generation using urlSchemeZeroPadding as a custom URL builder
2017
+ urlSchemeZeroPadding: {
2018
+ '{x}': '',
2019
+ '{y}': '',
2020
+ '{z}': '',
2021
+ },
2022
+ });
2023
+ // Override the buildImageResource method to use Google Static Maps API
2024
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- monkey-patching internal Cesium method not exposed in typings
2025
+ googleImageryProvider.buildImageResource = function (x, y, level) {
2026
+ const tilingScheme = new Cesium.WebMercatorTilingScheme();
2027
+ const rectangle = tilingScheme.tileXYToRectangle(x, y, level);
2028
+ const west = Cesium.Math.toDegrees(rectangle.west);
2029
+ const south = Cesium.Math.toDegrees(rectangle.south);
2030
+ const east = Cesium.Math.toDegrees(rectangle.east);
2031
+ const north = Cesium.Math.toDegrees(rectangle.north);
2032
+ // Center point of the tile
2033
+ const centerLat = (south + north) / 2;
2034
+ const centerLng = (west + east) / 2;
2035
+ // Build Google Static Maps API URL
2036
+ const params = new URLSearchParams({
2037
+ center: `${centerLat},${centerLng}`,
2038
+ zoom: level.toString(),
2039
+ size: '256x256',
2040
+ scale: config.scale === 'scaleFactor1x' ? '1' : '2',
2041
+ maptype: googleMapTypeId,
2042
+ key: config.apiKey,
2043
+ format: 'png',
2044
+ });
2045
+ if (config.language) {
2046
+ params.set('language', config.language);
2047
+ }
2048
+ if (config.region) {
2049
+ params.set('region', config.region);
2050
+ }
2051
+ const url = `https://maps.googleapis.com/maps/api/staticmap?${params.toString()}`;
2052
+ return new Cesium.Resource({ url });
2053
+ };
2054
+ // Add Google logo for compliance
2055
+ this.ensureGoogleLogo();
2056
+ return new this.Cesium.ImageryLayer(googleImageryProvider, {
2057
+ alpha: config.opacity ?? 1,
2058
+ show: config.visible ?? true,
2059
+ });
2060
+ }
2061
+ getGoogleMapTypeId(mapType) {
2062
+ switch (mapType) {
2063
+ case 'roadmap':
2064
+ return 'roadmap';
2065
+ case 'satellite':
2066
+ return 'satellite';
2067
+ case 'terrain':
2068
+ return 'terrain';
2069
+ case 'hybrid':
2070
+ return 'hybrid';
2071
+ default:
2072
+ return 'roadmap';
2073
+ }
2074
+ }
2075
+ /**
2076
+ * Load Google Maps JavaScript API
2077
+ */
2078
+ async loadGoogleMapsApi(apiKey, opts) {
2079
+ const w = window;
2080
+ const mockLoader = w.__mockGoogleMapsApi;
2081
+ if (typeof mockLoader === 'function') {
2082
+ await mockLoader(apiKey, opts);
2083
+ return;
2084
+ }
2085
+ if (w.google?.maps)
2086
+ return;
2087
+ await new Promise((resolve, reject) => {
2088
+ const cbName = '___cesiumGoogleInit___' + Math.random().toString(36).slice(2);
2089
+ w[cbName] = () => resolve();
2090
+ const script = document.createElement('script');
2091
+ const params = new URLSearchParams({
2092
+ key: apiKey,
2093
+ callback: cbName,
2094
+ v: 'weekly',
2095
+ });
2096
+ if (opts?.language)
2097
+ params.set('language', opts.language);
2098
+ if (opts?.region)
2099
+ params.set('region', opts.region);
2100
+ if (opts?.libraries?.length)
2101
+ params.set('libraries', opts.libraries.join(','));
2102
+ script.src = `https://maps.googleapis.com/maps/api/js?${params.toString()}`;
2103
+ script.async = true;
2104
+ script.onerror = () => reject(new Error('Google Maps JS API failed to load'));
2105
+ document.head.appendChild(script);
2106
+ });
2107
+ }
2108
+ /**
2109
+ * Add Google logo for compliance
2110
+ */
2111
+ ensureGoogleLogo() {
2112
+ if (!this.viewer?.container ||
2113
+ this.viewer.container._googleLogoAdded)
2114
+ return;
2115
+ const logo = document.createElement('img');
2116
+ logo.src =
2117
+ 'https://developers.google.com/static/maps/documentation/images/google_on_white.png';
2118
+ logo.alt = 'Google';
2119
+ logo.style.position = 'absolute';
2120
+ logo.style.bottom = '6px';
2121
+ logo.style.left = '6px';
2122
+ logo.style.height = '18px';
2123
+ logo.style.pointerEvents = 'none';
2124
+ logo.style.zIndex = '1000';
2125
+ this.viewer.container.appendChild(logo);
2126
+ this.viewer.container._googleLogoAdded = true;
2127
+ }
2128
+ async createXYZLayer(config) {
2129
+ if (!config.url) {
2130
+ throw new Error('XYZ layer requires a url');
2131
+ }
2132
+ const credit = Array.isArray(config.attributions)
2133
+ ? config.attributions.join(', ')
2134
+ : config.attributions;
2135
+ const providerOptions = {
2136
+ url: config.url,
2137
+ credit,
2138
+ maximumLevel: config.maxZoom,
2139
+ ...(config.options || {}),
2140
+ };
2141
+ const provider = new this.Cesium.UrlTemplateImageryProvider(providerOptions);
2142
+ const layerOptions = {
2143
+ alpha: config.opacity ?? 1,
2144
+ show: config.visible ?? true,
2145
+ };
2146
+ return new this.Cesium.ImageryLayer(provider, layerOptions);
2147
+ }
2148
+ async createTerrainLayer(config) {
2149
+ let provider;
2150
+ if (config.elevationData) {
2151
+ provider = await this.Cesium.CesiumTerrainProvider.fromUrl(config.elevationData);
2152
+ }
2153
+ else {
2154
+ provider = await this.Cesium.createWorldTerrainAsync();
2155
+ }
2156
+ const layer = new CesiumTerrainLayer(this.Cesium, this.viewer, provider, config);
2157
+ if (config.visible !== undefined) {
2158
+ layer.setVisible(config.visible);
2159
+ }
2160
+ if (config.opacity !== undefined) {
2161
+ layer.setOpacity(config.opacity);
2162
+ }
2163
+ return layer;
2164
+ }
2165
+ /**
2166
+ * Create GeoTIFF Terrain Layer
2167
+ * Loads GeoTIFF elevation data and provides it as terrain
2168
+ */
2169
+ async createGeoTIFFTerrainLayer(config) {
2170
+ // If no URL is set, return a fallback layer with EllipsoidTerrainProvider
2171
+ if (!config.url) {
2172
+ messages.log(`${TERRAIN_GEOTIFF_LOG_PREFIX}layer created without URL, waiting for URL to load`);
2173
+ const fallbackProvider = new this.Cesium.EllipsoidTerrainProvider();
2174
+ const layer = new CesiumTerrainLayer(this.Cesium, this.viewer, fallbackProvider, config);
2175
+ // Set to invisible since there's no terrain data
2176
+ layer.setVisible(false);
2177
+ return layer;
2178
+ }
2179
+ try {
2180
+ messages.log(`${TERRAIN_GEOTIFF_LOG_PREFIX}create layer: url=${config.url}`);
2181
+ // Create the custom GeoTIFF terrain provider
2182
+ const provider = await createCesiumGeoTIFFTerrainProvider({
2183
+ url: config.url,
2184
+ projection: config.projection,
2185
+ forceProjection: config.forceProjection,
2186
+ nodata: config.nodata,
2187
+ Cesium: this.Cesium,
2188
+ });
2189
+ // Wrap it in a CesiumTerrainLayer
2190
+ // Cast config to terrain type since CesiumTerrainLayer expects it
2191
+ const layer = new CesiumTerrainLayer(this.Cesium, this.viewer, provider, config);
2192
+ if (config.visible !== undefined) {
2193
+ layer.setVisible(config.visible);
2194
+ }
2195
+ if (config.opacity !== undefined) {
2196
+ layer.setOpacity(config.opacity);
2197
+ }
2198
+ messages.log(`${TERRAIN_GEOTIFF_LOG_PREFIX}layer created successfully`);
2199
+ return layer;
2200
+ }
2201
+ catch (err) {
2202
+ messages.error(`${TERRAIN_GEOTIFF_LOG_PREFIX}failed to create terrain layer:`, err);
2203
+ // Return a fallback with EllipsoidTerrainProvider
2204
+ const fallbackProvider = new this.Cesium.EllipsoidTerrainProvider();
2205
+ return new CesiumTerrainLayer(this.Cesium, this.viewer, fallbackProvider, config);
2206
+ }
2207
+ }
2208
+ async addWMSLayer(config) {
2209
+ return new this.Cesium.ImageryLayer(new this.Cesium.WebMapServiceImageryProvider({
2210
+ url: config.url,
2211
+ layers: config.layers,
2212
+ parameters: config.extraParams,
2213
+ }));
2214
+ }
2215
+ /**
2216
+ * Create WCS (Web Coverage Service) ImageryLayer
2217
+ * Supports WCS 2.0.1 (subset) and 1.x.x (BBOX) versions
2218
+ */
2219
+ async createWCSLayer(config) {
2220
+ if (!config.url || !config.coverageName) {
2221
+ throw new Error('WCS layer requires url and coverageName');
2222
+ }
2223
+ const version = config.version ?? '2.0.1';
2224
+ const format = config.format ?? 'image/tiff';
2225
+ const projection = config.projection ?? 'EPSG:4326';
2226
+ const tileSize = config.tileSize ?? 256;
2227
+ const Cesium = this.Cesium;
2228
+ // Create a custom URL template - will be overridden by buildImageResource
2229
+ const customUrlTemplate = `${config.url}?wcs_placeholder`;
2230
+ const wcsImageryProvider = new Cesium.UrlTemplateImageryProvider({
2231
+ url: customUrlTemplate,
2232
+ maximumLevel: config.maxZoom ?? 18,
2233
+ minimumLevel: config.minZoom ?? 0,
2234
+ tileWidth: tileSize,
2235
+ tileHeight: tileSize,
2236
+ tilingScheme: new Cesium.GeographicTilingScheme(),
2237
+ credit: 'WCS',
2238
+ });
2239
+ // Override the buildImageResource method to generate WCS GetCoverage URLs
2240
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- monkey-patching internal Cesium method not exposed in typings
2241
+ wcsImageryProvider.buildImageResource = function (x, y, level) {
2242
+ const tilingScheme = new Cesium.GeographicTilingScheme();
2243
+ const rectangle = tilingScheme.tileXYToRectangle(x, y, level);
2244
+ // Convert to degrees
2245
+ const west = Cesium.Math.toDegrees(rectangle.west);
2246
+ const south = Cesium.Math.toDegrees(rectangle.south);
2247
+ const east = Cesium.Math.toDegrees(rectangle.east);
2248
+ const north = Cesium.Math.toDegrees(rectangle.north);
2249
+ const baseParams = {
2250
+ SERVICE: 'WCS',
2251
+ REQUEST: 'GetCoverage',
2252
+ VERSION: version,
2253
+ FORMAT: format,
2254
+ };
2255
+ let url;
2256
+ // WCS 2.0.1 uses subset parameters
2257
+ if (version.startsWith('2.0')) {
2258
+ const params = {
2259
+ ...baseParams,
2260
+ coverageId: config.coverageName,
2261
+ ...(config.params || {}),
2262
+ };
2263
+ // Add GeoTIFF compression if format is tiff
2264
+ if (format.includes('tiff') || format.includes('geotiff')) {
2265
+ params['geotiff:compression'] = 'LZW';
2266
+ }
2267
+ // Build query string
2268
+ const query = new URLSearchParams();
2269
+ Object.entries(params).forEach(([key, value]) => {
2270
+ if (value !== undefined && value !== null) {
2271
+ query.set(key, String(value));
2272
+ }
2273
+ });
2274
+ const queryString = query.toString();
2275
+ const subsetX = `subset=X(${west},${east})`;
2276
+ const subsetY = `subset=Y(${south},${north})`;
2277
+ url = `${config.url}${config.url.includes('?') ? '&' : '?'}${queryString}&${subsetX}&${subsetY}`;
2278
+ }
2279
+ // WCS 1.x.x uses BBOX parameter
2280
+ else {
2281
+ const params = {
2282
+ ...baseParams,
2283
+ COVERAGE: config.coverageName,
2284
+ BBOX: `${west},${south},${east},${north}`,
2285
+ CRS: projection,
2286
+ WIDTH: String(tileSize),
2287
+ HEIGHT: String(tileSize),
2288
+ ...(config.params || {}),
2289
+ };
2290
+ const query = new URLSearchParams();
2291
+ Object.entries(params).forEach(([key, value]) => {
2292
+ if (value !== undefined && value !== null) {
2293
+ query.set(key, String(value));
2294
+ }
2295
+ });
2296
+ url = `${config.url}${config.url.includes('?') ? '&' : '?'}${query.toString()}`;
2297
+ }
2298
+ return new Cesium.Resource({ url });
2299
+ };
2300
+ return new this.Cesium.ImageryLayer(wcsImageryProvider, {
2301
+ alpha: config.opacity ?? 1,
2302
+ show: config.visible ?? true,
2303
+ });
2304
+ }
2305
+ async addArcGISLayer(config) {
2306
+ //"https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer"
2307
+ const provider = await this.Cesium.ArcGisMapServerImageryProvider.fromUrl(config.url);
2308
+ this.viewer.imageryLayers.addImageryProvider(provider);
2309
+ }
2310
+ async createGeoTIFFLayer(config) {
2311
+ if (!config.url) {
2312
+ throw new Error('GeoTIFF layer requires a URL');
2313
+ }
2314
+ // The GeoTIFFImageryProvider always uses WebMercatorTilingScheme,
2315
+ // so the tile processor must reproject into EPSG:3857 to match
2316
+ // the tile coordinate math (x,y,z → bounds).
2317
+ const viewProjection = 'EPSG:3857';
2318
+ try {
2319
+ const geotiffExtra = config;
2320
+ const source = await geotiffSource.getGeoTIFFSource(config.url, geotiffExtra.projection, geotiffExtra.forceProjection, config.nodata);
2321
+ const tileProcessorConfig = await geotiffSource.getTileProcessorConfig(source, viewProjection);
2322
+ const tileProcessor = new geotiffSource.GeoTIFFTileProcessor(tileProcessorConfig);
2323
+ tileProcessor.createGlobalTriangulation();
2324
+ let colorStops;
2325
+ if (config.colorMap) {
2326
+ const { stops } = geotiffSource.getColorStops(config.colorMap, config.valueRange);
2327
+ colorStops = stops;
2328
+ }
2329
+ const geotiffRenderExtra = config;
2330
+ const tileSize = geotiffRenderExtra.tileSize ?? 256;
2331
+ const resolution = geotiffRenderExtra.resolution ?? 1.0;
2332
+ const resampleMethod = geotiffRenderExtra.resampleMethod ?? 'bilinear';
2333
+ const imageryProvider = new GeoTIFFImageryProvider({
2334
+ Cesium: this.Cesium,
2335
+ rectangleDegrees: source.wgs84Bounds,
2336
+ tileProcessor,
2337
+ tileSize,
2338
+ resolution,
2339
+ resampleMethod,
2340
+ colorStops,
2341
+ });
2342
+ const layer = new this.Cesium.ImageryLayer(imageryProvider, {
2343
+ alpha: config.opacity ?? 1.0,
2344
+ show: config.visible ?? true,
2345
+ });
2346
+ layer.__vmapGeoTIFFMeta = {
2347
+ url: config.url,
2348
+ width: source.width,
2349
+ height: source.height,
2350
+ samplesPerPixel: source.samplesPerPixel,
2351
+ noData: source.noDataValue,
2352
+ };
2353
+ return layer;
2354
+ }
2355
+ catch (err) {
2356
+ messages.error('v-map - provider - cesium - Failed to create GeoTIFF layer', err);
2357
+ // Return a placeholder layer in case of error
2358
+ const provider = new this.Cesium.SingleTileImageryProvider({
2359
+ url: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
2360
+ rectangle: this.Cesium.Rectangle.fromDegrees(-180, -90, 180, 90),
2361
+ });
2362
+ return new this.Cesium.ImageryLayer(provider, {
2363
+ alpha: 0,
2364
+ show: false,
2365
+ });
2366
+ }
2367
+ }
2368
+ async createTile3DLayer(config) {
2369
+ if (!config.url) {
2370
+ throw new Error('Tile3D layer requires a URL');
2371
+ }
2372
+ const tileset = await this.Cesium.Cesium3DTileset.fromUrl(config.url, config.tilesetOptions ?? {});
2373
+ if (config.cesiumStyle) {
2374
+ tileset.style = new this.Cesium.Cesium3DTileStyle(config.cesiumStyle);
2375
+ }
2376
+ return tileset;
2377
+ }
2378
+ async updateLayer(layerId, update) {
2379
+ return await this.layerManagerMutex.runExclusive(async () => {
2380
+ const hadErrorListener = this.layerErrorCallbacks.has(layerId);
2381
+ if (hadErrorListener)
2382
+ this.offLayerError(layerId);
2383
+ const oldLayer = this.layerManager.getLayer(layerId);
2384
+ switch (update.type) {
2385
+ case 'geojson':
2386
+ {
2387
+ const data = update.data;
2388
+ const options = oldLayer.getOptions();
2389
+ const dataSource = await this.createGeoJSONLayer({
2390
+ geojson: data.geojson,
2391
+ url: data.url,
2392
+ style: data.style,
2393
+ geostylerStyle: data.geostylerStyle,
2394
+ }, options);
2395
+ const layer = this.layerManager.replaceLayer(layerId, oldLayer, dataSource);
2396
+ layer.setOptions(options);
2397
+ }
2398
+ break;
2399
+ case 'wfs':
2400
+ {
2401
+ const data = update.data;
2402
+ const options = oldLayer.getOptions();
2403
+ const dataSource = await this.createWFSLayer(data, options);
2404
+ const layer = this.layerManager.replaceLayer(layerId, oldLayer, dataSource);
2405
+ layer.setOptions(options);
2406
+ }
2407
+ break;
2408
+ case 'osm':
2409
+ {
2410
+ const osmOptions = oldLayer.getOptions();
2411
+ const osmLayer = new this.Cesium.ImageryLayer(new this.Cesium.OpenStreetMapImageryProvider({
2412
+ url: update.data.url || 'https://a.tile.openstreetmap.org',
2413
+ }));
2414
+ const updatedOsmlayer = this.layerManager.replaceLayer(layerId, oldLayer, osmLayer);
2415
+ updatedOsmlayer.setOptions(osmOptions);
2416
+ }
2417
+ break;
2418
+ case 'google':
2419
+ {
2420
+ const googleOptions = oldLayer.getOptions();
2421
+ const googleLayer = await this.createGoogleLayer(update.data);
2422
+ const updatedGoogleLayer = this.layerManager.replaceLayer(layerId, oldLayer, googleLayer);
2423
+ updatedGoogleLayer.setOptions(googleOptions);
2424
+ }
2425
+ break;
2426
+ case 'xyz':
2427
+ {
2428
+ const xyzOptions = oldLayer.getOptions();
2429
+ const xyzLayer = await this.createXYZLayer(update.data);
2430
+ const updatedXyzLayer = this.layerManager.replaceLayer(layerId, oldLayer, xyzLayer);
2431
+ updatedXyzLayer.setOptions(xyzOptions);
2432
+ }
2433
+ break;
2434
+ case 'wcs':
2435
+ {
2436
+ const wcsOptions = oldLayer.getOptions();
2437
+ const wcsLayer = await this.createWCSLayer(update.data);
2438
+ const updatedWcsLayer = this.layerManager.replaceLayer(layerId, oldLayer, wcsLayer);
2439
+ updatedWcsLayer.setOptions(wcsOptions);
2440
+ }
2441
+ break;
2442
+ case 'wkt':
2443
+ {
2444
+ const data = update.data;
2445
+ const options = oldLayer.getOptions();
2446
+ const dataSource = await this.createWKTLayer({
2447
+ wkt: data.wkt,
2448
+ url: data.url,
2449
+ style: data.style,
2450
+ geostylerStyle: data.geostylerStyle,
2451
+ }, options);
2452
+ const layer = this.layerManager.replaceLayer(layerId, oldLayer, dataSource);
2453
+ layer.setOptions(options);
2454
+ }
2455
+ break;
2456
+ case 'geotiff':
2457
+ {
2458
+ const data = update.data;
2459
+ const iLayer = await this.createGeoTIFFLayer({
2460
+ url: data.url,
2461
+ });
2462
+ this.layerManager.replaceLayer(layerId, oldLayer, iLayer);
2463
+ }
2464
+ break;
2465
+ case 'tile3d':
2466
+ {
2467
+ const data = update.data ?? {};
2468
+ if (!data.url) {
2469
+ throw new Error('tile3d update requires a url');
2470
+ }
2471
+ const layer = await this.createTile3DLayer({
2472
+ type: 'tile3d',
2473
+ url: data.url,
2474
+ tilesetOptions: data.tilesetOptions,
2475
+ cesiumStyle: data.cesiumStyle,
2476
+ });
2477
+ const updatedLayer = this.layerManager.replaceLayer(layerId, oldLayer, layer);
2478
+ updatedLayer.setOptions(data.tilesetOptions ?? {});
2479
+ if (data.cesiumStyle && 'setStyle' in updatedLayer) {
2480
+ updatedLayer.setStyle(data.cesiumStyle);
2481
+ }
2482
+ }
2483
+ break;
2484
+ case 'tile3d-style':
2485
+ {
2486
+ const data = update.data ?? {};
2487
+ if ('setStyle' in oldLayer) {
2488
+ const stylePayload = data.style ?? {};
2489
+ oldLayer.setStyle(stylePayload);
2490
+ }
2491
+ }
2492
+ break;
2493
+ case 'terrain':
2494
+ {
2495
+ const previousOptions = oldLayer.getOptions();
2496
+ const visible = oldLayer.getVisible();
2497
+ const opacity = oldLayer.getOpacity();
2498
+ oldLayer.remove();
2499
+ const terrainLayer = await this.createTerrainLayer({
2500
+ type: 'terrain',
2501
+ ...previousOptions,
2502
+ ...(update.data ?? {}),
2503
+ });
2504
+ const wrapped = this.layerManager.addCustomLayer(layerId, terrainLayer);
2505
+ wrapped.setVisible(visible);
2506
+ wrapped.setOpacity(opacity);
2507
+ }
2508
+ break;
2509
+ case 'terrain-geotiff':
2510
+ {
2511
+ //const previousOptions = oldLayer.getOptions();
2512
+ //const visible = oldLayer.getVisible();
2513
+ //const opacity = oldLayer.getOpacity();
2514
+ oldLayer.remove();
2515
+ const terrainLayer = await this.createGeoTIFFTerrainLayer({
2516
+ type: 'terrain-geotiff',
2517
+ ...(update.data ?? {}),
2518
+ });
2519
+ this.layerManager.addCustomLayer(layerId, terrainLayer);
2520
+ //wrapped.setVisible(visible);
2521
+ //wrapped.setOpacity(opacity);
2522
+ }
2523
+ break;
2524
+ }
2525
+ // Re-attach error listeners after layer replacement
2526
+ if (hadErrorListener)
2527
+ this.attachCesiumErrorListeners(layerId);
2528
+ });
2529
+ }
2530
+ async setView(center, zoom) {
2531
+ if (!this.viewer)
2532
+ return;
2533
+ const [lon, lat] = center;
2534
+ this.viewer.camera.flyTo({
2535
+ destination: this.Cesium.Cartesian3.fromDegrees(lon, lat, 1000000 / zoom),
2536
+ duration: 2.0, // Sekunden, anpassbar
2537
+ orientation: {
2538
+ heading: this.Cesium.Math.toRadians(0.0), // Blickrichtung nach Norden
2539
+ pitch: this.Cesium.Math.toRadians(-30), // leicht nach unten schauen
2540
+ roll: 0.0,
2541
+ },
2542
+ // optional: onComplete / onCancel callbacks
2543
+ complete: () => messages.log('v-map - provider - cesium - Fly‑to finished'),
2544
+ cancel: () => messages.warn('v-map - provider - cesium - Fly‑to cancelled'),
2545
+ });
2546
+ }
2547
+ async fetchWFSFromUrl(config) {
2548
+ const baseParams = {
2549
+ service: 'WFS',
2550
+ request: 'GetFeature',
2551
+ version: config.version ?? '1.1.0',
2552
+ typeName: config.typeName,
2553
+ outputFormat: config.outputFormat ?? 'application/json',
2554
+ srsName: config.srsName ?? 'EPSG:4326',
2555
+ };
2556
+ const params = { ...baseParams, ...(config.params ?? {}) };
2557
+ const requestUrl = this.appendParams(config.url, params);
2558
+ const response = await fetch(requestUrl);
2559
+ if (!response.ok) {
2560
+ throw new Error(`WFS request failed (${response.status} ${response.statusText})`);
2561
+ }
2562
+ const outputFormat = (config.outputFormat ?? 'application/json').toLowerCase();
2563
+ // Handle JSON formats
2564
+ if (outputFormat.includes('json') ||
2565
+ outputFormat.includes('geojson') ||
2566
+ outputFormat === 'application/json') {
2567
+ const contentType = response.headers.get('content-type');
2568
+ if (contentType?.includes('application/json')) {
2569
+ return await response.json();
2570
+ }
2571
+ // Try to parse as JSON anyway
2572
+ const text = await response.text();
2573
+ return JSON.parse(text);
2574
+ }
2575
+ // Handle GML formats - parse XML to GeoJSON using @npm9912/s-gml
2576
+ if (outputFormat.includes('gml') || outputFormat.includes('xml')) {
2577
+ const xml = await response.text();
2578
+ const { GmlParser } = await Promise.resolve().then(function () { return require('./index.browser-DQhD8Jwl.js'); });
2579
+ const parser = new GmlParser();
2580
+ return await parser.parse(xml);
2581
+ }
2582
+ // Default: try to parse as JSON
2583
+ return await response.json();
2584
+ }
2585
+ appendParams(baseUrl, params) {
2586
+ const query = new URLSearchParams();
2587
+ Object.entries(params).forEach(([key, value]) => {
2588
+ if (value !== undefined && value !== null) {
2589
+ query.set(key, String(value));
2590
+ }
2591
+ });
2592
+ if (!query.toString())
2593
+ return baseUrl;
2594
+ return `${baseUrl}${baseUrl.includes('?') ? '&' : '?'}${query.toString()}`;
2595
+ }
2596
+ }
2597
+
2598
+ exports.CesiumProvider = CesiumProvider;