@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,1563 @@
1
+ import { DEFAULT_STYLE } from "../../types/styleconfig";
2
+ import { GmlParser } from "@npm9912/s-gml";
3
+ import { wellknownModule } from "wellknown";
4
+ import { createDeckGLGeoTIFFLayer } from "./DeckGLGeoTIFFLayer";
5
+ import { createDeckGLGeoTIFFTerrainLayer } from "./DeckGLGeoTIFFTerrainLayer";
6
+ import { Deck } from "@deck.gl/core";
7
+ import { GeoJsonLayer, BitmapLayer, ScatterplotLayer } from "@deck.gl/layers";
8
+ import { TerrainLayer, TileLayer } from "@deck.gl/geo-layers";
9
+ import { log, warn } from "../../utils/logger";
10
+ import { formatBbox, buildQuery } from "../../utils/spatial-utils";
11
+ import { LayerGroups } from "./LayerGroups";
12
+ import { LayerGroupWithModel } from "./LayerGroupWithModel";
13
+ export class DeckProvider {
14
+ deck;
15
+ target;
16
+ shadowRoot;
17
+ injectedStyle;
18
+ // Store arbeitet mit RenderableGroup — wir nutzen hier die modellbasierte Gruppe
19
+ layerGroups = new LayerGroups({});
20
+ layerErrorCallbacks = new Map();
21
+ async init(opts) {
22
+ this.target = opts.target;
23
+ this.shadowRoot = opts.shadowRoot;
24
+ this.injectedStyle = await (async function injectCss(sr) {
25
+ const style = document.createElement('style');
26
+ style.textContent =
27
+ 'canvas.deckgl-canvas { background:#fff !important; }';
28
+ sr?.appendChild(style);
29
+ return style;
30
+ })(this.shadowRoot);
31
+ const lon = opts.mapInitOptions?.center?.[0] ?? 8.5417;
32
+ const lat = opts.mapInitOptions?.center?.[1] ?? 49.0069;
33
+ const zoom = opts.mapInitOptions?.zoom ?? 5;
34
+ let viewState = {
35
+ longitude: lon,
36
+ latitude: lat,
37
+ zoom,
38
+ bearing: 0,
39
+ pitch: 0,
40
+ };
41
+ Object.assign(this.target.style, {
42
+ width: '100%',
43
+ height: '100%',
44
+ position: 'relative',
45
+ background: '#fff',
46
+ });
47
+ this.deck = new Deck({
48
+ parent: this.target,
49
+ controller: {
50
+ scrollZoom: true,
51
+ dragPan: true,
52
+ dragRotate: true,
53
+ touchZoom: true,
54
+ touchRotate: true,
55
+ doubleClickZoom: true,
56
+ keyboard: true,
57
+ },
58
+ viewState,
59
+ onViewStateChange: ({ viewState: vs }) => {
60
+ viewState = vs;
61
+ this.deck.setProps({ viewState });
62
+ },
63
+ layers: [],
64
+ _typedArrayManagerProps: { overAlloc: 1 },
65
+ });
66
+ this.layerGroups.attachDeck(this.deck);
67
+ }
68
+ // ---------- Helpers: Modelle / Gruppen ----------
69
+ /** Liefert (oder erzeugt) eine modellbasierte Gruppe */
70
+ ensureModelGroup(groupId) {
71
+ const g = this.layerGroups.getGroup(groupId);
72
+ if (g)
73
+ return g;
74
+ const ng = new LayerGroupWithModel({
75
+ id: groupId,
76
+ syncMode: 'force-model',
77
+ });
78
+ this.layerGroups.addGroup(ng);
79
+ return ng;
80
+ }
81
+ /** Erzeugt ein LayerModel aus einem LayerConfig + Factory */
82
+ createLayerModel(layerId, make, enabled = true, elementId = null) {
83
+ return { id: layerId, elementId, enabled, make, meta: {} };
84
+ }
85
+ // ---------- Layer-Factories (unverändert, geben Deck-Layer zurück) ----------
86
+ async buildXyzTileLayer(cfg, layerId) {
87
+ const tileSize = cfg.tileSize ?? 256;
88
+ /*
89
+ const subdomains: string[] = Array.isArray(cfg.subdomains)
90
+ ? cfg.subdomains
91
+ : typeof cfg.subdomains === 'string' && cfg.subdomains.length
92
+ ? cfg.subdomains.split(',')
93
+ : ['a', 'b', 'c'];
94
+ const makeUrl = (z: number, x: number, y: number) => {
95
+ const s = subdomains.length
96
+ ? subdomains[(x + y + z) % subdomains.length]
97
+ : '';
98
+ return (cfg.url as string)
99
+ .replace('{z}', String(z))
100
+ .replace('{x}', String(x))
101
+ .replace('{y}', String(y))
102
+ .replace('{s}', s);
103
+ };
104
+
105
+ */
106
+ /*
107
+ const makeUrl = (z: number, x: number, y: number) => {
108
+ return (cfg.url as string)
109
+ .replace('{z}', String(z))
110
+ .replace('{x}', String(x))
111
+ .replace('{y}', String(y));
112
+ };
113
+ */
114
+ // return new TileLayer<ImageBitmap>({
115
+ return new TileLayer({
116
+ id: layerId,
117
+ data: [cfg.url],
118
+ zIndex: 100,
119
+ maxRequests: 20,
120
+ tileSize,
121
+ minZoom: cfg.minZoom ?? 0,
122
+ maxZoom: cfg.maxZoom ?? 19,
123
+ opacity: cfg.opacity,
124
+ /*
125
+ getTileData: async ({ signal, index }) => {
126
+ const { x, y, z } = index;
127
+ const yXYZ = (1 << z) - 1 - y; // flip TMS to XYZ
128
+ const data = await this.loadImageBitmap(makeUrl(z, x, yXYZ), signal);
129
+ if (signal.aborted) {
130
+ return null;
131
+ }
132
+ return data;
133
+ },
134
+ */
135
+ /* getTileData: async ({ index }) => {
136
+ const { x, y, z } = index;
137
+ const yXYZ = (1 << z) - 1 - y; // flip TMS to XYZ
138
+ const tile = { url: makeUrl(z, x, yXYZ) };
139
+ if (fetch && tile.url) {
140
+ return fetch(tile.url, {propName: 'data', layer: this, signal});
141
+ }
142
+ return null;
143
+ },
144
+ */
145
+ onTileError: (err) => {
146
+ log(`v-map - provider - deck - Tile Error: ${err}`);
147
+ this.layerErrorCallbacks.get(layerId)?.({ type: 'network', message: `Tile load error: ${err}`, cause: err });
148
+ },
149
+ renderSubLayers: sl => {
150
+ const { west, south, east, north } = sl.tile.bbox;
151
+ const bounds = [west, south, east, north];
152
+ //const data = sl.data && sl.data.url ? [sl.data] : [];
153
+ const { data, ...otherProps } = sl;
154
+ if (data == null) {
155
+ const canvas = document.createElement('canvas');
156
+ canvas.width = sl.tile.width;
157
+ canvas.height = sl.tile.height;
158
+ const ctx = canvas.getContext('2d');
159
+ ctx?.clearRect(0, 0, sl.tile.width, sl.tile.height); // Transparenter Hintergrund
160
+ return new BitmapLayer({
161
+ id: `dynamic-transparent-bitmap-${sl.tile.index.x}-${sl.tile.index.y}-${sl.tile.index.z}`, // Eindeutige ID!
162
+ image: canvas,
163
+ coordinates: 'pixel',
164
+ bounds: [0, 0, sl.tile.width, sl.tile.height],
165
+ });
166
+ }
167
+ return new BitmapLayer(otherProps, {
168
+ //pickable
169
+ image: data,
170
+ bounds,
171
+ opacity: sl.opacity ?? 1,
172
+ });
173
+ },
174
+ updateTriggers: {
175
+ renderSubLayers: ['sl.props.opacity'],
176
+ },
177
+ });
178
+ }
179
+ buildArcgisUrl(url, params, token) {
180
+ const query = new URLSearchParams();
181
+ if (params) {
182
+ Object.entries(params).forEach(([key, value]) => {
183
+ if (value !== undefined && value !== null) {
184
+ query.set(key, String(value));
185
+ }
186
+ });
187
+ }
188
+ if (token) {
189
+ query.set('token', token);
190
+ }
191
+ const qs = query.toString();
192
+ if (!qs)
193
+ return url;
194
+ return `${url}${url.includes('?') ? '&' : '?'}${qs}`;
195
+ }
196
+ async buildArcgisTileLayer(cfg, layerId) {
197
+ const templateUrl = this.buildArcgisUrl(cfg.url, cfg.params, cfg.token);
198
+ return this.buildXyzTileLayer({
199
+ ...cfg,
200
+ url: templateUrl,
201
+ minZoom: cfg.minZoom,
202
+ maxZoom: cfg.maxZoom,
203
+ opacity: cfg.opacity,
204
+ }, layerId);
205
+ }
206
+ async buildTerrainLayer(cfg, layerId) {
207
+ const elevationDecoder = this.normalizeElevationDecoder(cfg.elevationDecoder);
208
+ return new TerrainLayer({
209
+ id: layerId,
210
+ elevationData: cfg.elevationData,
211
+ texture: cfg.texture,
212
+ elevationDecoder,
213
+ wireframe: cfg.wireframe ?? false,
214
+ color: cfg.color,
215
+ minZoom: cfg.minZoom,
216
+ maxZoom: cfg.maxZoom,
217
+ meshMaxError: cfg.meshMaxError,
218
+ opacity: cfg.opacity ?? 1,
219
+ visible: cfg.visible ?? true,
220
+ material: true,
221
+ pickable: false,
222
+ });
223
+ }
224
+ getModelUrl(model) {
225
+ if (!model || typeof model.make !== 'function')
226
+ return undefined;
227
+ try {
228
+ const layerInstance = model.make();
229
+ const props = layerInstance?.props;
230
+ const data = props?.data;
231
+ const firstDataEntry = Array.isArray(data) ? data[0] : undefined;
232
+ return firstDataEntry ?? props?.url;
233
+ }
234
+ catch (error) {
235
+ warn('Failed to resolve model URL', error);
236
+ return undefined;
237
+ }
238
+ }
239
+ normalizeElevationDecoder(decoder) {
240
+ const defaults = {
241
+ rScaler: 1,
242
+ gScaler: 1,
243
+ bScaler: 1,
244
+ offset: 0,
245
+ };
246
+ if (!decoder) {
247
+ return defaults;
248
+ }
249
+ // Decoder may come from user config with rScaler/gScaler/bScaler or r/g/b keys
250
+ const d = decoder;
251
+ return {
252
+ rScaler: d.rScaler ?? d.r ?? defaults.rScaler,
253
+ gScaler: d.gScaler ?? d.g ?? defaults.gScaler,
254
+ bScaler: d.bScaler ?? d.b ?? defaults.bScaler,
255
+ offset: decoder.offset ?? defaults.offset,
256
+ };
257
+ }
258
+ // ========== Enhanced Styling Helper Methods ==========
259
+ /**
260
+ * Convert a Geostyler style to Deck.gl style configuration
261
+ */
262
+ createGeostylerDeckGLStyle(geostylerStyle) {
263
+ // Helper to extract static value from GeoStyler property
264
+ const getValue = (prop, defaultValue = undefined) => {
265
+ if (prop === undefined || prop === null)
266
+ return defaultValue;
267
+ // If it's a GeoStyler function object, we can't evaluate it here - return default
268
+ if (typeof prop === 'object' && prop.name)
269
+ return defaultValue;
270
+ return prop;
271
+ };
272
+ const defaultFillColor = [
273
+ 0, 100, 255, 76,
274
+ ];
275
+ const defaultStrokeColor = [
276
+ 0, 100, 255, 255,
277
+ ];
278
+ const defaultPointColor = [
279
+ 0, 100, 255, 255,
280
+ ];
281
+ let fillColorValue = defaultFillColor;
282
+ let strokeColorValue = defaultStrokeColor;
283
+ let pointColorValue = defaultPointColor;
284
+ let pointRadiusValue = 8;
285
+ let lineWidthValue = 2;
286
+ // Extract styles from rules
287
+ if (geostylerStyle.rules) {
288
+ for (const rule of geostylerStyle.rules) {
289
+ if (rule.symbolizers) {
290
+ for (const symbolizer of rule.symbolizers) {
291
+ switch (symbolizer.kind) {
292
+ case 'Fill':
293
+ const fillColor = getValue(symbolizer.color, 'rgba(0,100,255,0.3)');
294
+ const fillOpacity = getValue(symbolizer.opacity, 0.3);
295
+ fillColorValue = this.parseColor(fillColor, defaultFillColor);
296
+ if (fillOpacity !== undefined) {
297
+ fillColorValue = this.applyOpacity(fillColorValue, fillOpacity);
298
+ }
299
+ const outlineColor = getValue(symbolizer.outlineColor);
300
+ if (outlineColor) {
301
+ strokeColorValue = this.parseColor(outlineColor, defaultStrokeColor);
302
+ }
303
+ const outlineWidth = getValue(symbolizer.outlineWidth, 1);
304
+ if (outlineWidth !== undefined) {
305
+ lineWidthValue = outlineWidth;
306
+ }
307
+ break;
308
+ case 'Line':
309
+ const lineColor = getValue(symbolizer.color, 'rgba(0,100,255,1)');
310
+ strokeColorValue = this.parseColor(lineColor, defaultStrokeColor);
311
+ const lineWidth = getValue(symbolizer.width, 2);
312
+ if (lineWidth !== undefined) {
313
+ lineWidthValue = lineWidth;
314
+ }
315
+ break;
316
+ case 'Mark':
317
+ const markColor = getValue(symbolizer.color, 'rgba(0,100,255,1)');
318
+ pointColorValue = this.parseColor(markColor, defaultPointColor);
319
+ const markRadius = getValue(symbolizer.radius, 6);
320
+ if (markRadius !== undefined) {
321
+ pointRadiusValue = markRadius;
322
+ }
323
+ break;
324
+ case 'Icon':
325
+ // Icon handling would require custom IconLayer implementation
326
+ // For now, we'll use Mark as fallback
327
+ const iconSize = getValue(symbolizer.size, 32);
328
+ if (iconSize !== undefined) {
329
+ pointRadiusValue = iconSize / 2; // Convert size to radius
330
+ }
331
+ break;
332
+ }
333
+ }
334
+ }
335
+ }
336
+ }
337
+ return {
338
+ getFillColor: () => fillColorValue,
339
+ getLineColor: () => strokeColorValue,
340
+ getPointRadius: () => pointRadiusValue,
341
+ getPointFillColor: () => pointColorValue,
342
+ lineWidthMinPixels: lineWidthValue,
343
+ pointRadiusMinPixels: 2,
344
+ pointRadiusMaxPixels: 100,
345
+ };
346
+ }
347
+ /**
348
+ * Convert CSS color to Deck.gl RGBA array
349
+ */
350
+ parseColor(color, defaultColor) {
351
+ if (!color)
352
+ return defaultColor;
353
+ // Handle hex colors
354
+ if (color.startsWith('#')) {
355
+ const hex = color.slice(1);
356
+ const r = parseInt(hex.slice(0, 2), 16);
357
+ const g = parseInt(hex.slice(2, 4), 16);
358
+ const b = parseInt(hex.slice(4, 6), 16);
359
+ return [r, g, b, 255];
360
+ }
361
+ // Handle rgba/rgb colors
362
+ const rgbaMatch = color.match(/rgba?\(([^)]+)\)/);
363
+ if (rgbaMatch) {
364
+ const values = rgbaMatch[1].split(',').map(v => parseFloat(v.trim()));
365
+ return [
366
+ values[0] || 0,
367
+ values[1] || 0,
368
+ values[2] || 0,
369
+ values[3] !== undefined ? Math.round(values[3] * 255) : 255,
370
+ ];
371
+ }
372
+ return defaultColor;
373
+ }
374
+ /**
375
+ * Apply opacity to color array
376
+ */
377
+ applyOpacity(color, opacity) {
378
+ return [color[0], color[1], color[2], Math.round(opacity * 255)];
379
+ }
380
+ /**
381
+ * Create Deck.gl style configuration from StyleConfig
382
+ */
383
+ createDeckGLStyle(style = {}) {
384
+ // Default colors
385
+ const defaultFillColor = [
386
+ 0, 100, 255, 76,
387
+ ];
388
+ const defaultStrokeColor = [
389
+ 0, 100, 255, 255,
390
+ ];
391
+ const defaultPointColor = [
392
+ 0, 100, 255, 255,
393
+ ];
394
+ // Parse colors
395
+ const fillColor = this.parseColor(style.fillColor, defaultFillColor);
396
+ const strokeColor = this.parseColor(style.strokeColor, defaultStrokeColor);
397
+ const pointColor = this.parseColor(style.pointColor, defaultPointColor);
398
+ // Apply opacity
399
+ const finalFillColor = style.fillOpacity !== undefined
400
+ ? this.applyOpacity(fillColor, style.fillOpacity)
401
+ : fillColor;
402
+ const finalStrokeColor = style.strokeOpacity !== undefined
403
+ ? this.applyOpacity(strokeColor, style.strokeOpacity)
404
+ : strokeColor;
405
+ const finalPointColor = style.pointOpacity !== undefined
406
+ ? this.applyOpacity(pointColor, style.pointOpacity)
407
+ : pointColor;
408
+ return {
409
+ getFillColor: (feature) => {
410
+ // Apply conditional styling if styleFunction exists
411
+ if (style.styleFunction) {
412
+ const conditionalStyle = style.styleFunction(feature);
413
+ if (conditionalStyle.fillColor) {
414
+ const conditionalFillColor = this.parseColor(conditionalStyle.fillColor, finalFillColor);
415
+ return conditionalStyle.fillOpacity !== undefined
416
+ ? this.applyOpacity(conditionalFillColor, conditionalStyle.fillOpacity)
417
+ : conditionalFillColor;
418
+ }
419
+ }
420
+ return finalFillColor;
421
+ },
422
+ getLineColor: (feature) => {
423
+ if (style.styleFunction) {
424
+ const conditionalStyle = style.styleFunction(feature);
425
+ if (conditionalStyle.strokeColor) {
426
+ const conditionalStrokeColor = this.parseColor(conditionalStyle.strokeColor, finalStrokeColor);
427
+ return conditionalStyle.strokeOpacity !== undefined
428
+ ? this.applyOpacity(conditionalStrokeColor, conditionalStyle.strokeOpacity)
429
+ : conditionalStrokeColor;
430
+ }
431
+ }
432
+ return finalStrokeColor;
433
+ },
434
+ getPointRadius: (feature) => {
435
+ if (style.styleFunction) {
436
+ const conditionalStyle = style.styleFunction(feature);
437
+ if (conditionalStyle.pointRadius !== undefined) {
438
+ return conditionalStyle.pointRadius;
439
+ }
440
+ }
441
+ return style.pointRadius ?? 8;
442
+ },
443
+ getPointFillColor: (feature) => {
444
+ if (style.styleFunction) {
445
+ const conditionalStyle = style.styleFunction(feature);
446
+ if (conditionalStyle.pointColor) {
447
+ const conditionalPointColor = this.parseColor(conditionalStyle.pointColor, finalPointColor);
448
+ return conditionalStyle.pointOpacity !== undefined
449
+ ? this.applyOpacity(conditionalPointColor, conditionalStyle.pointOpacity)
450
+ : conditionalPointColor;
451
+ }
452
+ }
453
+ return finalPointColor;
454
+ },
455
+ lineWidthMinPixels: style.strokeWidth ?? 2,
456
+ pointRadiusMinPixels: 2,
457
+ pointRadiusMaxPixels: 100,
458
+ };
459
+ }
460
+ async buildOsmLayer(cfg, layerId) {
461
+ let url = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png';
462
+ if (cfg.url) {
463
+ url = cfg.url + '/{z}/{x}/{y}.png';
464
+ }
465
+ return this.buildXyzTileLayer({
466
+ ...cfg,
467
+ url: url,
468
+ // subdomains: cfg.subdomains || 'a,b,c',
469
+ }, layerId);
470
+ }
471
+ async buildGoogleTileLayer(cfg, layerId) {
472
+ if (!cfg.apiKey) {
473
+ throw new Error("Google-Layer benötigt 'apiKey' (Google Maps Platform).");
474
+ }
475
+ // Load Google Maps JavaScript API
476
+ await this.loadGoogleMapsApi(cfg.apiKey, {
477
+ language: cfg.language,
478
+ region: cfg.region,
479
+ libraries: cfg.libraries,
480
+ });
481
+ // For deck.gl, we'll use a simplified approach with TileLayer
482
+ // that uses Google Static Maps API for better compatibility
483
+ const mapType = cfg.mapType || 'roadmap';
484
+ const googleMapTypeId = this.getGoogleMapTypeId(mapType);
485
+ return new TileLayer({
486
+ id: layerId,
487
+ data: ['placeholder'], // Will be overridden by getTileData
488
+ opacity: cfg.opacity ?? 1,
489
+ visible: cfg.visible ?? true,
490
+ minZoom: 0,
491
+ maxZoom: cfg.maxZoom ?? 19,
492
+ tileSize: 256,
493
+ getTileData: async ({ index }) => {
494
+ const { x, y, z } = index;
495
+ // Build Google Static Maps API URL for this tile
496
+ const tilingScheme = {
497
+ tileXYToNativeRectangle: (x, y, level) => {
498
+ const n = Math.pow(2, level);
499
+ const lonLeft = (x / n) * 360 - 180;
500
+ const lonRight = ((x + 1) / n) * 360 - 180;
501
+ const latBottom = (Math.atan(Math.sinh(Math.PI * (1 - (2 * (y + 1)) / n))) * 180) /
502
+ Math.PI;
503
+ const latTop = (Math.atan(Math.sinh(Math.PI * (1 - (2 * y) / n))) * 180) /
504
+ Math.PI;
505
+ return {
506
+ west: lonLeft,
507
+ south: latBottom,
508
+ east: lonRight,
509
+ north: latTop,
510
+ };
511
+ },
512
+ };
513
+ const rect = tilingScheme.tileXYToNativeRectangle(x, y, z);
514
+ const centerLat = (rect.south + rect.north) / 2;
515
+ const centerLng = (rect.west + rect.east) / 2;
516
+ const params = new URLSearchParams({
517
+ center: `${centerLat},${centerLng}`,
518
+ zoom: z.toString(),
519
+ size: '256x256',
520
+ scale: cfg.scale === 'scaleFactor1x' ? '1' : '2',
521
+ maptype: googleMapTypeId,
522
+ key: cfg.apiKey,
523
+ format: 'png',
524
+ });
525
+ if (cfg.language)
526
+ params.set('language', cfg.language);
527
+ if (cfg.region)
528
+ params.set('region', cfg.region);
529
+ const url = `https://maps.googleapis.com/maps/api/staticmap?${params.toString()}`;
530
+ try {
531
+ const response = await fetch(url);
532
+ if (!response.ok)
533
+ throw new Error(`HTTP ${response.status}`);
534
+ return response.blob();
535
+ }
536
+ catch (error) {
537
+ warn('Failed to load Google tile:', error);
538
+ return null;
539
+ }
540
+ },
541
+ renderSubLayers: (sl) => {
542
+ const data = sl.data;
543
+ const tile = sl.tile;
544
+ if (!data)
545
+ return null;
546
+ const { west, south, east, north } = tile.bbox;
547
+ return new BitmapLayer({
548
+ id: `${layerId}-bitmap-${tile.index.x}-${tile.index.y}-${tile.index.z}`,
549
+ image: data,
550
+ bounds: [west, south, east, north],
551
+ opacity: sl.opacity ?? 1,
552
+ });
553
+ },
554
+ onTileLoad: () => {
555
+ // Add Google logo for compliance when first tile loads
556
+ this.ensureGoogleLogo(this.target);
557
+ },
558
+ });
559
+ }
560
+ getGoogleMapTypeId(mapType) {
561
+ switch (mapType) {
562
+ case 'roadmap':
563
+ return 'roadmap';
564
+ case 'satellite':
565
+ return 'satellite';
566
+ case 'terrain':
567
+ return 'terrain';
568
+ case 'hybrid':
569
+ return 'hybrid';
570
+ default:
571
+ return 'roadmap';
572
+ }
573
+ }
574
+ /**
575
+ * Load Google Maps JavaScript API
576
+ */
577
+ async loadGoogleMapsApi(apiKey, opts) {
578
+ const win = window;
579
+ const mockLoader = win.__mockGoogleMapsApi;
580
+ if (typeof mockLoader === 'function') {
581
+ await mockLoader(apiKey, opts);
582
+ return;
583
+ }
584
+ if (win.google?.maps)
585
+ return;
586
+ await new Promise((resolve, reject) => {
587
+ const cbName = '___deckGoogleInit___' + Math.random().toString(36).slice(2);
588
+ win[cbName] = () => resolve();
589
+ const script = document.createElement('script');
590
+ const params = new URLSearchParams({
591
+ key: apiKey,
592
+ callback: cbName,
593
+ v: 'weekly',
594
+ });
595
+ if (opts?.language)
596
+ params.set('language', opts.language);
597
+ if (opts?.region)
598
+ params.set('region', opts.region);
599
+ if (opts?.libraries?.length)
600
+ params.set('libraries', opts.libraries.join(','));
601
+ script.src = `https://maps.googleapis.com/maps/api/js?${params.toString()}`;
602
+ script.async = true;
603
+ script.onerror = () => reject(new Error('Google Maps JS API failed to load'));
604
+ document.head.appendChild(script);
605
+ });
606
+ }
607
+ /**
608
+ * Add Google logo for compliance
609
+ */
610
+ ensureGoogleLogo(container) {
611
+ const el = container;
612
+ if (el._googleLogoAdded)
613
+ return;
614
+ const logo = document.createElement('img');
615
+ logo.src =
616
+ 'https://developers.google.com/static/maps/documentation/images/google_on_white.png';
617
+ logo.alt = 'Google';
618
+ logo.style.position = 'absolute';
619
+ logo.style.bottom = '6px';
620
+ logo.style.left = '6px';
621
+ logo.style.height = '18px';
622
+ logo.style.pointerEvents = 'none';
623
+ logo.style.zIndex = '1000';
624
+ container.appendChild(logo);
625
+ el._googleLogoAdded = true;
626
+ }
627
+ async buildScatterPlot(layerConfig, layerId) {
628
+ const data = layerConfig.data;
629
+ const scatterLayer = new ScatterplotLayer({
630
+ id: layerId,
631
+ data, // <- dein Array von Punkten (any[] oder ein konkretes Interface)
632
+ getPosition: d => d.position,
633
+ getRadius: d => d.radius,
634
+ getFillColor: d => d.color,
635
+ radiusMinPixels: 2,
636
+ radiusMaxPixels: 30,
637
+ pickable: true,
638
+ autoHighlight: true,
639
+ highlightColor: [255, 255, 0, 128],
640
+ // optional – wenn du Hover‑Infos brauchst
641
+ onHover: info => {
642
+ if (info.object)
643
+ log('v-map - provider - deck - Hover:', info.object);
644
+ },
645
+ // Wichtig für Deck.gl, damit es erkennt, wann sich etwas ändert
646
+ updateTriggers: {
647
+ getPosition: data,
648
+ getRadius: data,
649
+ getFillColor: data,
650
+ },
651
+ });
652
+ return scatterLayer;
653
+ }
654
+ async createGeoJSONLayer(config, layerId) {
655
+ let layer = null;
656
+ let geojson_or_url = null;
657
+ if (config.geojson) {
658
+ geojson_or_url = JSON.parse(config.geojson);
659
+ }
660
+ else {
661
+ geojson_or_url = config.url;
662
+ }
663
+ if (geojson_or_url) {
664
+ // Use geostyler style if available, otherwise use default style
665
+ let deckStyle;
666
+ if (config.geostylerStyle) {
667
+ deckStyle = this.createGeostylerDeckGLStyle(config.geostylerStyle);
668
+ }
669
+ else {
670
+ const style = config.style
671
+ ? { ...DEFAULT_STYLE, ...config.style }
672
+ : DEFAULT_STYLE;
673
+ deckStyle = this.createDeckGLStyle(style);
674
+ }
675
+ layer = new GeoJsonLayer({
676
+ id: layerId,
677
+ data: geojson_or_url,
678
+ filled: true,
679
+ stroked: true,
680
+ pointType: 'circle',
681
+ pickable: true,
682
+ // Enhanced styling
683
+ ...deckStyle,
684
+ opacity: config.opacity ?? 1,
685
+ visible: config.visible ?? true,
686
+ // Update triggers for dynamic styling
687
+ updateTriggers: {
688
+ getFillColor: [config.style, config.geostylerStyle],
689
+ getLineColor: [config.style, config.geostylerStyle],
690
+ getPointRadius: [config.style, config.geostylerStyle],
691
+ data: [config.geojson, config.url],
692
+ },
693
+ });
694
+ }
695
+ return layer;
696
+ }
697
+ // --- innerhalb der DeckProvider-Klasse ---
698
+ async buildWmsTileLayer(cfg,
699
+ // cfg2: {
700
+ // url: string; // Basis-URL ohne Query (z.B. https://server/wms)
701
+ // layers: string; // Pflicht: WMS-Layers (kommagetrennt möglich)
702
+ // styles?: string; // optional
703
+ // format?: string; // default image/png
704
+ // transparent?: boolean; // default true
705
+ // version?: '1.1.1' | '1.3.0'; // default 1.3.0
706
+ // crs?: WmsCrs; // default 'EPSG:3857'
707
+ // tileSize?: number; // default 256
708
+ // minZoom?: number; // default 0
709
+ // maxZoom?: number; // default 19
710
+ // opacity?: number; // optional
711
+ // time?: string; // optional WMS TIME=
712
+ // extraParams?: Record<string, string | number | boolean>; // optional Zusatz-Parameter
713
+ // },
714
+ layerId) {
715
+ const tileSize = cfg.tileSize ?? 256;
716
+ const version = cfg.version ?? '1.3.0';
717
+ // const crs: string = cfg.crs ?? 'EPSG:3857';
718
+ const crs = 'EPSG:3857';
719
+ const format = cfg.format ?? 'image/png';
720
+ const transparent = cfg.transparent ?? true;
721
+ const crsParamKey = version === '1.1.1' ? 'SRS' : 'CRS';
722
+ const baseParams = {
723
+ SERVICE: 'WMS',
724
+ REQUEST: 'GetMap',
725
+ VERSION: version,
726
+ LAYERS: cfg.layers,
727
+ STYLES: cfg.styles ?? '',
728
+ FORMAT: format,
729
+ TRANSPARENT: transparent ? 'TRUE' : 'FALSE',
730
+ [crsParamKey]: crs,
731
+ TILED: 'true', // oder 'TRUE'
732
+ };
733
+ return new TileLayer({
734
+ id: layerId,
735
+ data: [cfg.url],
736
+ zIndex: 100,
737
+ tileSize,
738
+ minZoom: cfg.minZoom ?? 0,
739
+ maxZoom: cfg.maxZoom ?? 19,
740
+ opacity: cfg.opacity,
741
+ maxRequests: 20,
742
+ // Für jeden Tile-Index die passende GetMap-URL bauen und Bild laden
743
+ getTileData: async (tile) => {
744
+ /*
745
+ export type TileLoadProps = {
746
+ index: TileIndex;
747
+ id: string;
748
+ bbox: TileBoundingBox;
749
+ url?: string | null;
750
+ signal?: AbortSignal;
751
+ userData?: Record<string, any>;
752
+ zoom?: number;
753
+ };
754
+ */
755
+ const { west, south, east, north } = tile.bbox; // lon/lat (WGS84)
756
+ const bbox = formatBbox(west, south, east, north, version, crs);
757
+ const params = {
758
+ ...baseParams,
759
+ BBOX: bbox,
760
+ WIDTH: tileSize, //tile.width,
761
+ HEIGHT: tileSize, //tile.height,
762
+ TIME: cfg.time,
763
+ ...cfg.extraParams,
764
+ };
765
+ const url = `${cfg.url}${buildQuery(params)}`;
766
+ try {
767
+ const res = await fetch(url, {
768
+ /*signal,*/ mode: 'cors',
769
+ });
770
+ if (!res.ok)
771
+ throw new Error(`HTTP ${res.status}`);
772
+ const blob = await res.blob();
773
+ // Bei Image/* → ImageBitmap. Bei Fehlern transparente Kachel zurückgeben.
774
+ return await createImageBitmap(blob);
775
+ }
776
+ catch (err) {
777
+ this.layerErrorCallbacks.get(layerId)?.({ type: 'network', message: `WMS tile fetch error: ${err}`, cause: err });
778
+ // Transparente Fallback-Kachel, damit Deck sauber weiterzeichnet
779
+ const canvas = document.createElement('canvas');
780
+ canvas.width = tileSize;
781
+ canvas.height = tileSize;
782
+ const ctx = canvas.getContext('2d');
783
+ ctx?.clearRect(0, 0, canvas.width, canvas.height);
784
+ return canvas;
785
+ }
786
+ },
787
+ onTileError: (err) => {
788
+ log(`v-map - provider - deck - WMS Tile Error: ${err}`);
789
+ this.layerErrorCallbacks.get(layerId)?.({ type: 'network', message: `WMS tile error: ${err}`, cause: err });
790
+ },
791
+ renderSubLayers: sl => {
792
+ const { west, south, east, north } = sl.tile.bbox;
793
+ if (sl.data instanceof HTMLCanvasElement) {
794
+ return new BitmapLayer({
795
+ id: `${layerId}-bmp-${sl.tile.index.x}-${sl.tile.index.y}-${sl.tile.index.z}`, // Eindeutige ID!
796
+ image: sl.data,
797
+ coordinates: 'pixel',
798
+ bounds: [0, 0, sl.tile.width, sl.tile.height],
799
+ });
800
+ }
801
+ return new BitmapLayer({
802
+ id: `${layerId}-bmp-${sl.tile.index.x}-${sl.tile.index.y}-${sl.tile.index.z}`,
803
+ image: sl.data,
804
+ bounds: [west, south, east, north],
805
+ opacity: sl.opacity ?? 1,
806
+ pickable: false,
807
+ });
808
+ },
809
+ updateTriggers: {
810
+ // Neurendern, wenn sich Zeit/Styles/Opacity etc. ändern
811
+ getTileData: [
812
+ cfg.layers,
813
+ cfg.styles,
814
+ cfg.format,
815
+ cfg.transparent,
816
+ cfg.version,
817
+ cfg.crs,
818
+ cfg.time,
819
+ JSON.stringify(cfg.extraParams ?? {}),
820
+ ],
821
+ renderSubLayers: ['sl.props.opacity'],
822
+ },
823
+ });
824
+ }
825
+ /**
826
+ * Build WCS (Web Coverage Service) TileLayer for deck.gl
827
+ * Supports WCS 2.0.1 (subset) and 1.x.x (BBOX) versions
828
+ */
829
+ async buildWcsTileLayer(cfg, layerId) {
830
+ const tileSize = cfg.tileSize ?? 256;
831
+ const version = cfg.version ?? '2.0.1';
832
+ const format = cfg.format ?? 'image/tiff';
833
+ const projection = cfg.projection ?? 'EPSG:4326';
834
+ const baseParams = {
835
+ SERVICE: 'WCS',
836
+ REQUEST: 'GetCoverage',
837
+ VERSION: version,
838
+ FORMAT: format,
839
+ };
840
+ return new TileLayer({
841
+ id: layerId,
842
+ data: [cfg.url],
843
+ zIndex: 100,
844
+ tileSize,
845
+ minZoom: cfg.minZoom ?? 0,
846
+ maxZoom: cfg.maxZoom ?? 19,
847
+ opacity: cfg.opacity,
848
+ maxRequests: 20,
849
+ getTileData: async (tile) => {
850
+ const { west, south, east, north } = tile.bbox;
851
+ let params;
852
+ // WCS 2.0.1 uses subset parameters
853
+ if (version.startsWith('2.0')) {
854
+ params = {
855
+ ...baseParams,
856
+ coverageId: cfg.coverageName,
857
+ ...cfg.params,
858
+ };
859
+ // Add GeoTIFF compression if format is tiff
860
+ if (format.includes('tiff') || format.includes('geotiff')) {
861
+ params['geotiff:compression'] = 'LZW';
862
+ }
863
+ // Build query string with subset parameters
864
+ const queryString = buildQuery(params);
865
+ const subsetX = `subset=X(${west},${east})`;
866
+ const subsetY = `subset=Y(${south},${north})`;
867
+ const url = `${cfg.url}${queryString}&${subsetX}&${subsetY}`;
868
+ try {
869
+ const res = await fetch(url, { mode: 'cors' });
870
+ if (!res.ok)
871
+ throw new Error(`HTTP ${res.status}`);
872
+ const blob = await res.blob();
873
+ return await createImageBitmap(blob);
874
+ }
875
+ catch (err) {
876
+ this.layerErrorCallbacks.get(layerId)?.({ type: 'network', message: `WCS tile fetch error: ${err}`, cause: err });
877
+ // Return transparent fallback tile
878
+ const canvas = document.createElement('canvas');
879
+ canvas.width = tileSize;
880
+ canvas.height = tileSize;
881
+ const ctx = canvas.getContext('2d');
882
+ ctx?.clearRect(0, 0, canvas.width, canvas.height);
883
+ return canvas;
884
+ }
885
+ }
886
+ // WCS 1.x.x uses BBOX parameter
887
+ else {
888
+ params = {
889
+ ...baseParams,
890
+ COVERAGE: cfg.coverageName,
891
+ BBOX: `${west},${south},${east},${north}`,
892
+ CRS: projection,
893
+ WIDTH: tileSize,
894
+ HEIGHT: tileSize,
895
+ ...cfg.params,
896
+ };
897
+ const url = `${cfg.url}${buildQuery(params)}`;
898
+ try {
899
+ const res = await fetch(url, { mode: 'cors' });
900
+ if (!res.ok)
901
+ throw new Error(`HTTP ${res.status}`);
902
+ const blob = await res.blob();
903
+ return await createImageBitmap(blob);
904
+ }
905
+ catch (err) {
906
+ this.layerErrorCallbacks.get(layerId)?.({ type: 'network', message: `WCS tile fetch error: ${err}`, cause: err });
907
+ // Return transparent fallback tile
908
+ const canvas = document.createElement('canvas');
909
+ canvas.width = tileSize;
910
+ canvas.height = tileSize;
911
+ const ctx = canvas.getContext('2d');
912
+ ctx?.clearRect(0, 0, canvas.width, canvas.height);
913
+ return canvas;
914
+ }
915
+ }
916
+ },
917
+ onTileError: (err) => {
918
+ log(`v-map - provider - deck - WCS Tile Error: ${err}`);
919
+ this.layerErrorCallbacks.get(layerId)?.({ type: 'network', message: `WCS tile error: ${err}`, cause: err });
920
+ },
921
+ renderSubLayers: sl => {
922
+ const { west, south, east, north } = sl.tile.bbox;
923
+ if (sl.data instanceof HTMLCanvasElement) {
924
+ return new BitmapLayer({
925
+ id: `${layerId}-bmp-${sl.tile.index.x}-${sl.tile.index.y}-${sl.tile.index.z}`,
926
+ image: sl.data,
927
+ coordinates: 'pixel',
928
+ bounds: [0, 0, sl.tile.width, sl.tile.height],
929
+ });
930
+ }
931
+ return new BitmapLayer({
932
+ id: `${layerId}-bmp-${sl.tile.index.x}-${sl.tile.index.y}-${sl.tile.index.z}`,
933
+ image: sl.data,
934
+ bounds: [west, south, east, north],
935
+ opacity: sl.opacity ?? 1,
936
+ pickable: false,
937
+ });
938
+ },
939
+ updateTriggers: {
940
+ getTileData: [
941
+ cfg.coverageName,
942
+ cfg.format,
943
+ cfg.version,
944
+ cfg.projection,
945
+ JSON.stringify(cfg.params ?? {}),
946
+ ],
947
+ renderSubLayers: ['sl.props.opacity'],
948
+ },
949
+ });
950
+ }
951
+ async createLayer(layerConfig, layerId) {
952
+ switch (layerConfig.type) {
953
+ case 'geojson':
954
+ return this.createGeoJSONLayer(layerConfig, layerId);
955
+ case 'osm':
956
+ return this.buildOsmLayer(layerConfig, layerId);
957
+ case 'google':
958
+ return this.buildGoogleTileLayer(layerConfig, layerId);
959
+ case 'wms':
960
+ return this.buildWmsTileLayer(layerConfig, layerId);
961
+ case 'wcs':
962
+ return this.buildWcsTileLayer(layerConfig, layerId);
963
+ case 'wfs':
964
+ return this.createWFSLayer(layerConfig, layerId);
965
+ case 'arcgis':
966
+ return this.buildArcgisTileLayer(layerConfig, layerId);
967
+ case 'terrain':
968
+ return this.buildTerrainLayer(layerConfig, layerId);
969
+ case 'terrain-geotiff':
970
+ return this.createGeoTIFFTerrainLayer(layerConfig, layerId);
971
+ case 'xyz':
972
+ return this.buildXyzTileLayer(layerConfig, layerId);
973
+ case 'scatterplot':
974
+ return this.buildScatterPlot(layerConfig, layerId);
975
+ case 'wkt':
976
+ return this.createWKTLayer(layerConfig, layerId);
977
+ case 'geotiff':
978
+ return this.createGeoTIFFLayer(layerConfig, layerId);
979
+ default:
980
+ log(`v-map - provider - deck - Unsupported layer type: ${layerConfig.type}`);
981
+ return null;
982
+ }
983
+ }
984
+ // ---------- Provider-API: nutzt NUR Model/Store ----------
985
+ // async addLayer(config: LayerConfig): Promise<string> {
986
+ // const groupId = config.groupId ?? 'default';
987
+ // const group = this.ensureModelGroup(groupId);
988
+ // const layerId = crypto.randomUUID();
989
+ // const make = async () => this.createLayer(config, layerId);
990
+ // const model = this.createLayerModel(layerId, () => null as any, true);
991
+ // // make() lazy auflösen (async Factory umwickeln)
992
+ // model.make = () => {
993
+ // // Achtung: Factory muss sync sein → wir „promoten“ hier bekannte Layer
994
+ // // Lösung: createLayer bei add* schon aufrufen:
995
+ // throw new Error('model.make should not be async');
996
+ // };
997
+ // // Besser: Layer jetzt schon erstellen, damit make() sync bleibt:
998
+ // const layer = await this.createLayer(config, layerId);
999
+ // model.make = () => layer;
1000
+ // group.addModel(model);
1001
+ // // Overrides aus config übernehmen
1002
+ // const ov: any = {};
1003
+ // if ((config as any).opacity !== undefined)
1004
+ // ov.opacity = (config as any).opacity;
1005
+ // if ((config as any).zIndex !== undefined)
1006
+ // ov.zIndex = (config as any).zIndex;
1007
+ // if ((config as any).visible === true) ov.visible = true;
1008
+ // if ((config as any).visible === false) ov.visible = false;
1009
+ // if (Object.keys(ov).length) group.setModelOverrides(layerId, ov);
1010
+ // // Render
1011
+ // this.layerGroups.applyToDeck();
1012
+ // return layerId;
1013
+ // }
1014
+ async addLayerToGroup(layerConfig) {
1015
+ const group = this.ensureModelGroup(layerConfig.groupId);
1016
+ const layerId = crypto.randomUUID();
1017
+ const template = await this.createLayer(layerConfig, layerId);
1018
+ if (!template)
1019
+ return null;
1020
+ const model = this.createLayerModel(layerId, () => template.clone({}), layerConfig.visible ?? true);
1021
+ if (typeof layerConfig.groupVisible !== undefined) {
1022
+ group.visible = layerConfig.groupVisible;
1023
+ }
1024
+ group.addModel(model);
1025
+ const ov = {};
1026
+ if (layerConfig.opacity !== undefined)
1027
+ ov.opacity = layerConfig.opacity;
1028
+ if (layerConfig.zIndex !== undefined)
1029
+ ov.zIndex = layerConfig.zIndex;
1030
+ if (layerConfig.visible === true)
1031
+ ov.visible = true;
1032
+ if (layerConfig.visible === false)
1033
+ ov.visible = false;
1034
+ if (Object.keys(ov).length)
1035
+ group.setModelOverrides(layerId, ov);
1036
+ this.layerGroups.applyToDeck();
1037
+ return layerId;
1038
+ }
1039
+ async addBaseLayer(layerConfig, basemapid, layerElementId) {
1040
+ if (!layerElementId || !basemapid) {
1041
+ log('ol - addBaseLayer - ids missing');
1042
+ return null;
1043
+ }
1044
+ const group = this.ensureModelGroup(layerConfig.groupId ?? 'basemap');
1045
+ group.basemap = basemapid;
1046
+ const layerId = crypto.randomUUID();
1047
+ const layer = await this.createLayer(layerConfig, layerId);
1048
+ if (!layer)
1049
+ return null;
1050
+ const model = this.createLayerModel(layerId, () => layer, true, layerElementId);
1051
+ group.addModel(model);
1052
+ // Overrides aus config
1053
+ const ov = {};
1054
+ if (layerConfig.opacity !== undefined)
1055
+ ov.opacity = layerConfig.opacity;
1056
+ if (layerConfig.zIndex !== undefined)
1057
+ ov.zIndex = layerConfig.zIndex;
1058
+ if (layerConfig.visible === true)
1059
+ ov.visible = true;
1060
+ if (layerConfig.visible === false)
1061
+ ov.visible = false;
1062
+ if (Object.keys(ov).length)
1063
+ group.setModelOverrides(layerId, ov);
1064
+ this.layerGroups.applyToDeck();
1065
+ return layerId;
1066
+ }
1067
+ async setBaseLayer(groupId, layerElementId) {
1068
+ const group = this.ensureModelGroup(groupId);
1069
+ group.basemap = layerElementId ?? null;
1070
+ this.layerGroups.applyToDeck();
1071
+ }
1072
+ async ensureGroup(groupId, visible, _opts) {
1073
+ await this._ensureGroup(groupId, visible, _opts);
1074
+ }
1075
+ async _ensureGroup(groupId, visible, opts) {
1076
+ const existed = this.layerGroups.hasGroup(groupId);
1077
+ const group = this.ensureModelGroup(groupId);
1078
+ if (typeof visible === 'boolean' && group.visible !== visible) {
1079
+ group.visible = visible;
1080
+ }
1081
+ if (opts?.basemapid !== undefined && group.basemap !== opts.basemapid) {
1082
+ group.basemap = opts.basemapid ?? null;
1083
+ }
1084
+ if (!existed ||
1085
+ typeof visible === 'boolean' ||
1086
+ opts?.basemapid !== undefined) {
1087
+ this.layerGroups.applyToDeck();
1088
+ }
1089
+ return group;
1090
+ }
1091
+ // ------ Updates: ausschließlich via Model-Overrides / Model-Factory ------
1092
+ async updateLayer(layerId, update) {
1093
+ // Finde die Gruppe, die das Model hat
1094
+ const group = this.layerGroups.groups.find(g => g.getModel?.(layerId));
1095
+ if (!group)
1096
+ return;
1097
+ switch (update.type) {
1098
+ case 'geojson': {
1099
+ const data = update.data?.geojson
1100
+ ? JSON.parse(update.data.geojson)
1101
+ : update.data?.url;
1102
+ if (data)
1103
+ group.setModelOverrides(layerId, { data });
1104
+ break;
1105
+ }
1106
+ case 'osm': {
1107
+ if (update.data?.url)
1108
+ group.setModelOverrides(layerId, {
1109
+ url: `${update.data.url}/{z}/{x}/{y}.png`,
1110
+ });
1111
+ break;
1112
+ }
1113
+ case 'google': {
1114
+ // Google maps updates would require rebuilding the layer
1115
+ // as tile URLs are constructed dynamically
1116
+ if (update.data?.mapType || update.data?.apiKey) {
1117
+ // For now, log that Google updates aren't fully supported
1118
+ warn('Google Maps layer updates require full layer recreation');
1119
+ }
1120
+ break;
1121
+ }
1122
+ case 'wms': {
1123
+ const ov = {};
1124
+ if (update.data?.url)
1125
+ ov.url = update.data.url; // Basis-URL
1126
+ if (update.data?.layers)
1127
+ ov.layers = update.data.layers;
1128
+ if (update.data?.styles !== undefined)
1129
+ ov.styles = update.data.styles;
1130
+ if (update.data?.format)
1131
+ ov.format = update.data.format;
1132
+ if (update.data?.transparent !== undefined)
1133
+ ov.transparent = update.data.transparent;
1134
+ if (update.data?.version)
1135
+ ov.version = update.data.version;
1136
+ if (update.data?.crs)
1137
+ ov.crs = update.data.crs;
1138
+ if (update.data?.time !== undefined)
1139
+ ov.time = update.data.time;
1140
+ if (update.data?.extraParams)
1141
+ ov.extraParams = update.data.extraParams;
1142
+ if (Object.keys(ov).length)
1143
+ group.setModelOverrides(layerId, ov);
1144
+ break;
1145
+ }
1146
+ case 'wcs': {
1147
+ const ov = {};
1148
+ if (update.data?.url)
1149
+ ov.url = update.data.url;
1150
+ if (update.data?.coverageName)
1151
+ ov.coverageName = update.data.coverageName;
1152
+ if (update.data?.format)
1153
+ ov.format = update.data.format;
1154
+ if (update.data?.version)
1155
+ ov.version = update.data.version;
1156
+ if (update.data?.projection)
1157
+ ov.projection = update.data.projection;
1158
+ if (update.data?.params)
1159
+ ov.params = update.data.params;
1160
+ if (update.data?.tileSize !== undefined)
1161
+ ov.tileSize = update.data.tileSize;
1162
+ if (update.data?.minZoom !== undefined)
1163
+ ov.minZoom = update.data.minZoom;
1164
+ if (update.data?.maxZoom !== undefined)
1165
+ ov.maxZoom = update.data.maxZoom;
1166
+ if (Object.keys(ov).length)
1167
+ group.setModelOverrides(layerId, ov);
1168
+ break;
1169
+ }
1170
+ case 'arcgis': {
1171
+ const ov = {};
1172
+ const currentModel = group.getModel?.(layerId);
1173
+ const currentUrl = this.getModelUrl(currentModel);
1174
+ const baseUrl = update.data?.url ?? currentUrl ?? null;
1175
+ if (baseUrl) {
1176
+ const nextUrl = this.buildArcgisUrl(baseUrl, update.data?.params, update.data?.token);
1177
+ ov.data = [nextUrl];
1178
+ ov.url = nextUrl;
1179
+ }
1180
+ if (update.data?.minZoom !== undefined)
1181
+ ov.minZoom = update.data.minZoom;
1182
+ if (update.data?.maxZoom !== undefined)
1183
+ ov.maxZoom = update.data.maxZoom;
1184
+ if (Object.keys(ov).length)
1185
+ group.setModelOverrides(layerId, ov);
1186
+ break;
1187
+ }
1188
+ case 'terrain': {
1189
+ const ov = {};
1190
+ if (update.data?.elevationData)
1191
+ ov.elevationData = update.data.elevationData;
1192
+ if (update.data?.texture !== undefined)
1193
+ ov.texture = update.data.texture;
1194
+ if (update.data?.elevationDecoder !== undefined)
1195
+ ov.elevationDecoder = update.data.elevationDecoder;
1196
+ if (update.data?.wireframe !== undefined)
1197
+ ov.wireframe = update.data.wireframe;
1198
+ if (update.data?.color !== undefined)
1199
+ ov.color = update.data.color;
1200
+ if (update.data?.meshMaxError !== undefined)
1201
+ ov.meshMaxError = update.data.meshMaxError;
1202
+ if (Object.keys(ov).length)
1203
+ group.setModelOverrides(layerId, ov);
1204
+ break;
1205
+ }
1206
+ case 'wkt': {
1207
+ if (update.data?.wkt) {
1208
+ const data = await this.wktToGeoJSON(update.data.wkt);
1209
+ group.setModelOverrides(layerId, { data });
1210
+ }
1211
+ else if (update.data?.url) {
1212
+ group.setModelOverrides(layerId, { data: update.data.url });
1213
+ }
1214
+ break;
1215
+ }
1216
+ case 'geotiff': {
1217
+ const data = (update.data ?? {});
1218
+ const ov = {};
1219
+ if ('url' in data)
1220
+ ov.url = data.url;
1221
+ if ('nodata' in data)
1222
+ ov.noDataValue = data.nodata;
1223
+ if ('colorMap' in data)
1224
+ ov.colorMap = data.colorMap;
1225
+ if ('valueRange' in data)
1226
+ ov.valueRange = data.valueRange;
1227
+ if ('resolution' in data)
1228
+ ov.resolution = data.resolution;
1229
+ if ('resampleMethod' in data)
1230
+ ov.resampleMethod = data.resampleMethod;
1231
+ if (Object.keys(ov).length)
1232
+ group.setModelOverrides(layerId, ov);
1233
+ break;
1234
+ }
1235
+ case 'terrain-geotiff': {
1236
+ const data = (update.data ?? {});
1237
+ const ov = {};
1238
+ if ('url' in data)
1239
+ ov.url = data.url;
1240
+ if ('projection' in data)
1241
+ ov.projection = data.projection;
1242
+ if ('forceProjection' in data)
1243
+ ov.forceProjection = data.forceProjection;
1244
+ if ('nodata' in data)
1245
+ ov.noDataValue = data.nodata;
1246
+ if ('meshMaxError' in data)
1247
+ ov.meshMaxError = data.meshMaxError;
1248
+ if ('wireframe' in data)
1249
+ ov.wireframe = data.wireframe;
1250
+ if ('texture' in data)
1251
+ ov.texture = data.texture;
1252
+ if ('color' in data)
1253
+ ov.color = data.color;
1254
+ if ('colorMap' in data)
1255
+ ov.colorMap = data.colorMap;
1256
+ if ('valueRange' in data)
1257
+ ov.valueRange = data.valueRange;
1258
+ if ('elevationScale' in data)
1259
+ ov.elevationScale = data.elevationScale;
1260
+ if ('renderMode' in data)
1261
+ ov.renderMode = data.renderMode;
1262
+ if (Object.keys(ov).length)
1263
+ group.setModelOverrides(layerId, ov);
1264
+ break;
1265
+ }
1266
+ case 'wfs': {
1267
+ const geojson = await this.fetchWFSFromUrl(update.data);
1268
+ group.setModelOverrides(layerId, { data: geojson });
1269
+ break;
1270
+ }
1271
+ }
1272
+ this.layerGroups.applyToDeck();
1273
+ }
1274
+ onLayerError(layerId, callback) {
1275
+ this.layerErrorCallbacks.set(layerId, callback);
1276
+ }
1277
+ offLayerError(layerId) {
1278
+ this.layerErrorCallbacks.delete(layerId);
1279
+ }
1280
+ async removeLayer(layerId) {
1281
+ this.offLayerError(layerId);
1282
+ // Modellbasiert: Model entfernen → apply
1283
+ for (const g of this.layerGroups.groups) {
1284
+ const modelGroup = g;
1285
+ const removeModel = modelGroup.removeModel?.bind(modelGroup);
1286
+ const getModel = modelGroup.getModel?.bind(modelGroup);
1287
+ if (typeof getModel === 'function' && getModel(layerId)) {
1288
+ removeModel(layerId);
1289
+ this.layerGroups.applyToDeck();
1290
+ return;
1291
+ }
1292
+ }
1293
+ // Fallback: falls nicht modellbasiert vorhanden, klassisch entfernen
1294
+ this.layerGroups.removeLayer(layerId, { removeFromAll: true });
1295
+ }
1296
+ async setOpacity(layerId, opacity) {
1297
+ const g = this.layerGroups.groups.find(grp => grp.getModel?.(layerId));
1298
+ if (!g)
1299
+ return;
1300
+ g.setModelOverrides(layerId, { opacity });
1301
+ this.layerGroups.applyToDeck();
1302
+ }
1303
+ async setZIndex(layerId, zIndex) {
1304
+ const g = this.layerGroups.groups.find(grp => grp.getModel?.(layerId));
1305
+ if (!g)
1306
+ return;
1307
+ g.setModelOverrides(layerId, { zIndex });
1308
+ this.layerGroups.applyToDeck();
1309
+ }
1310
+ async setVisible(layerId, visible) {
1311
+ const g = this.layerGroups.groups.find(grp => grp.getModel?.(layerId));
1312
+ if (!g)
1313
+ return;
1314
+ // zwei Ebenen: Model.enabled (dein "Layer visible") und Deck-Visible
1315
+ g.setModelEnabled(layerId, visible); // Model-Visibility
1316
+ g.setModelOverrides(layerId, { visible }); // Deck-Override (optional)
1317
+ this.layerGroups.applyToDeck();
1318
+ }
1319
+ async setGroupVisible(groupId, visible) {
1320
+ this.layerGroups.setGroupVisible(groupId, visible);
1321
+ }
1322
+ async setView([lon, lat], zoom) {
1323
+ this.deck?.setProps({
1324
+ viewState: { longitude: lon, latitude: lat, zoom, bearing: 0, pitch: 0 },
1325
+ });
1326
+ }
1327
+ async createWKTLayer(config, layerId) {
1328
+ const geoJsonData = await this.resolveWktToGeoJSON(config);
1329
+ // Use geostyler style if available, otherwise use default style
1330
+ let deckStyle;
1331
+ if (config.geostylerStyle) {
1332
+ deckStyle = this.createGeostylerDeckGLStyle(config.geostylerStyle);
1333
+ }
1334
+ else {
1335
+ const style = config.style
1336
+ ? { ...DEFAULT_STYLE, ...config.style }
1337
+ : DEFAULT_STYLE;
1338
+ deckStyle = this.createDeckGLStyle(style);
1339
+ }
1340
+ return new GeoJsonLayer({
1341
+ id: layerId,
1342
+ data: geoJsonData,
1343
+ filled: true,
1344
+ stroked: true,
1345
+ pointType: 'circle',
1346
+ pickable: true,
1347
+ // Enhanced styling
1348
+ ...deckStyle,
1349
+ opacity: config.opacity ?? 1,
1350
+ visible: config.visible ?? true,
1351
+ // Update triggers for dynamic styling
1352
+ updateTriggers: {
1353
+ getFillColor: [config.style, config.geostylerStyle],
1354
+ getLineColor: [config.style, config.geostylerStyle],
1355
+ getPointRadius: [config.style, config.geostylerStyle],
1356
+ data: [config.wkt, config.url],
1357
+ },
1358
+ });
1359
+ }
1360
+ async resolveWktToGeoJSON(config) {
1361
+ try {
1362
+ const wktText = await this.resolveWktText(config);
1363
+ return await this.wktToGeoJSON(wktText);
1364
+ }
1365
+ catch (e) {
1366
+ log('v-map - provider - deck - Failed to parse WKT:', e);
1367
+ return { type: 'FeatureCollection', features: [] };
1368
+ }
1369
+ }
1370
+ async resolveWktText(config) {
1371
+ if (config.wkt)
1372
+ return config.wkt;
1373
+ if (config.url) {
1374
+ const response = await fetch(config.url);
1375
+ if (!response.ok)
1376
+ throw new Error(`Failed to fetch WKT: ${response.status}`);
1377
+ return await response.text();
1378
+ }
1379
+ throw new Error('Either wkt or url must be provided');
1380
+ }
1381
+ async wktToGeoJSON(wkt) {
1382
+ const parseFn = typeof wellknownModule.default === 'function'
1383
+ ? wellknownModule.default
1384
+ : wellknownModule.parse;
1385
+ if (typeof parseFn !== 'function') {
1386
+ throw new Error('wellknown parser not available');
1387
+ }
1388
+ const geometry = parseFn(wkt);
1389
+ if (!geometry) {
1390
+ throw new Error('Failed to parse WKT');
1391
+ }
1392
+ return {
1393
+ type: 'FeatureCollection',
1394
+ features: [
1395
+ {
1396
+ type: 'Feature',
1397
+ geometry,
1398
+ properties: {},
1399
+ },
1400
+ ],
1401
+ };
1402
+ }
1403
+ async createGeoTIFFLayer(config, layerId) {
1404
+ if (!config.url) {
1405
+ throw new Error('GeoTIFF layer requires a URL');
1406
+ }
1407
+ try {
1408
+ const layer = await createDeckGLGeoTIFFLayer({
1409
+ id: layerId,
1410
+ url: config.url,
1411
+ opacity: config.opacity ?? 1.0,
1412
+ visible: config.visible ?? true,
1413
+ noDataValue: config.nodata,
1414
+ nullColor: [0, 0, 0, 0],
1415
+ onTileLoadError: (err) => {
1416
+ this.layerErrorCallbacks.get(layerId)?.({ type: 'network', message: `GeoTIFF tile error: ${err.message}`, cause: err });
1417
+ },
1418
+ });
1419
+ return layer;
1420
+ }
1421
+ catch (error) {
1422
+ log('v-map - provider - deck - Failed to create GeoTIFF layer:', error);
1423
+ return new GeoJsonLayer({
1424
+ id: layerId,
1425
+ data: { type: 'FeatureCollection', features: [] },
1426
+ opacity: 0,
1427
+ });
1428
+ }
1429
+ }
1430
+ async createGeoTIFFTerrainLayer(config, layerId) {
1431
+ try {
1432
+ const layer = await createDeckGLGeoTIFFTerrainLayer({
1433
+ id: layerId,
1434
+ url: config.url,
1435
+ projection: config.projection,
1436
+ forceProjection: config.forceProjection,
1437
+ noDataValue: config.nodata,
1438
+ minZoom: config.minZoom,
1439
+ maxZoom: config.maxZoom,
1440
+ tileSize: config.tileSize,
1441
+ meshMaxError: config.meshMaxError,
1442
+ wireframe: config.wireframe,
1443
+ texture: config.texture,
1444
+ color: config.color,
1445
+ colorMap: config.colorMap,
1446
+ valueRange: config.valueRange,
1447
+ elevationScale: config.elevationScale,
1448
+ renderMode: config.renderMode,
1449
+ opacity: config.opacity ?? 1.0,
1450
+ visible: config.visible ?? true,
1451
+ onTileLoadError: (err) => {
1452
+ this.layerErrorCallbacks.get(layerId)?.({ type: 'network', message: `GeoTIFF terrain tile error: ${err.message}`, cause: err });
1453
+ },
1454
+ });
1455
+ return layer;
1456
+ }
1457
+ catch (error) {
1458
+ log('v-map - provider - deck - Failed to create GeoTIFF Terrain layer:', error);
1459
+ return null;
1460
+ }
1461
+ }
1462
+ onPointerMove(callback) {
1463
+ const handler = (e) => {
1464
+ const rect = this.target.getBoundingClientRect();
1465
+ const pixel = [e.clientX - rect.left, e.clientY - rect.top];
1466
+ try {
1467
+ const viewport = this.deck?.getViewports()?.[0];
1468
+ if (viewport) {
1469
+ const [lng, lat] = viewport.unproject(pixel);
1470
+ callback([lng, lat], pixel);
1471
+ }
1472
+ else {
1473
+ callback(null, pixel);
1474
+ }
1475
+ }
1476
+ catch {
1477
+ callback(null, pixel);
1478
+ }
1479
+ };
1480
+ this.target.addEventListener('pointermove', handler);
1481
+ return () => this.target.removeEventListener('pointermove', handler);
1482
+ }
1483
+ async destroy() {
1484
+ try {
1485
+ this.layerGroups.clear({ destroy: true });
1486
+ if (this.shadowRoot)
1487
+ this.injectedStyle?.remove();
1488
+ this.deck?.finalize();
1489
+ }
1490
+ catch { }
1491
+ }
1492
+ async createWFSLayer(config, layerId) {
1493
+ const geojson = await this.fetchWFSFromUrl(config);
1494
+ // Use geostyler style if available, otherwise use default style
1495
+ let deckStyle;
1496
+ if (config.geostylerStyle) {
1497
+ deckStyle = this.createGeostylerDeckGLStyle(config.geostylerStyle);
1498
+ }
1499
+ else {
1500
+ const style = config.style
1501
+ ? { ...DEFAULT_STYLE, ...config.style }
1502
+ : DEFAULT_STYLE;
1503
+ deckStyle = this.createDeckGLStyle(style);
1504
+ }
1505
+ const layer = new GeoJsonLayer({
1506
+ id: layerId,
1507
+ data: geojson,
1508
+ filled: true,
1509
+ stroked: true,
1510
+ pointType: 'circle',
1511
+ ...deckStyle,
1512
+ pickable: true,
1513
+ autoHighlight: true,
1514
+ });
1515
+ return layer;
1516
+ }
1517
+ async fetchWFSFromUrl(config) {
1518
+ const baseParams = {
1519
+ service: 'WFS',
1520
+ request: 'GetFeature',
1521
+ version: config.version ?? '1.1.0',
1522
+ typeName: config.typeName,
1523
+ outputFormat: config.outputFormat ?? 'application/json',
1524
+ srsName: config.srsName ?? 'EPSG:4326',
1525
+ };
1526
+ const params = { ...baseParams, ...(config.params ?? {}) };
1527
+ const requestUrl = this.appendParams(config.url, params);
1528
+ const response = await fetch(requestUrl);
1529
+ if (!response.ok) {
1530
+ throw new Error(`WFS request failed (${response.status} ${response.statusText})`);
1531
+ }
1532
+ const outputFormat = (config.outputFormat ?? 'application/json').toLowerCase();
1533
+ // Handle JSON formats
1534
+ if (outputFormat.includes('json') ||
1535
+ outputFormat.includes('geojson') ||
1536
+ outputFormat === 'application/json') {
1537
+ return await response.json();
1538
+ }
1539
+ // Handle GML formats - parse XML to GeoJSON using @npm9912/s-gml
1540
+ if (outputFormat.includes('gml') || outputFormat.includes('xml')) {
1541
+ const xml = await response.text();
1542
+ const parser = new GmlParser();
1543
+ return await parser.parse(xml);
1544
+ }
1545
+ // Default: try to parse as JSON
1546
+ return await response.json();
1547
+ }
1548
+ appendParams(baseUrl, params) {
1549
+ const query = new URLSearchParams();
1550
+ Object.entries(params).forEach(([key, value]) => {
1551
+ if (value !== undefined && value !== null) {
1552
+ query.set(key, String(value));
1553
+ }
1554
+ });
1555
+ if (!query.toString())
1556
+ return baseUrl;
1557
+ return `${baseUrl}${baseUrl.includes('?') ? '&' : '?'}${query.toString()}`;
1558
+ }
1559
+ getMap() {
1560
+ return this.deck;
1561
+ }
1562
+ }
1563
+ export default DeckProvider;