@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,1408 @@
1
+ // CesiumProvider.ts – relevante Ergänzungen
2
+ import { CesiumLayerGroups } from "./CesiumLayerGroups";
3
+ import { LayerManager } from "./layer-manager";
4
+ import { log, warn, error } from "../../utils/logger";
5
+ import { loadCesium, injectWidgetsCss } from "../../lib/cesium-loader";
6
+ import { AsyncMutex } from "../../utils/async-mutex";
7
+ import { getColorStops } from "../geotiff/utils/colormap-utils";
8
+ import { GeoTIFFTileProcessor, getTileProcessorConfig, } from "../geotiff/utils/GeoTIFFTileProcessor";
9
+ import { getGeoTIFFSource } from "../geotiff/geotiff-source";
10
+ import { GeoTIFFImageryProvider } from "./GeoTIFFImageryProvider";
11
+ import { createCesiumGeoTIFFTerrainProvider } from "./CesiumGeoTIFFTerrainProvider";
12
+ const TERRAIN_GEOTIFF_LOG_PREFIX = 'v-map - cesium - terrain-geotiff - ';
13
+ /**
14
+ * Entfernt das von Cesium injectWidgetsCss() eingefügte CSS.
15
+ * Funktioniert sowohl, wenn das Element eine ID hat,
16
+ * als auch wenn es keine ID besitzt (neue Cesium‑Versionen).
17
+ */
18
+ function removeCesiumWidgetsCss(shadowRoot) {
19
+ if (!shadowRoot)
20
+ return;
21
+ // NodeList → echtes Array konvertieren
22
+ const styles = Array.from(shadowRoot.querySelectorAll('style'));
23
+ for (const style of styles) {
24
+ if (style.textContent?.includes('.cesium-credit-lightbox-overlay')) {
25
+ style.remove(); // modernes DOM‑API
26
+ // oder für sehr alte Browser:
27
+ // style.parentNode?.removeChild(style);
28
+ log('v-map - provider - cesium - Cesium‑Widget‑CSS entfernt');
29
+ break; // wir haben das gesuchte Style‑Tag gefunden
30
+ }
31
+ }
32
+ }
33
+ class CesiumTerrainLayer {
34
+ Cesium;
35
+ viewer;
36
+ provider;
37
+ options;
38
+ opacity = 1;
39
+ previousProvider;
40
+ constructor(Cesium, viewer, provider, options) {
41
+ this.Cesium = Cesium;
42
+ this.viewer = viewer;
43
+ this.provider = provider;
44
+ this.options = options ?? {};
45
+ this.previousProvider = viewer.terrainProvider;
46
+ this.viewer.terrainProvider = this.provider;
47
+ }
48
+ getOptions() {
49
+ return this.options;
50
+ }
51
+ setOptions(options) {
52
+ this.options = options;
53
+ }
54
+ getVisible() {
55
+ return this.viewer.scene.globe.show;
56
+ }
57
+ setVisible(value) {
58
+ this.viewer.scene.globe.show = value;
59
+ }
60
+ getOpacity() {
61
+ return this.opacity;
62
+ }
63
+ setOpacity(value) {
64
+ this.opacity = value;
65
+ const globe = this.viewer.scene.globe;
66
+ if (!globe.translucency) {
67
+ try {
68
+ globe.translucency = new this.Cesium.GlobeTranslucency();
69
+ globe.translucency.enabled = true;
70
+ }
71
+ catch (e) {
72
+ warn('Cesium terrain opacity not supported', e);
73
+ return;
74
+ }
75
+ }
76
+ globe.translucency.enabled = value < 1;
77
+ globe.translucency.frontFaceAlpha = value;
78
+ }
79
+ getZIndex() {
80
+ return 0;
81
+ }
82
+ async setZIndex(_zIndex) {
83
+ return;
84
+ }
85
+ remove() {
86
+ try {
87
+ this.viewer.terrainProvider = this.previousProvider
88
+ ? this.previousProvider
89
+ : new this.Cesium.EllipsoidTerrainProvider();
90
+ this.viewer.scene.globe.show = true;
91
+ }
92
+ catch (error) {
93
+ warn('Cesium terrain reset failed', error);
94
+ }
95
+ }
96
+ }
97
+ export class CesiumProvider {
98
+ viewer;
99
+ Cesium;
100
+ layerManager;
101
+ shadowRoot;
102
+ layerGroups = new CesiumLayerGroups();
103
+ layerManagerMutex = new AsyncMutex();
104
+ layerErrorCallbacks = new Map();
105
+ layerErrorCleanups = new Map();
106
+ async init(options) {
107
+ this.shadowRoot = options.shadowRoot;
108
+ const sr = options.target.getRootNode() instanceof ShadowRoot
109
+ ? options.target.getRootNode()
110
+ : undefined;
111
+ await injectWidgetsCss(sr);
112
+ this.Cesium = await loadCesium();
113
+ /*
114
+ this.viewer = new this.Cesium.Viewer(container, {
115
+ terrainProvider: await this.Cesium.createWorldTerrainAsync(),
116
+ ...options,
117
+ });
118
+ */
119
+ Cesium.Ion.defaultAccessToken = null;
120
+ this.viewer = new this.Cesium.Viewer(options.target, {
121
+ baseLayer: false,
122
+ baseLayerPicker: false, // Remove the base layer picker if you don’t need to switch layers
123
+ terrainProvider: new Cesium.EllipsoidTerrainProvider(), // Use a simple ellipsoid terrain
124
+ });
125
+ //this.viewer.scene.terrainProvider..removeAll();
126
+ this.viewer.scene.primitives.removeAll();
127
+ this.viewer.scene.backgroundColor = this.Cesium.Color.WHITE;
128
+ this.viewer.scene.globe.baseColor = this.Cesium.Color.WHITE;
129
+ this.viewer.scene.globe.depthTestAgainstTerrain = false;
130
+ // this.viewer.terrainProvider = null;
131
+ /*
132
+ if (options.center) {
133
+ await this.viewer.camera.flyTo({
134
+ destination: this.Cesium.Cartesian3.fromDegrees(
135
+ options.center.longitude,
136
+ options.center.latitude,
137
+ 1000,
138
+ ),
139
+ });
140
+ }
141
+ */
142
+ this.layerManager = new LayerManager(this.Cesium, this.viewer);
143
+ }
144
+ async destroy() {
145
+ removeCesiumWidgetsCss(this.shadowRoot);
146
+ this.viewer?.destroy();
147
+ this.viewer = undefined;
148
+ }
149
+ async createLayer(layerConfig, layerId) {
150
+ let wrapper = null;
151
+ switch (layerConfig.type) {
152
+ case 'geojson': {
153
+ const options = {
154
+ // clampToGround: true,
155
+ //fill: Cesium.Color.RED,
156
+ };
157
+ const geojsonConfig = layerConfig;
158
+ const ds = await this.createGeoJSONLayer(geojsonConfig, options);
159
+ wrapper = this.layerManager.addLayer(layerId, ds);
160
+ wrapper.setOptions(options);
161
+ break;
162
+ }
163
+ case 'osm': {
164
+ const iLayer = await this.createOSMLayer(layerConfig);
165
+ wrapper = this.layerManager.addLayer(layerId, iLayer);
166
+ break;
167
+ }
168
+ case 'google': {
169
+ const iLayer = await this.createGoogleLayer(layerConfig);
170
+ wrapper = this.layerManager.addLayer(layerId, iLayer);
171
+ break;
172
+ }
173
+ case 'terrain': {
174
+ const terrainLayer = await this.createTerrainLayer(layerConfig);
175
+ wrapper = this.layerManager.addCustomLayer(layerId, terrainLayer);
176
+ break;
177
+ }
178
+ case 'xyz': {
179
+ const iLayer = await this.createXYZLayer(layerConfig);
180
+ wrapper = this.layerManager.addLayer(layerId, iLayer);
181
+ break;
182
+ }
183
+ case 'wms': {
184
+ const iLayer = await this.addWMSLayer(layerConfig);
185
+ wrapper = this.layerManager.addLayer(layerId, iLayer);
186
+ break;
187
+ }
188
+ case 'wcs': {
189
+ const iLayer = await this.createWCSLayer(layerConfig);
190
+ wrapper = this.layerManager.addLayer(layerId, iLayer);
191
+ break;
192
+ }
193
+ case 'arcgis': {
194
+ await this.addArcGISLayer(layerConfig);
195
+ //todo wrapper = this.layerManager.addLayer(layerId, iLayer);
196
+ break;
197
+ }
198
+ case 'wfs': {
199
+ const options = { clampToGround: true };
200
+ const wfsConfig = layerConfig;
201
+ const ds = await this.createWFSLayer(wfsConfig, options);
202
+ wrapper = this.layerManager.addLayer(layerId, ds);
203
+ wrapper.setOptions(options);
204
+ break;
205
+ }
206
+ case 'wkt': {
207
+ const options = { clampToGround: true };
208
+ const wktConfig = layerConfig;
209
+ const ds = await this.createWKTLayer(wktConfig, options);
210
+ wrapper = this.layerManager.addLayer(layerId, ds);
211
+ wrapper.setOptions(options);
212
+ break;
213
+ }
214
+ case 'geotiff': {
215
+ const iLayer = await this.createGeoTIFFLayer(layerConfig);
216
+ wrapper = this.layerManager.addLayer(layerId, iLayer);
217
+ break;
218
+ }
219
+ case 'tile3d': {
220
+ const tileset = await this.createTile3DLayer(layerConfig);
221
+ wrapper = this.layerManager.addLayer(layerId, tileset);
222
+ const tile3dConfig = layerConfig;
223
+ wrapper.setOptions(tile3dConfig.tilesetOptions ?? {});
224
+ if (tile3dConfig.cesiumStyle && 'setStyle' in wrapper) {
225
+ wrapper.setStyle(tile3dConfig.cesiumStyle);
226
+ }
227
+ break;
228
+ }
229
+ case 'terrain-geotiff': {
230
+ const terrainLayer = await this.createGeoTIFFTerrainLayer(layerConfig);
231
+ wrapper = this.layerManager.addCustomLayer(layerId, terrainLayer);
232
+ break;
233
+ }
234
+ default:
235
+ throw new Error(`Unsupported layer type: ${layerConfig.type}`);
236
+ }
237
+ if (!wrapper)
238
+ return null;
239
+ // zIndex/Opacity/Visible zuerst auf dem Layer anwenden (bleiben „Originalzustand“ der Gruppe)
240
+ const commonProps = layerConfig;
241
+ if (commonProps.zIndex !== undefined)
242
+ await wrapper.setZIndex(commonProps.zIndex);
243
+ if (commonProps.opacity !== undefined)
244
+ wrapper.setOpacity(commonProps.opacity);
245
+ if (commonProps.visible !== undefined)
246
+ wrapper.setVisible(commonProps.visible);
247
+ return wrapper;
248
+ }
249
+ // ---------- Layer anlegen (mit Group & Basemap-Key) ----------
250
+ async addLayerToGroup(layerConfig) {
251
+ return await this.layerManagerMutex.runExclusive(async () => {
252
+ const layerId = crypto.randomUUID();
253
+ const wrapper = await this.createLayer(layerConfig, layerId);
254
+ // >>> In Gruppenverwaltung registrieren (inkl. Basemap-Key)
255
+ const elementId = layerConfig.layerElementId ??
256
+ layerConfig.elementId ??
257
+ null;
258
+ this.layerGroups.addLayerToGroup(layerConfig.groupId, typeof layerConfig.groupVisible !== undefined
259
+ ? layerConfig.groupVisible
260
+ : true, {
261
+ id: layerId,
262
+ elementId,
263
+ layer: wrapper,
264
+ });
265
+ // Regeln anwenden (sichtbar/basemap)
266
+ this.layerGroups.apply();
267
+ return layerId;
268
+ });
269
+ }
270
+ // ---------- Basemap-API analog deck ----------
271
+ async setBaseLayer(groupId, layerElementId) {
272
+ await this.layerManagerMutex.runExclusive(async () => {
273
+ this.layerGroups.setBasemap(groupId, layerElementId ?? null);
274
+ this.layerGroups.apply();
275
+ });
276
+ }
277
+ // Optional: Helper wie in deck.addBaseLayer(...)
278
+ async addBaseLayer(layerConfig, basemapid, layerElementId) {
279
+ if (!layerElementId || !basemapid)
280
+ return null;
281
+ return await this.layerManagerMutex.runExclusive(async () => {
282
+ const layerId = crypto.randomUUID();
283
+ const wrapper = await this.createLayer(layerConfig, layerId);
284
+ this.layerGroups.addLayerToGroup(layerConfig.groupId, typeof layerConfig.groupVisible !== undefined
285
+ ? layerConfig.groupVisible
286
+ : true, {
287
+ id: layerId,
288
+ elementId: layerElementId,
289
+ layer: wrapper,
290
+ });
291
+ this.layerGroups.setBasemap(layerConfig.groupId ?? 'basemap', basemapid);
292
+ this.layerGroups.apply();
293
+ return layerId;
294
+ });
295
+ }
296
+ async ensureGroup(groupId, visible, _opts) {
297
+ this.layerGroups.ensureGroup(groupId, visible);
298
+ }
299
+ // ---------- Sichtbarkeit/Z-Index/Opacity bleiben wie gehabt ----------
300
+ async setGroupVisible(groupId, visible) {
301
+ this.layerGroups.setGroupVisible(groupId, visible);
302
+ this.layerGroups.apply();
303
+ }
304
+ // ── Runtime error listeners ──────────────────────────────────────
305
+ onLayerError(layerId, callback) {
306
+ this.layerErrorCallbacks.set(layerId, callback);
307
+ this.attachCesiumErrorListeners(layerId);
308
+ }
309
+ offLayerError(layerId) {
310
+ this.layerErrorCleanups.get(layerId)?.();
311
+ this.layerErrorCleanups.delete(layerId);
312
+ this.layerErrorCallbacks.delete(layerId);
313
+ }
314
+ attachCesiumErrorListeners(layerId) {
315
+ this.layerErrorCleanups.get(layerId)?.();
316
+ const cb = this.layerErrorCallbacks.get(layerId);
317
+ if (!cb)
318
+ return;
319
+ const iLayer = this.layerManager.getLayer(layerId);
320
+ if (!iLayer)
321
+ return;
322
+ const cleanups = [];
323
+ const handler = () => { cb({ type: 'network', message: 'Tile load error' }); };
324
+ // ImageryLayer: access provider.errorEvent
325
+ const nativeLayer = iLayer._imageryLayer;
326
+ if (nativeLayer?.imageryProvider?.errorEvent) {
327
+ const unsub = nativeLayer.imageryProvider.errorEvent.addEventListener(handler);
328
+ cleanups.push(unsub);
329
+ }
330
+ // Cesium3DTileset: tileFailed event
331
+ const tileset = iLayer._tileset;
332
+ if (tileset?.tileFailed) {
333
+ const unsub = tileset.tileFailed.addEventListener(handler);
334
+ cleanups.push(unsub);
335
+ }
336
+ if (cleanups.length > 0) {
337
+ this.layerErrorCleanups.set(layerId, () => cleanups.forEach(fn => fn()));
338
+ }
339
+ }
340
+ async removeLayer(layerId) {
341
+ if (!layerId)
342
+ return;
343
+ this.offLayerError(layerId);
344
+ await this.layerManagerMutex.runExclusive(async () => {
345
+ this.layerManager.removeLayer(layerId);
346
+ this.layerGroups.removeLayer(layerId, true);
347
+ this.layerGroups.apply();
348
+ });
349
+ }
350
+ // updateLayer, setOpacity, setZIndex, setVisible bleiben – du änderst damit den
351
+ // „Originalzustand“ der Layer. Danach LayerGroups.apply() aufrufen, damit
352
+ // Gruppen-/Basemap-Regeln sofort wieder durchgesetzt werden:
353
+ async setOpacity(layerId, opacity) {
354
+ this.layerManager.setOpacity(layerId, opacity);
355
+ this.layerGroups.apply();
356
+ }
357
+ async setVisible(layerId, visible) {
358
+ this.layerManager.setVisible(layerId, visible);
359
+ this.layerGroups.apply();
360
+ }
361
+ async setZIndex(layerId, zIndex) {
362
+ // Note: layerManager.setZIndex calls layer.setZIndex which is async (returns Promise<void>)
363
+ // even though the manager method itself is not marked as async. The await is kept here
364
+ // for future compatibility when the manager method becomes properly async.
365
+ await this.layerManager.setZIndex(layerId, zIndex);
366
+ // Z-Order ist unabhängig von Basemap/Group-Visible, aber apply() schadet nicht
367
+ this.layerGroups.apply();
368
+ }
369
+ // ========== Enhanced Styling Helper Methods ==========
370
+ /**
371
+ * Apply Geostyler styling to a GeoJsonDataSource
372
+ */
373
+ applyGeostylerStyling(dataSource, geostylerStyle) {
374
+ dataSource.__vmapLockOpacity = true;
375
+ // Helper to extract static value from GeoStyler property
376
+ const getValue = (prop, defaultValue) => {
377
+ if (prop === undefined || prop === null)
378
+ return defaultValue;
379
+ // If it's a GeoStyler function object, we can't evaluate it here - return default
380
+ if (typeof prop === 'object' && prop !== null && 'name' in prop)
381
+ return defaultValue;
382
+ return prop;
383
+ };
384
+ const toNumber = (value, fallback) => {
385
+ if (value == null)
386
+ return fallback;
387
+ if (typeof value === 'number')
388
+ return value;
389
+ const n = Number(value);
390
+ return Number.isFinite(n) ? n : fallback;
391
+ };
392
+ const entities = dataSource.entities.values;
393
+ if (geostylerStyle.rules) {
394
+ for (const rule of geostylerStyle.rules) {
395
+ if (rule.symbolizers) {
396
+ for (const symbolizer of rule.symbolizers) {
397
+ for (let i = 0; i < entities.length; i++) {
398
+ const entity = entities[i];
399
+ switch (symbolizer.kind) {
400
+ case 'Fill':
401
+ if (entity.polygon) {
402
+ const fillColor = getValue(symbolizer.color, 'rgba(0,100,255,0.3)');
403
+ const fillOpacity = toNumber(getValue(symbolizer.opacity, 0.3), 0.3);
404
+ const outlineColor = getValue(symbolizer.outlineColor, 'rgba(0,100,255,1)');
405
+ const outlineWidth = getValue(symbolizer.outlineWidth, 1);
406
+ let polygonColor = this.parseCesiumColor(fillColor, this.Cesium.Color.BLUE.withAlpha(0.3));
407
+ if (fillOpacity !== undefined && fillOpacity !== null) {
408
+ polygonColor = this.applyCesiumOpacity(polygonColor, fillOpacity);
409
+ }
410
+ //outline color
411
+ const outlineCesiumColor = this.parseCesiumColor(outlineColor, this.Cesium.Color.BLUE);
412
+ log('v-map - provider - cesium - applyGeostylerStyling: Fill', {
413
+ fillColor,
414
+ fillOpacity,
415
+ computedFill: polygonColor?.toString?.(),
416
+ outlineColor,
417
+ outlineWidth,
418
+ });
419
+ //fill
420
+ entity.polygon.fill = new this.Cesium.ConstantProperty(true);
421
+ //fill color
422
+ entity.polygon.material =
423
+ new this.Cesium.ColorMaterialProperty(polygonColor);
424
+ //outline
425
+ entity.polygon.outline = new this.Cesium.ConstantProperty(true);
426
+ entity.polygon.outlineColor =
427
+ new this.Cesium.ConstantProperty(outlineCesiumColor);
428
+ entity.polygon.outlineWidth =
429
+ new this.Cesium.ConstantProperty(outlineWidth);
430
+ //entity.polygon.height = new this.Cesium.ConstantProperty(0);
431
+ //
432
+ entity.polygon.extrudedHeight = undefined;
433
+ entity.polygon.heightReference =
434
+ new this.Cesium.ConstantProperty(this.Cesium.HeightReference.CLAMP_TO_GROUND);
435
+ entity.polygon.perPositionHeight =
436
+ new this.Cesium.ConstantProperty(false);
437
+ entity.polygon.classificationType =
438
+ new this.Cesium.ConstantProperty(this.Cesium.ClassificationType.BOTH);
439
+ }
440
+ break;
441
+ case 'Line':
442
+ if (entity.polyline) {
443
+ const lineColor = getValue(symbolizer.color, 'rgba(0,100,255,1)');
444
+ const lineWidth = toNumber(getValue(symbolizer.width, 2), 2);
445
+ const lineOpacity = toNumber(getValue(symbolizer.opacity, 1), 1);
446
+ let materialColor = this.parseCesiumColor(lineColor, this.Cesium.Color.BLUE);
447
+ if (lineOpacity !== undefined && lineOpacity !== null) {
448
+ materialColor = this.applyCesiumOpacity(materialColor, lineOpacity);
449
+ }
450
+ log('v-map - provider - cesium - applyGeostylerStyling: Line', {
451
+ lineColor,
452
+ lineOpacity,
453
+ computedColor: materialColor?.toString?.(),
454
+ lineWidth,
455
+ });
456
+ entity.polyline.material =
457
+ new this.Cesium.ColorMaterialProperty(materialColor);
458
+ entity.polyline.width = new this.Cesium.ConstantProperty(lineWidth);
459
+ }
460
+ break;
461
+ case 'Mark':
462
+ if (entity.point) {
463
+ const pointColor = getValue(symbolizer.color, 'rgba(0,100,255,1)');
464
+ const pointRadius = toNumber(getValue(symbolizer.radius, 6), 6);
465
+ const pointOpacity = toNumber(getValue(symbolizer.opacity, 1), 1);
466
+ let materialColor = this.parseCesiumColor(pointColor, this.Cesium.Color.BLUE);
467
+ if (pointOpacity !== undefined && pointOpacity !== null) {
468
+ materialColor = this.applyCesiumOpacity(materialColor, pointOpacity);
469
+ }
470
+ log('v-map - provider - cesium - applyGeostylerStyling: Mark', {
471
+ pointColor,
472
+ pointOpacity,
473
+ computedColor: materialColor?.toString?.(),
474
+ pointRadius,
475
+ });
476
+ entity.point.color = new this.Cesium.ConstantProperty(materialColor);
477
+ entity.point.pixelSize = new this.Cesium.ConstantProperty(pointRadius);
478
+ }
479
+ break;
480
+ case 'Icon':
481
+ if (entity.point) {
482
+ const iconSrc = getValue(symbolizer.image);
483
+ const iconSize = toNumber(getValue(symbolizer.size, 32), 32);
484
+ const iconOpacity = toNumber(getValue(symbolizer.opacity, 1), 1);
485
+ if (iconSrc && typeof iconSrc === 'string') {
486
+ entity.billboard = new this.Cesium.BillboardGraphics({
487
+ image: new this.Cesium.ConstantProperty(iconSrc),
488
+ width: new this.Cesium.ConstantProperty(iconSize),
489
+ height: new this.Cesium.ConstantProperty(iconSize),
490
+ verticalOrigin: new this.Cesium.ConstantProperty(this.Cesium.VerticalOrigin.BOTTOM),
491
+ color: iconOpacity !== undefined && iconOpacity !== null
492
+ ? new this.Cesium.ConstantProperty(this.Cesium.Color.WHITE.withAlpha(iconOpacity))
493
+ : undefined,
494
+ });
495
+ entity.point.show = new this.Cesium.ConstantProperty(false);
496
+ log('v-map - provider - cesium - applyGeostylerStyling: Icon', {
497
+ iconSrc,
498
+ iconSize,
499
+ iconOpacity,
500
+ });
501
+ }
502
+ }
503
+ break;
504
+ case 'Text':
505
+ const labelExpr = symbolizer.label;
506
+ const labelProp = typeof labelExpr === 'string' ? labelExpr : undefined;
507
+ if (labelProp &&
508
+ entity.properties &&
509
+ entity.properties[labelProp]) {
510
+ const textColor = getValue(symbolizer.color, '#000000');
511
+ const textSize = toNumber(getValue(symbolizer.size, 12), 12);
512
+ const textOpacity = toNumber(getValue(symbolizer.opacity, 1), 1);
513
+ let labelColor = this.parseCesiumColor(textColor, this.Cesium.Color.WHITE);
514
+ if (textOpacity !== undefined && textOpacity !== null) {
515
+ labelColor = this.applyCesiumOpacity(labelColor, textOpacity);
516
+ }
517
+ log('v-map - provider - cesium - applyGeostylerStyling: Text', {
518
+ labelProp,
519
+ textColor,
520
+ textOpacity,
521
+ computedColor: labelColor?.toString?.(),
522
+ textSize,
523
+ });
524
+ const textValue = entity.properties[labelProp]?.getValue?.(this.viewer.clock.currentTime) ??
525
+ entity.properties[labelProp]?._value ??
526
+ '';
527
+ entity.label = new this.Cesium.LabelGraphics({
528
+ text: new this.Cesium.ConstantProperty(String(textValue)),
529
+ font: new this.Cesium.ConstantProperty(`${textSize}px Arial`),
530
+ fillColor: new this.Cesium.ConstantProperty(labelColor),
531
+ verticalOrigin: new this.Cesium.ConstantProperty(this.Cesium.VerticalOrigin.BOTTOM),
532
+ });
533
+ }
534
+ break;
535
+ }
536
+ }
537
+ }
538
+ }
539
+ }
540
+ }
541
+ }
542
+ /**
543
+ * Convert CSS color to Cesium Color
544
+ */
545
+ parseCesiumColor(color, defaultColor) {
546
+ if (!color)
547
+ return defaultColor;
548
+ // Handle hex colors
549
+ if (color.startsWith('#')) {
550
+ return this.Cesium.Color.fromCssColorString(color);
551
+ }
552
+ // Handle rgba/rgb colors
553
+ if (color.includes('rgb')) {
554
+ return this.Cesium.Color.fromCssColorString(color);
555
+ }
556
+ // Try to parse as CSS color string
557
+ try {
558
+ return this.Cesium.Color.fromCssColorString(color);
559
+ }
560
+ catch {
561
+ return defaultColor;
562
+ }
563
+ }
564
+ /**
565
+ * Apply opacity to Cesium color
566
+ */
567
+ applyCesiumOpacity(color, opacity) {
568
+ if (!color)
569
+ return color;
570
+ return color.withAlpha(opacity);
571
+ }
572
+ /**
573
+ * Create Cesium styling options from StyleConfig
574
+ */
575
+ createCesiumStyle(style = {}) {
576
+ // Default colors
577
+ const defaultFillColor = this.Cesium.Color.BLUE.withAlpha(0.3);
578
+ const defaultStrokeColor = this.Cesium.Color.BLUE;
579
+ const defaultPointColor = this.Cesium.Color.BLUE;
580
+ // Parse colors
581
+ const fillColor = this.parseCesiumColor(style.fillColor, defaultFillColor);
582
+ const strokeColor = this.parseCesiumColor(style.strokeColor, defaultStrokeColor);
583
+ const pointColor = this.parseCesiumColor(style.pointColor, defaultPointColor);
584
+ // Apply opacity
585
+ const finalFillColor = style.fillOpacity !== undefined
586
+ ? this.applyCesiumOpacity(fillColor, style.fillOpacity)
587
+ : fillColor;
588
+ const finalStrokeColor = style.strokeOpacity !== undefined
589
+ ? this.applyCesiumOpacity(strokeColor, style.strokeOpacity)
590
+ : strokeColor;
591
+ const finalPointColor = style.pointOpacity !== undefined
592
+ ? this.applyCesiumOpacity(pointColor, style.pointOpacity)
593
+ : pointColor;
594
+ return {
595
+ // Polygon styling
596
+ fill: true,
597
+ fillColor: finalFillColor,
598
+ outline: true,
599
+ outlineColor: finalStrokeColor,
600
+ outlineWidth: style.strokeWidth ?? 2,
601
+ extrudedHeight: style.extrudeHeight,
602
+ heightReference: style.zOffset
603
+ ? this.Cesium.HeightReference.RELATIVE_TO_GROUND
604
+ : this.Cesium.HeightReference.CLAMP_TO_GROUND,
605
+ // Point styling
606
+ pixelSize: style.pointRadius ?? 8,
607
+ color: finalPointColor,
608
+ scaleByDistance: style.pointRadius
609
+ ? new this.Cesium.NearFarScalar(1.5e2, 2.0, 1.5e7, 0.5)
610
+ : undefined,
611
+ // Line styling
612
+ width: style.strokeWidth ?? 2,
613
+ clampToGround: !style.zOffset,
614
+ // Text/Label styling
615
+ labelText: style.textProperty,
616
+ labelFont: style.textSize
617
+ ? `${style.textSize}pt monospace`
618
+ : '12pt monospace',
619
+ labelFillColor: style.textColor
620
+ ? this.parseCesiumColor(style.textColor, this.Cesium.Color.WHITE)
621
+ : this.Cesium.Color.WHITE,
622
+ labelOutlineColor: style.textHaloColor
623
+ ? this.parseCesiumColor(style.textHaloColor, this.Cesium.Color.BLACK)
624
+ : this.Cesium.Color.BLACK,
625
+ labelOutlineWidth: style.textHaloWidth ?? 1,
626
+ labelPixelOffset: style.textOffset
627
+ ? new this.Cesium.Cartesian2(style.textOffset[0], style.textOffset[1])
628
+ : this.Cesium.Cartesian2.ZERO,
629
+ // 3D specific
630
+ height: style.zOffset ?? 0,
631
+ };
632
+ }
633
+ /**
634
+ * Apply enhanced styling to a GeoJsonDataSource
635
+ */
636
+ applyEnhancedStyling(dataSource, style = {}) {
637
+ const cesiumStyle = this.createCesiumStyle(style);
638
+ const entities = dataSource.entities.values;
639
+ for (let i = 0; i < entities.length; i++) {
640
+ const entity = entities[i];
641
+ let finalStyle = cesiumStyle;
642
+ if (style.styleFunction && entity.properties) {
643
+ const feature = {
644
+ properties: entity.properties._propertyNames.reduce((props, name) => {
645
+ props[name] = entity.properties[name]?._value;
646
+ return props;
647
+ }, {}),
648
+ geometry: entity,
649
+ };
650
+ const conditionalStyle = style.styleFunction(feature);
651
+ if (conditionalStyle) {
652
+ finalStyle = {
653
+ ...cesiumStyle,
654
+ ...this.createCesiumStyle(conditionalStyle),
655
+ };
656
+ }
657
+ }
658
+ if (entity.polygon) {
659
+ entity.polygon.fill = new this.Cesium.ConstantProperty(finalStyle.fill);
660
+ entity.polygon.material = new this.Cesium.ColorMaterialProperty(finalStyle.fillColor);
661
+ entity.polygon.outline = new this.Cesium.ConstantProperty(finalStyle.outline);
662
+ entity.polygon.outlineColor = new this.Cesium.ConstantProperty(finalStyle.outlineColor);
663
+ entity.polygon.outlineWidth = new this.Cesium.ConstantProperty(finalStyle.outlineWidth);
664
+ entity.polygon.height =
665
+ finalStyle.height !== undefined
666
+ ? new this.Cesium.ConstantProperty(finalStyle.height)
667
+ : undefined;
668
+ entity.polygon.extrudedHeight =
669
+ finalStyle.extrudedHeight !== undefined
670
+ ? new this.Cesium.ConstantProperty(finalStyle.extrudedHeight)
671
+ : undefined;
672
+ entity.polygon.heightReference =
673
+ finalStyle.heightReference !== undefined
674
+ ? new this.Cesium.ConstantProperty(finalStyle.heightReference)
675
+ : undefined;
676
+ }
677
+ if (entity.polyline) {
678
+ entity.polyline.material = new this.Cesium.ColorMaterialProperty(finalStyle.outlineColor);
679
+ entity.polyline.width = new this.Cesium.ConstantProperty(finalStyle.width);
680
+ entity.polyline.clampToGround = new this.Cesium.ConstantProperty(finalStyle.clampToGround);
681
+ }
682
+ if (entity.point) {
683
+ entity.point.pixelSize = new this.Cesium.ConstantProperty(finalStyle.pixelSize);
684
+ entity.point.color = new this.Cesium.ConstantProperty(finalStyle.color);
685
+ const scaleByDistance = finalStyle.scaleByDistance;
686
+ entity.point.scaleByDistance = scaleByDistance
687
+ ? new this.Cesium.ConstantProperty(scaleByDistance)
688
+ : undefined;
689
+ if (style.iconUrl) {
690
+ entity.billboard = new this.Cesium.BillboardGraphics({
691
+ image: new this.Cesium.ConstantProperty(style.iconUrl),
692
+ width: new this.Cesium.ConstantProperty(style.iconSize ? style.iconSize[0] : 32),
693
+ height: new this.Cesium.ConstantProperty(style.iconSize ? style.iconSize[1] : 32),
694
+ verticalOrigin: new this.Cesium.ConstantProperty(this.Cesium.VerticalOrigin.BOTTOM),
695
+ scaleByDistance: scaleByDistance
696
+ ? new this.Cesium.ConstantProperty(scaleByDistance)
697
+ : undefined,
698
+ });
699
+ entity.point.show = new this.Cesium.ConstantProperty(false);
700
+ }
701
+ }
702
+ if (style.textProperty &&
703
+ entity.properties &&
704
+ entity.properties[style.textProperty]) {
705
+ const textValue = entity.properties[style.textProperty]?.getValue?.(this.viewer.clock.currentTime) ??
706
+ entity.properties[style.textProperty]?._value ??
707
+ '';
708
+ entity.label = new this.Cesium.LabelGraphics({
709
+ text: new this.Cesium.ConstantProperty(String(textValue)),
710
+ font: new this.Cesium.ConstantProperty(finalStyle.labelFont),
711
+ fillColor: new this.Cesium.ConstantProperty(finalStyle.labelFillColor),
712
+ outlineColor: new this.Cesium.ConstantProperty(finalStyle.labelOutlineColor),
713
+ outlineWidth: new this.Cesium.ConstantProperty(finalStyle.labelOutlineWidth),
714
+ pixelOffset: new this.Cesium.ConstantProperty(finalStyle.labelPixelOffset),
715
+ verticalOrigin: new this.Cesium.ConstantProperty(this.Cesium.VerticalOrigin.BOTTOM),
716
+ });
717
+ }
718
+ }
719
+ }
720
+ async createWKTLayer(config, options) {
721
+ const geoJsonData = await this.wktToGeoJSON(config);
722
+ const dataSource = await this.Cesium.GeoJsonDataSource.load(geoJsonData, options);
723
+ // Apply geostyler style if provided, otherwise use enhanced styling
724
+ if (config.geostylerStyle) {
725
+ this.applyGeostylerStyling(dataSource, config.geostylerStyle);
726
+ }
727
+ else if (config.style) {
728
+ this.applyEnhancedStyling(dataSource, config.style);
729
+ }
730
+ return dataSource;
731
+ }
732
+ async wktToGeoJSON(config) {
733
+ const wktText = await this.resolveWktText(config);
734
+ const wellknownModule = await import('wellknown');
735
+ const parseFn = typeof wellknownModule.default === 'function'
736
+ ? wellknownModule.default
737
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- wellknown has inconsistent module exports across bundlers
738
+ : wellknownModule.parse;
739
+ if (typeof parseFn !== 'function') {
740
+ throw new Error('wellknown parser not available');
741
+ }
742
+ const geometry = parseFn(wktText);
743
+ if (!geometry) {
744
+ throw new Error('Failed to parse WKT');
745
+ }
746
+ return {
747
+ type: 'FeatureCollection',
748
+ features: [
749
+ {
750
+ type: 'Feature',
751
+ properties: {},
752
+ geometry,
753
+ },
754
+ ],
755
+ };
756
+ }
757
+ async resolveWktText(config) {
758
+ if (config.wkt)
759
+ return config.wkt;
760
+ if (config.url) {
761
+ const response = await fetch(config.url);
762
+ if (!response.ok)
763
+ throw new Error(`Failed to fetch WKT: ${response.status}`);
764
+ return await response.text();
765
+ }
766
+ throw new Error('Either wkt or url must be provided');
767
+ }
768
+ async createGeoJSONLayer(config, options) {
769
+ let geojson_or_url = null;
770
+ if (config.geojson) {
771
+ geojson_or_url = JSON.parse(config.geojson);
772
+ }
773
+ else {
774
+ geojson_or_url = config.url;
775
+ }
776
+ //https://cesium.com/learn/ion-sdk/ref-doc/GeoJsonDataSource.html
777
+ const dataSource = await this.Cesium.GeoJsonDataSource.load(geojson_or_url, options);
778
+ // Apply geostyler style if provided, otherwise use enhanced styling
779
+ if (config.geostylerStyle) {
780
+ this.applyGeostylerStyling(dataSource, config.geostylerStyle);
781
+ }
782
+ else if (config.style) {
783
+ this.applyEnhancedStyling(dataSource, config.style);
784
+ }
785
+ return dataSource;
786
+ }
787
+ async createWFSLayer(config, options) {
788
+ // Fetch GeoJSON from WFS server
789
+ const geojson = await this.fetchWFSFromUrl(config);
790
+ // Load GeoJSON into Cesium DataSource
791
+ const dataSource = await this.Cesium.GeoJsonDataSource.load(geojson, options);
792
+ // Apply geostyler style if provided, otherwise use enhanced styling
793
+ if (config.geostylerStyle) {
794
+ this.applyGeostylerStyling(dataSource, config.geostylerStyle);
795
+ }
796
+ else if (config.style) {
797
+ this.applyEnhancedStyling(dataSource, config.style);
798
+ }
799
+ return dataSource;
800
+ }
801
+ async createOSMLayer(cfg) {
802
+ return new this.Cesium.ImageryLayer(new this.Cesium.OpenStreetMapImageryProvider({
803
+ url: cfg.url || 'https://a.tile.openstreetmap.org',
804
+ }));
805
+ }
806
+ async createGoogleLayer(config) {
807
+ if (!config.apiKey) {
808
+ throw new Error("Google-Layer benötigt 'apiKey' (Google Maps Platform).");
809
+ }
810
+ // Load Google Maps JavaScript API
811
+ await this.loadGoogleMapsApi(config.apiKey, {
812
+ language: config.language,
813
+ region: config.region,
814
+ libraries: config.libraries,
815
+ });
816
+ const mapType = config.mapType || 'roadmap';
817
+ const googleMapTypeId = this.getGoogleMapTypeId(mapType);
818
+ // Use a simpler approach with UrlTemplateImageryProvider and custom URL generator
819
+ const Cesium = this.Cesium;
820
+ // Create a custom URL template that we'll handle in the urlSchemeZeroPadding function
821
+ const customUrlTemplate = 'https://maps.googleapis.com/maps/api/staticmap?template';
822
+ const googleImageryProvider = new Cesium.UrlTemplateImageryProvider({
823
+ url: customUrlTemplate,
824
+ maximumLevel: config.maxZoom || 19,
825
+ minimumLevel: 0,
826
+ tilingScheme: new Cesium.WebMercatorTilingScheme(),
827
+ credit: 'Google Maps',
828
+ // Override URL generation using urlSchemeZeroPadding as a custom URL builder
829
+ urlSchemeZeroPadding: {
830
+ '{x}': '',
831
+ '{y}': '',
832
+ '{z}': '',
833
+ },
834
+ });
835
+ // Override the buildImageResource method to use Google Static Maps API
836
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- monkey-patching internal Cesium method not exposed in typings
837
+ googleImageryProvider.buildImageResource = function (x, y, level) {
838
+ const tilingScheme = new Cesium.WebMercatorTilingScheme();
839
+ const rectangle = tilingScheme.tileXYToRectangle(x, y, level);
840
+ const west = Cesium.Math.toDegrees(rectangle.west);
841
+ const south = Cesium.Math.toDegrees(rectangle.south);
842
+ const east = Cesium.Math.toDegrees(rectangle.east);
843
+ const north = Cesium.Math.toDegrees(rectangle.north);
844
+ // Center point of the tile
845
+ const centerLat = (south + north) / 2;
846
+ const centerLng = (west + east) / 2;
847
+ // Build Google Static Maps API URL
848
+ const params = new URLSearchParams({
849
+ center: `${centerLat},${centerLng}`,
850
+ zoom: level.toString(),
851
+ size: '256x256',
852
+ scale: config.scale === 'scaleFactor1x' ? '1' : '2',
853
+ maptype: googleMapTypeId,
854
+ key: config.apiKey,
855
+ format: 'png',
856
+ });
857
+ if (config.language) {
858
+ params.set('language', config.language);
859
+ }
860
+ if (config.region) {
861
+ params.set('region', config.region);
862
+ }
863
+ const url = `https://maps.googleapis.com/maps/api/staticmap?${params.toString()}`;
864
+ return new Cesium.Resource({ url });
865
+ };
866
+ // Add Google logo for compliance
867
+ this.ensureGoogleLogo();
868
+ return new this.Cesium.ImageryLayer(googleImageryProvider, {
869
+ alpha: config.opacity ?? 1,
870
+ show: config.visible ?? true,
871
+ });
872
+ }
873
+ getGoogleMapTypeId(mapType) {
874
+ switch (mapType) {
875
+ case 'roadmap':
876
+ return 'roadmap';
877
+ case 'satellite':
878
+ return 'satellite';
879
+ case 'terrain':
880
+ return 'terrain';
881
+ case 'hybrid':
882
+ return 'hybrid';
883
+ default:
884
+ return 'roadmap';
885
+ }
886
+ }
887
+ /**
888
+ * Load Google Maps JavaScript API
889
+ */
890
+ async loadGoogleMapsApi(apiKey, opts) {
891
+ const w = window;
892
+ const mockLoader = w.__mockGoogleMapsApi;
893
+ if (typeof mockLoader === 'function') {
894
+ await mockLoader(apiKey, opts);
895
+ return;
896
+ }
897
+ if (w.google?.maps)
898
+ return;
899
+ await new Promise((resolve, reject) => {
900
+ const cbName = '___cesiumGoogleInit___' + Math.random().toString(36).slice(2);
901
+ w[cbName] = () => resolve();
902
+ const script = document.createElement('script');
903
+ const params = new URLSearchParams({
904
+ key: apiKey,
905
+ callback: cbName,
906
+ v: 'weekly',
907
+ });
908
+ if (opts?.language)
909
+ params.set('language', opts.language);
910
+ if (opts?.region)
911
+ params.set('region', opts.region);
912
+ if (opts?.libraries?.length)
913
+ params.set('libraries', opts.libraries.join(','));
914
+ script.src = `https://maps.googleapis.com/maps/api/js?${params.toString()}`;
915
+ script.async = true;
916
+ script.onerror = () => reject(new Error('Google Maps JS API failed to load'));
917
+ document.head.appendChild(script);
918
+ });
919
+ }
920
+ /**
921
+ * Add Google logo for compliance
922
+ */
923
+ ensureGoogleLogo() {
924
+ if (!this.viewer?.container ||
925
+ this.viewer.container._googleLogoAdded)
926
+ return;
927
+ const logo = document.createElement('img');
928
+ logo.src =
929
+ 'https://developers.google.com/static/maps/documentation/images/google_on_white.png';
930
+ logo.alt = 'Google';
931
+ logo.style.position = 'absolute';
932
+ logo.style.bottom = '6px';
933
+ logo.style.left = '6px';
934
+ logo.style.height = '18px';
935
+ logo.style.pointerEvents = 'none';
936
+ logo.style.zIndex = '1000';
937
+ this.viewer.container.appendChild(logo);
938
+ this.viewer.container._googleLogoAdded = true;
939
+ }
940
+ async createXYZLayer(config) {
941
+ if (!config.url) {
942
+ throw new Error('XYZ layer requires a url');
943
+ }
944
+ const credit = Array.isArray(config.attributions)
945
+ ? config.attributions.join(', ')
946
+ : config.attributions;
947
+ const providerOptions = {
948
+ url: config.url,
949
+ credit,
950
+ maximumLevel: config.maxZoom,
951
+ ...(config.options || {}),
952
+ };
953
+ const provider = new this.Cesium.UrlTemplateImageryProvider(providerOptions);
954
+ const layerOptions = {
955
+ alpha: config.opacity ?? 1,
956
+ show: config.visible ?? true,
957
+ };
958
+ return new this.Cesium.ImageryLayer(provider, layerOptions);
959
+ }
960
+ async createTerrainLayer(config) {
961
+ let provider;
962
+ if (config.elevationData) {
963
+ provider = await this.Cesium.CesiumTerrainProvider.fromUrl(config.elevationData);
964
+ }
965
+ else {
966
+ provider = await this.Cesium.createWorldTerrainAsync();
967
+ }
968
+ const layer = new CesiumTerrainLayer(this.Cesium, this.viewer, provider, config);
969
+ if (config.visible !== undefined) {
970
+ layer.setVisible(config.visible);
971
+ }
972
+ if (config.opacity !== undefined) {
973
+ layer.setOpacity(config.opacity);
974
+ }
975
+ return layer;
976
+ }
977
+ /**
978
+ * Create GeoTIFF Terrain Layer
979
+ * Loads GeoTIFF elevation data and provides it as terrain
980
+ */
981
+ async createGeoTIFFTerrainLayer(config) {
982
+ // If no URL is set, return a fallback layer with EllipsoidTerrainProvider
983
+ if (!config.url) {
984
+ log(`${TERRAIN_GEOTIFF_LOG_PREFIX}layer created without URL, waiting for URL to load`);
985
+ const fallbackProvider = new this.Cesium.EllipsoidTerrainProvider();
986
+ const layer = new CesiumTerrainLayer(this.Cesium, this.viewer, fallbackProvider, config);
987
+ // Set to invisible since there's no terrain data
988
+ layer.setVisible(false);
989
+ return layer;
990
+ }
991
+ try {
992
+ log(`${TERRAIN_GEOTIFF_LOG_PREFIX}create layer: url=${config.url}`);
993
+ // Create the custom GeoTIFF terrain provider
994
+ const provider = await createCesiumGeoTIFFTerrainProvider({
995
+ url: config.url,
996
+ projection: config.projection,
997
+ forceProjection: config.forceProjection,
998
+ nodata: config.nodata,
999
+ Cesium: this.Cesium,
1000
+ });
1001
+ // Wrap it in a CesiumTerrainLayer
1002
+ // Cast config to terrain type since CesiumTerrainLayer expects it
1003
+ const layer = new CesiumTerrainLayer(this.Cesium, this.viewer, provider, config);
1004
+ if (config.visible !== undefined) {
1005
+ layer.setVisible(config.visible);
1006
+ }
1007
+ if (config.opacity !== undefined) {
1008
+ layer.setOpacity(config.opacity);
1009
+ }
1010
+ log(`${TERRAIN_GEOTIFF_LOG_PREFIX}layer created successfully`);
1011
+ return layer;
1012
+ }
1013
+ catch (err) {
1014
+ error(`${TERRAIN_GEOTIFF_LOG_PREFIX}failed to create terrain layer:`, err);
1015
+ // Return a fallback with EllipsoidTerrainProvider
1016
+ const fallbackProvider = new this.Cesium.EllipsoidTerrainProvider();
1017
+ return new CesiumTerrainLayer(this.Cesium, this.viewer, fallbackProvider, config);
1018
+ }
1019
+ }
1020
+ async addWMSLayer(config) {
1021
+ return new this.Cesium.ImageryLayer(new this.Cesium.WebMapServiceImageryProvider({
1022
+ url: config.url,
1023
+ layers: config.layers,
1024
+ parameters: config.extraParams,
1025
+ }));
1026
+ }
1027
+ /**
1028
+ * Create WCS (Web Coverage Service) ImageryLayer
1029
+ * Supports WCS 2.0.1 (subset) and 1.x.x (BBOX) versions
1030
+ */
1031
+ async createWCSLayer(config) {
1032
+ if (!config.url || !config.coverageName) {
1033
+ throw new Error('WCS layer requires url and coverageName');
1034
+ }
1035
+ const version = config.version ?? '2.0.1';
1036
+ const format = config.format ?? 'image/tiff';
1037
+ const projection = config.projection ?? 'EPSG:4326';
1038
+ const tileSize = config.tileSize ?? 256;
1039
+ const Cesium = this.Cesium;
1040
+ // Create a custom URL template - will be overridden by buildImageResource
1041
+ const customUrlTemplate = `${config.url}?wcs_placeholder`;
1042
+ const wcsImageryProvider = new Cesium.UrlTemplateImageryProvider({
1043
+ url: customUrlTemplate,
1044
+ maximumLevel: config.maxZoom ?? 18,
1045
+ minimumLevel: config.minZoom ?? 0,
1046
+ tileWidth: tileSize,
1047
+ tileHeight: tileSize,
1048
+ tilingScheme: new Cesium.GeographicTilingScheme(),
1049
+ credit: 'WCS',
1050
+ });
1051
+ // Override the buildImageResource method to generate WCS GetCoverage URLs
1052
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- monkey-patching internal Cesium method not exposed in typings
1053
+ wcsImageryProvider.buildImageResource = function (x, y, level) {
1054
+ const tilingScheme = new Cesium.GeographicTilingScheme();
1055
+ const rectangle = tilingScheme.tileXYToRectangle(x, y, level);
1056
+ // Convert to degrees
1057
+ const west = Cesium.Math.toDegrees(rectangle.west);
1058
+ const south = Cesium.Math.toDegrees(rectangle.south);
1059
+ const east = Cesium.Math.toDegrees(rectangle.east);
1060
+ const north = Cesium.Math.toDegrees(rectangle.north);
1061
+ const baseParams = {
1062
+ SERVICE: 'WCS',
1063
+ REQUEST: 'GetCoverage',
1064
+ VERSION: version,
1065
+ FORMAT: format,
1066
+ };
1067
+ let url;
1068
+ // WCS 2.0.1 uses subset parameters
1069
+ if (version.startsWith('2.0')) {
1070
+ const params = {
1071
+ ...baseParams,
1072
+ coverageId: config.coverageName,
1073
+ ...(config.params || {}),
1074
+ };
1075
+ // Add GeoTIFF compression if format is tiff
1076
+ if (format.includes('tiff') || format.includes('geotiff')) {
1077
+ params['geotiff:compression'] = 'LZW';
1078
+ }
1079
+ // Build query string
1080
+ const query = new URLSearchParams();
1081
+ Object.entries(params).forEach(([key, value]) => {
1082
+ if (value !== undefined && value !== null) {
1083
+ query.set(key, String(value));
1084
+ }
1085
+ });
1086
+ const queryString = query.toString();
1087
+ const subsetX = `subset=X(${west},${east})`;
1088
+ const subsetY = `subset=Y(${south},${north})`;
1089
+ url = `${config.url}${config.url.includes('?') ? '&' : '?'}${queryString}&${subsetX}&${subsetY}`;
1090
+ }
1091
+ // WCS 1.x.x uses BBOX parameter
1092
+ else {
1093
+ const params = {
1094
+ ...baseParams,
1095
+ COVERAGE: config.coverageName,
1096
+ BBOX: `${west},${south},${east},${north}`,
1097
+ CRS: projection,
1098
+ WIDTH: String(tileSize),
1099
+ HEIGHT: String(tileSize),
1100
+ ...(config.params || {}),
1101
+ };
1102
+ const query = new URLSearchParams();
1103
+ Object.entries(params).forEach(([key, value]) => {
1104
+ if (value !== undefined && value !== null) {
1105
+ query.set(key, String(value));
1106
+ }
1107
+ });
1108
+ url = `${config.url}${config.url.includes('?') ? '&' : '?'}${query.toString()}`;
1109
+ }
1110
+ return new Cesium.Resource({ url });
1111
+ };
1112
+ return new this.Cesium.ImageryLayer(wcsImageryProvider, {
1113
+ alpha: config.opacity ?? 1,
1114
+ show: config.visible ?? true,
1115
+ });
1116
+ }
1117
+ async addArcGISLayer(config) {
1118
+ //"https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer"
1119
+ const provider = await this.Cesium.ArcGisMapServerImageryProvider.fromUrl(config.url);
1120
+ this.viewer.imageryLayers.addImageryProvider(provider);
1121
+ }
1122
+ async createGeoTIFFLayer(config) {
1123
+ if (!config.url) {
1124
+ throw new Error('GeoTIFF layer requires a URL');
1125
+ }
1126
+ // The GeoTIFFImageryProvider always uses WebMercatorTilingScheme,
1127
+ // so the tile processor must reproject into EPSG:3857 to match
1128
+ // the tile coordinate math (x,y,z → bounds).
1129
+ const viewProjection = 'EPSG:3857';
1130
+ try {
1131
+ const geotiffExtra = config;
1132
+ const source = await getGeoTIFFSource(config.url, geotiffExtra.projection, geotiffExtra.forceProjection, config.nodata);
1133
+ const tileProcessorConfig = await getTileProcessorConfig(source, viewProjection);
1134
+ const tileProcessor = new GeoTIFFTileProcessor(tileProcessorConfig);
1135
+ tileProcessor.createGlobalTriangulation();
1136
+ let colorStops;
1137
+ if (config.colorMap) {
1138
+ const { stops } = getColorStops(config.colorMap, config.valueRange);
1139
+ colorStops = stops;
1140
+ }
1141
+ const geotiffRenderExtra = config;
1142
+ const tileSize = geotiffRenderExtra.tileSize ?? 256;
1143
+ const resolution = geotiffRenderExtra.resolution ?? 1.0;
1144
+ const resampleMethod = geotiffRenderExtra.resampleMethod ?? 'bilinear';
1145
+ const imageryProvider = new GeoTIFFImageryProvider({
1146
+ Cesium: this.Cesium,
1147
+ rectangleDegrees: source.wgs84Bounds,
1148
+ tileProcessor,
1149
+ tileSize,
1150
+ resolution,
1151
+ resampleMethod,
1152
+ colorStops,
1153
+ });
1154
+ const layer = new this.Cesium.ImageryLayer(imageryProvider, {
1155
+ alpha: config.opacity ?? 1.0,
1156
+ show: config.visible ?? true,
1157
+ });
1158
+ layer.__vmapGeoTIFFMeta = {
1159
+ url: config.url,
1160
+ width: source.width,
1161
+ height: source.height,
1162
+ samplesPerPixel: source.samplesPerPixel,
1163
+ noData: source.noDataValue,
1164
+ };
1165
+ return layer;
1166
+ }
1167
+ catch (err) {
1168
+ error('v-map - provider - cesium - Failed to create GeoTIFF layer', err);
1169
+ // Return a placeholder layer in case of error
1170
+ const provider = new this.Cesium.SingleTileImageryProvider({
1171
+ url: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
1172
+ rectangle: this.Cesium.Rectangle.fromDegrees(-180, -90, 180, 90),
1173
+ });
1174
+ return new this.Cesium.ImageryLayer(provider, {
1175
+ alpha: 0,
1176
+ show: false,
1177
+ });
1178
+ }
1179
+ }
1180
+ async createTile3DLayer(config) {
1181
+ if (!config.url) {
1182
+ throw new Error('Tile3D layer requires a URL');
1183
+ }
1184
+ const tileset = await this.Cesium.Cesium3DTileset.fromUrl(config.url, config.tilesetOptions ?? {});
1185
+ if (config.cesiumStyle) {
1186
+ tileset.style = new this.Cesium.Cesium3DTileStyle(config.cesiumStyle);
1187
+ }
1188
+ return tileset;
1189
+ }
1190
+ async updateLayer(layerId, update) {
1191
+ return await this.layerManagerMutex.runExclusive(async () => {
1192
+ const hadErrorListener = this.layerErrorCallbacks.has(layerId);
1193
+ if (hadErrorListener)
1194
+ this.offLayerError(layerId);
1195
+ const oldLayer = this.layerManager.getLayer(layerId);
1196
+ switch (update.type) {
1197
+ case 'geojson':
1198
+ {
1199
+ const data = update.data;
1200
+ const options = oldLayer.getOptions();
1201
+ const dataSource = await this.createGeoJSONLayer({
1202
+ geojson: data.geojson,
1203
+ url: data.url,
1204
+ style: data.style,
1205
+ geostylerStyle: data.geostylerStyle,
1206
+ }, options);
1207
+ const layer = this.layerManager.replaceLayer(layerId, oldLayer, dataSource);
1208
+ layer.setOptions(options);
1209
+ }
1210
+ break;
1211
+ case 'wfs':
1212
+ {
1213
+ const data = update.data;
1214
+ const options = oldLayer.getOptions();
1215
+ const dataSource = await this.createWFSLayer(data, options);
1216
+ const layer = this.layerManager.replaceLayer(layerId, oldLayer, dataSource);
1217
+ layer.setOptions(options);
1218
+ }
1219
+ break;
1220
+ case 'osm':
1221
+ {
1222
+ const osmOptions = oldLayer.getOptions();
1223
+ const osmLayer = new this.Cesium.ImageryLayer(new this.Cesium.OpenStreetMapImageryProvider({
1224
+ url: update.data.url || 'https://a.tile.openstreetmap.org',
1225
+ }));
1226
+ const updatedOsmlayer = this.layerManager.replaceLayer(layerId, oldLayer, osmLayer);
1227
+ updatedOsmlayer.setOptions(osmOptions);
1228
+ }
1229
+ break;
1230
+ case 'google':
1231
+ {
1232
+ const googleOptions = oldLayer.getOptions();
1233
+ const googleLayer = await this.createGoogleLayer(update.data);
1234
+ const updatedGoogleLayer = this.layerManager.replaceLayer(layerId, oldLayer, googleLayer);
1235
+ updatedGoogleLayer.setOptions(googleOptions);
1236
+ }
1237
+ break;
1238
+ case 'xyz':
1239
+ {
1240
+ const xyzOptions = oldLayer.getOptions();
1241
+ const xyzLayer = await this.createXYZLayer(update.data);
1242
+ const updatedXyzLayer = this.layerManager.replaceLayer(layerId, oldLayer, xyzLayer);
1243
+ updatedXyzLayer.setOptions(xyzOptions);
1244
+ }
1245
+ break;
1246
+ case 'wcs':
1247
+ {
1248
+ const wcsOptions = oldLayer.getOptions();
1249
+ const wcsLayer = await this.createWCSLayer(update.data);
1250
+ const updatedWcsLayer = this.layerManager.replaceLayer(layerId, oldLayer, wcsLayer);
1251
+ updatedWcsLayer.setOptions(wcsOptions);
1252
+ }
1253
+ break;
1254
+ case 'wkt':
1255
+ {
1256
+ const data = update.data;
1257
+ const options = oldLayer.getOptions();
1258
+ const dataSource = await this.createWKTLayer({
1259
+ wkt: data.wkt,
1260
+ url: data.url,
1261
+ style: data.style,
1262
+ geostylerStyle: data.geostylerStyle,
1263
+ }, options);
1264
+ const layer = this.layerManager.replaceLayer(layerId, oldLayer, dataSource);
1265
+ layer.setOptions(options);
1266
+ }
1267
+ break;
1268
+ case 'geotiff':
1269
+ {
1270
+ const data = update.data;
1271
+ const iLayer = await this.createGeoTIFFLayer({
1272
+ url: data.url,
1273
+ });
1274
+ this.layerManager.replaceLayer(layerId, oldLayer, iLayer);
1275
+ }
1276
+ break;
1277
+ case 'tile3d':
1278
+ {
1279
+ const data = update.data ?? {};
1280
+ if (!data.url) {
1281
+ throw new Error('tile3d update requires a url');
1282
+ }
1283
+ const layer = await this.createTile3DLayer({
1284
+ type: 'tile3d',
1285
+ url: data.url,
1286
+ tilesetOptions: data.tilesetOptions,
1287
+ cesiumStyle: data.cesiumStyle,
1288
+ });
1289
+ const updatedLayer = this.layerManager.replaceLayer(layerId, oldLayer, layer);
1290
+ updatedLayer.setOptions(data.tilesetOptions ?? {});
1291
+ if (data.cesiumStyle && 'setStyle' in updatedLayer) {
1292
+ updatedLayer.setStyle(data.cesiumStyle);
1293
+ }
1294
+ }
1295
+ break;
1296
+ case 'tile3d-style':
1297
+ {
1298
+ const data = update.data ?? {};
1299
+ if ('setStyle' in oldLayer) {
1300
+ const stylePayload = data.style ?? {};
1301
+ oldLayer.setStyle(stylePayload);
1302
+ }
1303
+ }
1304
+ break;
1305
+ case 'terrain':
1306
+ {
1307
+ const previousOptions = oldLayer.getOptions();
1308
+ const visible = oldLayer.getVisible();
1309
+ const opacity = oldLayer.getOpacity();
1310
+ oldLayer.remove();
1311
+ const terrainLayer = await this.createTerrainLayer({
1312
+ type: 'terrain',
1313
+ ...previousOptions,
1314
+ ...(update.data ?? {}),
1315
+ });
1316
+ const wrapped = this.layerManager.addCustomLayer(layerId, terrainLayer);
1317
+ wrapped.setVisible(visible);
1318
+ wrapped.setOpacity(opacity);
1319
+ }
1320
+ break;
1321
+ case 'terrain-geotiff':
1322
+ {
1323
+ //const previousOptions = oldLayer.getOptions();
1324
+ //const visible = oldLayer.getVisible();
1325
+ //const opacity = oldLayer.getOpacity();
1326
+ oldLayer.remove();
1327
+ const terrainLayer = await this.createGeoTIFFTerrainLayer({
1328
+ type: 'terrain-geotiff',
1329
+ ...(update.data ?? {}),
1330
+ });
1331
+ this.layerManager.addCustomLayer(layerId, terrainLayer);
1332
+ //wrapped.setVisible(visible);
1333
+ //wrapped.setOpacity(opacity);
1334
+ }
1335
+ break;
1336
+ }
1337
+ // Re-attach error listeners after layer replacement
1338
+ if (hadErrorListener)
1339
+ this.attachCesiumErrorListeners(layerId);
1340
+ });
1341
+ }
1342
+ async setView(center, zoom) {
1343
+ if (!this.viewer)
1344
+ return;
1345
+ const [lon, lat] = center;
1346
+ this.viewer.camera.flyTo({
1347
+ destination: this.Cesium.Cartesian3.fromDegrees(lon, lat, 1000000 / zoom),
1348
+ duration: 2.0, // Sekunden, anpassbar
1349
+ orientation: {
1350
+ heading: this.Cesium.Math.toRadians(0.0), // Blickrichtung nach Norden
1351
+ pitch: this.Cesium.Math.toRadians(-30.0), // leicht nach unten schauen
1352
+ roll: 0.0,
1353
+ },
1354
+ // optional: onComplete / onCancel callbacks
1355
+ complete: () => log('v-map - provider - cesium - Fly‑to finished'),
1356
+ cancel: () => warn('v-map - provider - cesium - Fly‑to cancelled'),
1357
+ });
1358
+ }
1359
+ async fetchWFSFromUrl(config) {
1360
+ const baseParams = {
1361
+ service: 'WFS',
1362
+ request: 'GetFeature',
1363
+ version: config.version ?? '1.1.0',
1364
+ typeName: config.typeName,
1365
+ outputFormat: config.outputFormat ?? 'application/json',
1366
+ srsName: config.srsName ?? 'EPSG:4326',
1367
+ };
1368
+ const params = { ...baseParams, ...(config.params ?? {}) };
1369
+ const requestUrl = this.appendParams(config.url, params);
1370
+ const response = await fetch(requestUrl);
1371
+ if (!response.ok) {
1372
+ throw new Error(`WFS request failed (${response.status} ${response.statusText})`);
1373
+ }
1374
+ const outputFormat = (config.outputFormat ?? 'application/json').toLowerCase();
1375
+ // Handle JSON formats
1376
+ if (outputFormat.includes('json') ||
1377
+ outputFormat.includes('geojson') ||
1378
+ outputFormat === 'application/json') {
1379
+ const contentType = response.headers.get('content-type');
1380
+ if (contentType?.includes('application/json')) {
1381
+ return await response.json();
1382
+ }
1383
+ // Try to parse as JSON anyway
1384
+ const text = await response.text();
1385
+ return JSON.parse(text);
1386
+ }
1387
+ // Handle GML formats - parse XML to GeoJSON using @npm9912/s-gml
1388
+ if (outputFormat.includes('gml') || outputFormat.includes('xml')) {
1389
+ const xml = await response.text();
1390
+ const { GmlParser } = await import('@npm9912/s-gml');
1391
+ const parser = new GmlParser();
1392
+ return await parser.parse(xml);
1393
+ }
1394
+ // Default: try to parse as JSON
1395
+ return await response.json();
1396
+ }
1397
+ appendParams(baseUrl, params) {
1398
+ const query = new URLSearchParams();
1399
+ Object.entries(params).forEach(([key, value]) => {
1400
+ if (value !== undefined && value !== null) {
1401
+ query.set(key, String(value));
1402
+ }
1403
+ });
1404
+ if (!query.toString())
1405
+ return baseUrl;
1406
+ return `${baseUrl}${baseUrl.includes('?') ? '&' : '?'}${query.toString()}`;
1407
+ }
1408
+ }