@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,1794 @@
1
+ import { i as isBrowser, L as LEAFLET_VERSION, s as supportsAdoptedStyleSheets, w as watchElementResize } from './v-map.v-map-layer-osm.v-map-layergroup-B4pFHuSf.js';
2
+ import * as L from 'leaflet';
3
+ import { e as error, l as log } from './messages-CMKJzsgL.js';
4
+ import { D as DEFAULT_STYLE } from './styleconfig-B-bAcABs.js';
5
+ import { l as loadGeoTIFFSource, G as GeoTIFFTileProcessor, g as getColorStops } from './geotiff-source-esnDnC-u.js';
6
+ import { w as wellknownExports } from './index-BUHa4Jj0.js';
7
+ import { GmlParser } from './index.browser-DhQAXuA7.js';
8
+ import './index-jzneDarq.js';
9
+ import './v-map-layer-helper-Dys44Cgo.js';
10
+ import './_commonjsHelpers-E-ZsRS8r.js';
11
+
12
+ function injectInlineMin(root) {
13
+ if (!isBrowser())
14
+ return;
15
+ const css = `
16
+ :host { display:block; }
17
+ #map { width:100%; height:100%; display:block; }
18
+ `;
19
+ if (supportsAdoptedStyleSheets()) {
20
+ const sheet = new CSSStyleSheet();
21
+ sheet.replaceSync(css);
22
+ const target = (root ?? document);
23
+ const current = target.adoptedStyleSheets ?? [];
24
+ target.adoptedStyleSheets = [...current, sheet];
25
+ return null;
26
+ }
27
+ else {
28
+ const style = document.createElement('style');
29
+ style.textContent = css;
30
+ (root ?? document.head).appendChild(style);
31
+ return style;
32
+ }
33
+ }
34
+ function addLeafletCssFromCdn(root, version = LEAFLET_VERSION, cdn = 'jsdelivr') {
35
+ if (!isBrowser())
36
+ return;
37
+ const href = cdn === 'unpkg'
38
+ ? `https://unpkg.com/leaflet@${version}/dist/leaflet.css`
39
+ : `https://cdn.jsdelivr.net/npm/leaflet@${version}/dist/leaflet.css`;
40
+ if (cdn === 'unpkg')
41
+ L.Icon.Default.imagePath = `https://unpkg.com/npm/leaflet@${version}/dist/images/`;
42
+ else
43
+ L.Icon.Default.imagePath = `https://cdn.jsdelivr.net/npm/leaflet@${version}/dist/images/`;
44
+ // doppelte Injektion vermeiden (prüfe ShadowRoot **und** globales head)
45
+ const scope = root ?? document;
46
+ const already = scope.querySelector?.(`link[rel="stylesheet"][href="${href}"]`) ||
47
+ document.head.querySelector(`link[rel="stylesheet"][href="${href}"]`);
48
+ if (already)
49
+ return null;
50
+ const link = document.createElement('link');
51
+ link.rel = 'stylesheet';
52
+ link.href = href;
53
+ // Optional: link.integrity = '<SRI-Hash>'; link.crossOrigin = '';
54
+ (root ?? document.head).appendChild(link);
55
+ return link;
56
+ }
57
+ function removeInjectedCss(shadowRoot, injectedStyle) {
58
+ if (!shadowRoot || !injectedStyle)
59
+ return;
60
+ // Das <style>-Element aus dem Shadow‑DOM entfernen
61
+ injectedStyle.remove(); // moderne API
62
+ }
63
+ function ensureLeafletCss(mode, root) {
64
+ if (!isBrowser())
65
+ return; // Tests/SSR: no-op
66
+ switch (mode) {
67
+ case 'cdn':
68
+ return addLeafletCssFromCdn(root);
69
+ case 'inline-min':
70
+ return injectInlineMin(root);
71
+ }
72
+ return null;
73
+ }
74
+ // Die Google Maps JS API wird seit der Umstellung auf Map Tiles nicht mehr geladen.
75
+ /** Fügt ein kleines Google-Logo als Leaflet-Control hinzu (Branding-Sicherheit) */
76
+ function ensureGoogleLogo(map, markAdded) {
77
+ if (map._googleLogoAdded)
78
+ return;
79
+ const Logo = L.Control.extend({
80
+ onAdd() {
81
+ const img = L.DomUtil.create('img');
82
+ img.src =
83
+ 'https://developers.google.com/static/maps/documentation/images/google_on_white.png';
84
+ img.alt = 'Google';
85
+ img.style.pointerEvents = 'none';
86
+ img.style.height = '18px';
87
+ img.style.margin = '0 0 6px 6px';
88
+ return img;
89
+ },
90
+ onRemove() { },
91
+ });
92
+ new Logo({ position: 'bottomleft' }).addTo(map);
93
+ map._googleLogoAdded = true;
94
+ markAdded();
95
+ }
96
+
97
+ const CREATE_SESSION_URL = 'https://tile.googleapis.com/v1/createSession';
98
+ const TILE_URL_BASE = 'https://tile.googleapis.com/v1/2dtiles';
99
+ const ATTRIBUTION_URL = 'https://tile.googleapis.com/tile/v1/viewport';
100
+ const DEFAULT_MAX_ZOOM = 22;
101
+ const SESSION_REFRESH_BUFFER_MS = 60 * 1000;
102
+ const FALLBACK_TILE_SIZE = 256;
103
+ class GoogleMapTilesLayer extends L.GridLayer {
104
+ apiKey;
105
+ highDpi;
106
+ sessionRequest;
107
+ scaleFactor;
108
+ sessionToken;
109
+ sessionPromise;
110
+ sessionRefreshId;
111
+ previousViewport;
112
+ currentAttribution;
113
+ mapInstance;
114
+ onMoveEnd;
115
+ constructor(options) {
116
+ super();
117
+ this.applyInitialGridOptions(options);
118
+ const { apiKey, mapType, language, region, imageFormat, scale, highDpi, layerTypes, overlay, styles, apiOptions, } = options;
119
+ if (!apiKey) {
120
+ throw new Error('Google Map Tiles layer requires an apiKey');
121
+ }
122
+ this.apiKey = apiKey;
123
+ this.highDpi =
124
+ highDpi ?? (scale === undefined ? true : scale !== 'scaleFactor1x');
125
+ this.scaleFactor = this.mapScaleToFactor(scale, this.highDpi);
126
+ const request = {
127
+ mapType: mapType ?? 'roadmap',
128
+ language: language ?? 'en-US',
129
+ region: region ?? 'US',
130
+ };
131
+ if (imageFormat) {
132
+ request.imageFormat = imageFormat;
133
+ }
134
+ if (layerTypes?.length) {
135
+ request.layerTypes = layerTypes;
136
+ }
137
+ if (apiOptions?.length) {
138
+ request.apiOptions = apiOptions;
139
+ }
140
+ if (Array.isArray(styles) && styles.length > 0) {
141
+ request.styles = styles;
142
+ }
143
+ if (overlay === true) {
144
+ request.overlay = true;
145
+ }
146
+ const resolvedScale = scale ?? (this.scaleFactor > 1 ? this.factorToScale(this.scaleFactor) : undefined);
147
+ if (resolvedScale) {
148
+ request.scale = resolvedScale;
149
+ }
150
+ if (this.highDpi) {
151
+ request.highDpi = true;
152
+ }
153
+ this.sessionRequest = request;
154
+ this.onMoveEnd = () => {
155
+ void this.updateAttribution();
156
+ };
157
+ this.sessionPromise = this.startSessionFetch();
158
+ }
159
+ onAdd(map) {
160
+ this.mapInstance = map;
161
+ map.on('moveend', this.onMoveEnd);
162
+ map.on('zoomend', this.onMoveEnd);
163
+ void this.ensureSession().then(() => this.updateAttribution());
164
+ return super.onAdd(map);
165
+ }
166
+ onRemove(map) {
167
+ map.off('moveend', this.onMoveEnd);
168
+ map.off('zoomend', this.onMoveEnd);
169
+ this.clearSessionRefresh();
170
+ this.removeCurrentAttribution();
171
+ this.mapInstance = undefined;
172
+ return super.onRemove(map);
173
+ }
174
+ createTile(coords, done) {
175
+ const tile = document.createElement('img');
176
+ tile.decoding = 'async';
177
+ tile.alt = '';
178
+ tile.crossOrigin = 'anonymous';
179
+ const size = this.resolveTileSize();
180
+ tile.width = size.x;
181
+ tile.height = size.y;
182
+ const handleError = (err) => {
183
+ const message = err instanceof Error ? err.message : 'Google tile load error';
184
+ done(new Error(message), tile);
185
+ };
186
+ tile.onload = () => done(null, tile);
187
+ tile.onerror = (event) => {
188
+ const err = event instanceof ErrorEvent
189
+ ? event.error ?? new Error(event.message)
190
+ : new Error('Google tile failed to load');
191
+ handleError(err);
192
+ };
193
+ void this.ensureSession()
194
+ .then(() => {
195
+ if (!this.sessionToken) {
196
+ handleError(new Error('Google Maps session unavailable'));
197
+ return;
198
+ }
199
+ tile.src = this.buildTileUrl(coords);
200
+ })
201
+ .catch((err) => {
202
+ handleError(err);
203
+ });
204
+ return tile;
205
+ }
206
+ ensureSession() {
207
+ if (this.sessionToken) {
208
+ return Promise.resolve();
209
+ }
210
+ if (!this.sessionPromise) {
211
+ this.sessionPromise = this.startSessionFetch();
212
+ }
213
+ return this.sessionPromise;
214
+ }
215
+ startSessionFetch(force = false) {
216
+ if (this.sessionPromise && !force) {
217
+ return this.sessionPromise;
218
+ }
219
+ const promise = this.fetchAndApplySession()
220
+ .catch((err) => {
221
+ const wrapped = err instanceof Error
222
+ ? err
223
+ : new Error('Failed to create Google Maps session');
224
+ error('Google Map Tiles session error', wrapped);
225
+ this.sessionToken = undefined;
226
+ throw wrapped;
227
+ })
228
+ .finally(() => {
229
+ if (this.sessionPromise === promise) {
230
+ this.sessionPromise = undefined;
231
+ }
232
+ });
233
+ this.sessionPromise = promise;
234
+ return promise;
235
+ }
236
+ async fetchAndApplySession() {
237
+ const url = `${CREATE_SESSION_URL}?key=${this.apiKey}`;
238
+ const response = await fetch(url, {
239
+ method: 'POST',
240
+ headers: {
241
+ 'Content-Type': 'application/json',
242
+ },
243
+ body: JSON.stringify(this.sessionRequest),
244
+ });
245
+ if (!response.ok) {
246
+ let details;
247
+ try {
248
+ const body = await response.json();
249
+ details = body?.error?.message;
250
+ }
251
+ catch {
252
+ // ignore JSON parse errors
253
+ }
254
+ throw new Error(details ?? `Google Maps session request failed (${response.status})`);
255
+ }
256
+ const data = (await response.json());
257
+ this.sessionToken = data.session;
258
+ this.applyTileSize(data);
259
+ this.scheduleSessionRefresh(this.parseExpiry(data.expiry));
260
+ if (this.mapInstance) {
261
+ void this.updateAttribution();
262
+ this.redrawLayer();
263
+ }
264
+ log('Google Map Tiles session established');
265
+ }
266
+ scheduleSessionRefresh(expiryMs) {
267
+ if (!isFinite(expiryMs))
268
+ return;
269
+ const refreshInMs = Math.max(expiryMs - Date.now() - SESSION_REFRESH_BUFFER_MS, 1000);
270
+ this.clearSessionRefresh();
271
+ this.sessionRefreshId = setTimeout(() => {
272
+ void this.startSessionFetch(true).then(() => {
273
+ if (this.mapInstance) {
274
+ void this.updateAttribution();
275
+ this.redrawLayer();
276
+ }
277
+ });
278
+ }, refreshInMs);
279
+ }
280
+ clearSessionRefresh() {
281
+ if (this.sessionRefreshId !== undefined) {
282
+ clearTimeout(this.sessionRefreshId);
283
+ this.sessionRefreshId = undefined;
284
+ }
285
+ }
286
+ async updateAttribution() {
287
+ if (!this.mapInstance || !this.sessionToken)
288
+ return;
289
+ const bounds = this.mapInstance.getBounds();
290
+ if (!bounds?.isValid())
291
+ return;
292
+ const zoom = this.mapInstance.getZoom();
293
+ const viewport = `zoom=${zoom}&north=${bounds.getNorth()}&south=${bounds.getSouth()}&east=${bounds.getEast()}&west=${bounds.getWest()}`;
294
+ if (this.previousViewport === viewport) {
295
+ return;
296
+ }
297
+ this.previousViewport = viewport;
298
+ try {
299
+ const response = await fetch(`${ATTRIBUTION_URL}?session=${this.sessionToken}&key=${this.apiKey}&${viewport}`);
300
+ if (!response.ok) {
301
+ throw new Error(`Attribution request failed (${response.status})`);
302
+ }
303
+ const json = await response.json();
304
+ const copyright = json?.copyright;
305
+ if (typeof copyright === 'string' && copyright.length > 0) {
306
+ this.applyAttribution(copyright);
307
+ }
308
+ }
309
+ catch (err) {
310
+ error('Failed to fetch Google attribution', err);
311
+ }
312
+ }
313
+ applyAttribution(value) {
314
+ const map = this.mapInstance;
315
+ if (!map?.attributionControl)
316
+ return;
317
+ if (this.currentAttribution && this.currentAttribution !== value) {
318
+ map.attributionControl.removeAttribution(this.currentAttribution);
319
+ }
320
+ if (!this.currentAttribution || this.currentAttribution !== value) {
321
+ map.attributionControl.addAttribution(value);
322
+ this.currentAttribution = value;
323
+ }
324
+ }
325
+ removeCurrentAttribution() {
326
+ const map = this.mapInstance;
327
+ if (!map?.attributionControl || !this.currentAttribution)
328
+ return;
329
+ map.attributionControl.removeAttribution(this.currentAttribution);
330
+ this.currentAttribution = undefined;
331
+ }
332
+ applyTileSize(data) {
333
+ const width = Math.max(1, Math.round(data.tileWidth / this.scaleFactor));
334
+ const height = Math.max(1, Math.round(data.tileHeight / this.scaleFactor));
335
+ const tileSize = L.point(width, height);
336
+ this.setGridOptions({ tileSize });
337
+ }
338
+ parseExpiry(expiry) {
339
+ const asInt = parseInt(expiry, 10);
340
+ return Number.isFinite(asInt) ? asInt * 1000 : Number.NaN;
341
+ }
342
+ buildTileUrl(coords) {
343
+ if (!this.sessionToken) {
344
+ throw new Error('Google Maps session missing');
345
+ }
346
+ const z = coords.z;
347
+ const x = coords.x;
348
+ const y = coords.y;
349
+ return `${TILE_URL_BASE}/${z}/${x}/${y}?session=${this.sessionToken}&key=${this.apiKey}`;
350
+ }
351
+ mapScaleToFactor(scale, highDpi) {
352
+ switch (scale) {
353
+ case 'scaleFactor4x':
354
+ return 4;
355
+ case 'scaleFactor2x':
356
+ return 2;
357
+ case 'scaleFactor1x':
358
+ return 1;
359
+ default:
360
+ return highDpi ? 2 : 1;
361
+ }
362
+ }
363
+ factorToScale(factor) {
364
+ switch (factor) {
365
+ case 4:
366
+ return 'scaleFactor4x';
367
+ case 2:
368
+ return 'scaleFactor2x';
369
+ case 1:
370
+ return 'scaleFactor1x';
371
+ default:
372
+ return undefined;
373
+ }
374
+ }
375
+ applyInitialGridOptions(options) {
376
+ const payload = {};
377
+ const keys = [
378
+ 'attribution',
379
+ 'bounds',
380
+ 'className',
381
+ 'detectRetina',
382
+ 'errorTileUrl',
383
+ 'keepBuffer',
384
+ 'maxNativeZoom',
385
+ 'maxZoom',
386
+ 'minNativeZoom',
387
+ 'minZoom',
388
+ 'noWrap',
389
+ 'opacity',
390
+ 'pane',
391
+ 'reuseTiles',
392
+ 'subdomains',
393
+ 'tileSize',
394
+ 'tms',
395
+ 'updateInterval',
396
+ 'updateWhenIdle',
397
+ 'updateWhenZooming',
398
+ 'zIndex',
399
+ 'zoomOffset',
400
+ ];
401
+ for (const key of keys) {
402
+ const value = options[key];
403
+ if (value !== undefined) {
404
+ payload[key] = value;
405
+ }
406
+ }
407
+ if (payload.maxZoom === undefined) {
408
+ payload.maxZoom = DEFAULT_MAX_ZOOM;
409
+ }
410
+ this.setGridOptions(payload);
411
+ }
412
+ setGridOptions(options) {
413
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- L.Util.setOptions is typed as (obj: any, options: any) => any in Leaflet
414
+ const setOptionsFn = L.Util?.setOptions;
415
+ if (typeof setOptionsFn === 'function') {
416
+ setOptionsFn(this, options);
417
+ }
418
+ else {
419
+ const self = this;
420
+ self.options = {
421
+ ...self.options,
422
+ ...options,
423
+ };
424
+ }
425
+ }
426
+ resolveTileSize() {
427
+ const raw = this.options?.tileSize;
428
+ if (raw && typeof raw === 'object') {
429
+ if (Array.isArray(raw) && raw.length === 2) {
430
+ const [x, y] = raw;
431
+ return L.point(Number(x) || FALLBACK_TILE_SIZE, Number(y) || FALLBACK_TILE_SIZE);
432
+ }
433
+ if ('x' in raw && 'y' in raw) {
434
+ const point = raw;
435
+ return L.point(Number(point.x) || FALLBACK_TILE_SIZE, Number(point.y) || FALLBACK_TILE_SIZE);
436
+ }
437
+ }
438
+ if (typeof raw === 'number' && Number.isFinite(raw)) {
439
+ return L.point(raw, raw);
440
+ }
441
+ return L.point(FALLBACK_TILE_SIZE, FALLBACK_TILE_SIZE);
442
+ }
443
+ redrawLayer() {
444
+ this.redraw();
445
+ }
446
+ }
447
+
448
+ class GeoTIFFGridLayer extends L.GridLayer {
449
+ geotiffOptions;
450
+ tileProcessor = null;
451
+ colorStops;
452
+ loadingPromise;
453
+ defaultResolution = 1;
454
+ defaultResample = 'bilinear';
455
+ constructor(options) {
456
+ super(options);
457
+ this.geotiffOptions = { ...options };
458
+ }
459
+ onAdd(map) {
460
+ super.onAdd(map);
461
+ void this.ensureReady().then(() => this.redraw());
462
+ return this;
463
+ }
464
+ createTile(coords, done) {
465
+ const size = this.getTileSize();
466
+ const canvas = L.DomUtil.create('canvas', 'leaflet-tile');
467
+ canvas.width = size.x;
468
+ canvas.height = size.y;
469
+ this.ensureReady()
470
+ .then(async () => {
471
+ if (!this.tileProcessor) {
472
+ done(null, canvas);
473
+ return;
474
+ }
475
+ try {
476
+ const rgba = await this.tileProcessor.getTileData({
477
+ x: coords.x,
478
+ y: coords.y,
479
+ z: coords.z,
480
+ tileSize: size.x,
481
+ resolution: this.geotiffOptions.resolution ?? this.defaultResolution,
482
+ resampleMethod: this.geotiffOptions.resampleMethod ?? this.defaultResample,
483
+ colorStops: this.colorStops,
484
+ });
485
+ if (!rgba) {
486
+ done(null, canvas);
487
+ return;
488
+ }
489
+ const ctx = canvas.getContext('2d');
490
+ if (ctx) {
491
+ const imageData = ctx.createImageData(size.x, size.y);
492
+ imageData.data.set(rgba);
493
+ ctx.putImageData(imageData, 0, 0);
494
+ }
495
+ done(null, canvas);
496
+ }
497
+ catch (err) {
498
+ done(err, canvas);
499
+ }
500
+ })
501
+ .catch(err => {
502
+ done(err, canvas);
503
+ });
504
+ return canvas;
505
+ }
506
+ async ensureReady() {
507
+ if (!this.loadingPromise) {
508
+ this.loadingPromise = this.initializeProcessor();
509
+ }
510
+ return this.loadingPromise;
511
+ }
512
+ async updateSource(options) {
513
+ Object.assign(this.geotiffOptions, options);
514
+ this.tileProcessor = null;
515
+ this.colorStops = undefined;
516
+ this.loadingPromise = undefined;
517
+ await this.ensureReady();
518
+ this.redraw();
519
+ }
520
+ async initializeProcessor() {
521
+ if (this.tileProcessor)
522
+ return;
523
+ const [geotiffModule, { default: proj4 }, geokeysModule] = await Promise.all([
524
+ import('./geotiff-BEWxTIfH.js').then(function (n) { return n.g; }),
525
+ import('./index-RpJarvr_.js'),
526
+ import('./main-dist-CwnA7_Xn.js').then(function (n) { return n.m; }),
527
+ ]);
528
+ const source = await loadGeoTIFFSource(this.geotiffOptions.url, {
529
+ projection: undefined,
530
+ forceProjection: false,
531
+ nodata: this.geotiffOptions.nodata,
532
+ }, {
533
+ geotiff: geotiffModule,
534
+ proj4,
535
+ geokeysToProj4: geokeysModule,
536
+ });
537
+ const transformViewToSourceMapFn = (coord) => {
538
+ const result = source.proj4(this.geotiffOptions.viewProjection, //source.toProjection,
539
+ source.fromProjection, coord);
540
+ return [Number(result[0]), Number(result[1])];
541
+ };
542
+ const transformSourceMapToViewFn = (coord) => {
543
+ const result = source.proj4(source.fromProjection, this.geotiffOptions.viewProjection, //source.toProjection,
544
+ coord);
545
+ return [Number(result[0]), Number(result[1])];
546
+ };
547
+ this.tileProcessor = new GeoTIFFTileProcessor({
548
+ transformViewToSourceMapFn,
549
+ transformSourceMapToViewFn,
550
+ sourceBounds: source.sourceBounds,
551
+ sourceRef: source.sourceRef,
552
+ resolution: source.resolution,
553
+ imageWidth: source.width,
554
+ imageHeight: source.height,
555
+ fromProjection: source.fromProjection,
556
+ toProjection: this.geotiffOptions.viewProjection, //source.toProjection,
557
+ baseImage: source.baseImage,
558
+ overviewImages: source.overviewImages ?? [],
559
+ });
560
+ this.tileProcessor.createGlobalTriangulation();
561
+ // Set bounds to restrict tile loading to GeoTIFF coverage area
562
+ this.setViewBounds(source.sourceBounds, transformSourceMapToViewFn);
563
+ if (this.geotiffOptions.colorMap) {
564
+ const { stops } = getColorStops(this.geotiffOptions.colorMap, this.geotiffOptions.valueRange);
565
+ this.colorStops = stops;
566
+ }
567
+ }
568
+ /**
569
+ * Set Leaflet bounds from GeoTIFF source bounds
570
+ * Restricts tile loading to the GeoTIFF coverage area
571
+ */
572
+ setViewBounds(sourceBounds, transformSourceToView) {
573
+ const [srcWest, srcSouth, srcEast, srcNorth] = sourceBounds;
574
+ // Transform corners from Source to View (Web Mercator for Leaflet)
575
+ const sw = transformSourceToView([srcWest, srcSouth]);
576
+ const se = transformSourceToView([srcEast, srcSouth]);
577
+ const nw = transformSourceToView([srcWest, srcNorth]);
578
+ const ne = transformSourceToView([srcEast, srcNorth]);
579
+ // Calculate bounds in View coordinates
580
+ const minX = Math.min(sw[0], se[0], nw[0], ne[0]);
581
+ const maxX = Math.max(sw[0], se[0], nw[0], ne[0]);
582
+ const minY = Math.min(sw[1], se[1], nw[1], ne[1]);
583
+ const maxY = Math.max(sw[1], se[1], nw[1], ne[1]);
584
+ // Convert to Leaflet LatLngBounds (Web Mercator meters to lat/lng)
585
+ const southWest = L.CRS.EPSG3857.unproject(L.point(minX, maxY));
586
+ const northEast = L.CRS.EPSG3857.unproject(L.point(maxX, minY));
587
+ // Set bounds option - Leaflet will use this to restrict tile loading
588
+ this.options.bounds = L.latLngBounds(southWest, northEast);
589
+ }
590
+ }
591
+
592
+ const LOG_PREFIX = 'v-map - leaflet - wcs - tile - ';
593
+ /**
594
+ * Custom Leaflet GridLayer for WCS (Web Coverage Service) support
595
+ *
596
+ * Supports:
597
+ * - WCS 2.0.1 with subset parameters
598
+ * - WCS 1.x.x with BBOX parameters (backward compatibility)
599
+ * - GeoTIFF FLOAT32 format
600
+ * - Dynamic BBOX-based requests
601
+ */
602
+ class WCSGridLayer extends L.GridLayer {
603
+ wcsOptions;
604
+ constructor(options) {
605
+ super(options);
606
+ this.wcsOptions = {
607
+ ...options,
608
+ version: options.version ?? '2.0.1',
609
+ format: options.format ?? 'image/tiff',
610
+ projection: options.projection ?? 'EPSG:4326',
611
+ };
612
+ }
613
+ /**
614
+ * Build WCS GetCoverage URL for a given tile
615
+ */
616
+ buildWCSUrl(coords) {
617
+ const { url, coverageName, version, format, projection, params } = this.wcsOptions;
618
+ // Calculate tile bounds in lat/lng
619
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Leaflet private method not exposed in type definitions
620
+ const tileBounds = this._tileCoordsToBounds(coords);
621
+ const southwest = tileBounds.getSouthWest();
622
+ const northeast = tileBounds.getNorthEast();
623
+ const minx = southwest.lng;
624
+ const miny = southwest.lat;
625
+ const maxx = northeast.lng;
626
+ const maxy = northeast.lat;
627
+ const baseParams = {
628
+ SERVICE: 'WCS',
629
+ REQUEST: 'GetCoverage',
630
+ VERSION: version,
631
+ FORMAT: format,
632
+ };
633
+ // WCS 2.0.1 uses subset parameters
634
+ if (version.startsWith('2.0')) {
635
+ baseParams.coverageId = coverageName;
636
+ // Build URL with subset parameters
637
+ // Note: We can't use the same param name twice in URLSearchParams,
638
+ // so we'll manually construct the query string
639
+ const extraParams = params ? { ...params } : {};
640
+ const allParams = { ...baseParams, ...extraParams };
641
+ // Add GeoTIFF compression if format is tiff
642
+ if (format.includes('tiff') || format.includes('geotiff')) {
643
+ allParams['geotiff:compression'] = 'LZW';
644
+ }
645
+ const query = new URLSearchParams();
646
+ Object.entries(allParams).forEach(([key, value]) => {
647
+ if (value !== undefined && value !== null) {
648
+ query.set(key, String(value));
649
+ }
650
+ });
651
+ // Manually add subset parameters (can't use URLSearchParams for duplicate keys)
652
+ const queryString = query.toString();
653
+ const subsetX = `subset=X(${minx},${maxx})`;
654
+ const subsetY = `subset=Y(${miny},${maxy})`;
655
+ return `${url}${url.includes('?') ? '&' : '?'}${queryString}&${subsetX}&${subsetY}`;
656
+ }
657
+ // WCS 1.x.x uses BBOX parameter
658
+ else {
659
+ baseParams.COVERAGE = coverageName;
660
+ baseParams.BBOX = `${minx},${miny},${maxx},${maxy}`;
661
+ baseParams.CRS = projection;
662
+ // Calculate width and height for the tile
663
+ const tileSize = this.getTileSize();
664
+ baseParams.WIDTH = typeof tileSize === 'number' ? tileSize : tileSize.x;
665
+ baseParams.HEIGHT = typeof tileSize === 'number' ? tileSize : tileSize.y;
666
+ const extraParams = params ? { ...params } : {};
667
+ const allParams = { ...baseParams, ...extraParams };
668
+ const query = new URLSearchParams();
669
+ Object.entries(allParams).forEach(([key, value]) => {
670
+ if (value !== undefined && value !== null) {
671
+ query.set(key, String(value));
672
+ }
673
+ });
674
+ return `${url}${url.includes('?') ? '&' : '?'}${query.toString()}`;
675
+ }
676
+ }
677
+ /**
678
+ * Create tile element (required by GridLayer)
679
+ */
680
+ createTile(coords, done) {
681
+ const tile = document.createElement('img');
682
+ const wcsUrl = this.buildWCSUrl(coords);
683
+ log(`${LOG_PREFIX}load: coords=(${coords.x},${coords.y},${coords.z})`);
684
+ log(`${LOG_PREFIX}url: ${wcsUrl}`);
685
+ tile.onload = () => {
686
+ done(null, tile);
687
+ };
688
+ tile.onerror = (err) => {
689
+ error(`${LOG_PREFIX}failed to load tile:`, err);
690
+ done(err instanceof Error ? err : new Error(String(err)), tile);
691
+ };
692
+ // Set crossOrigin for CORS support
693
+ tile.crossOrigin = 'anonymous';
694
+ tile.src = wcsUrl;
695
+ return tile;
696
+ }
697
+ /**
698
+ * Update WCS options and redraw
699
+ */
700
+ updateOptions(newOptions) {
701
+ this.wcsOptions = {
702
+ ...this.wcsOptions,
703
+ ...newOptions,
704
+ };
705
+ this.redraw();
706
+ }
707
+ }
708
+
709
+ class LeafletProvider {
710
+ map;
711
+ layers = [];
712
+ baseLayers = [];
713
+ hiddenLayerGroups = [];
714
+ googleLogoAdded = false;
715
+ unsubscribeResize;
716
+ shadowRoot;
717
+ injectedStyle;
718
+ layerErrorCallbacks = new Map();
719
+ layerErrorCleanups = new Map();
720
+ async init(options) {
721
+ if (!isBrowser())
722
+ return;
723
+ this.shadowRoot = options.shadowRoot;
724
+ this.injectedStyle = ensureLeafletCss(options.cssMode, this.shadowRoot);
725
+ const [lon, lat] = (options?.mapInitOptions?.center ?? [0, 0]);
726
+ this.map = L.map(options.target, {
727
+ zoomControl: true,
728
+ attributionControl: true,
729
+ }).setView([lat, lon], options?.mapInitOptions?.zoom ?? 2);
730
+ this.unsubscribeResize = watchElementResize(options.target, () => {
731
+ this.map?.invalidateSize();
732
+ }, {
733
+ attributes: true,
734
+ attributeFilter: ['style', 'class'],
735
+ });
736
+ }
737
+ async updateLayer(layerId, update) {
738
+ const layer = await this._getLayerById(layerId);
739
+ switch (update.type) {
740
+ case 'geojson':
741
+ await this.updateGeoJSONLayer(layer, update.data);
742
+ break;
743
+ case 'osm':
744
+ await this.updateOSMLayer(layer, update.data);
745
+ break;
746
+ case 'arcgis':
747
+ await this.updateArcGISLayer(layer, update.data);
748
+ break;
749
+ case 'wkt':
750
+ await this.updateWKTLayer(layer, update.data);
751
+ break;
752
+ case 'geotiff':
753
+ await this.updateGeoTIFFLayer(layer, update.data);
754
+ break;
755
+ case 'wcs':
756
+ await this.updateWCSLayer(layer, update.data);
757
+ break;
758
+ case 'wfs':
759
+ if (layer instanceof L.GeoJSON) {
760
+ await this.updateWFSLayer(layer, update.data);
761
+ }
762
+ break;
763
+ }
764
+ }
765
+ // private async addStandaloneLayer(layerConfig: LayerConfig): Promise<L.Layer> {
766
+ // const layer = await this.createLayer(layerConfig);
767
+ // layer.addTo(this.map!);
768
+ // this.layers.push(layer);
769
+ // }
770
+ async addLayerToGroup(layerConfig) {
771
+ const group = await this._ensureGroup(layerConfig.groupId, layerConfig.groupVisible);
772
+ const layer = await this.createLayer(layerConfig);
773
+ if (layer == null) {
774
+ return null;
775
+ }
776
+ group.addLayer(layer);
777
+ const layerId = this.getLayerId(layer);
778
+ layer.vmapVisible = true;
779
+ layer.vmapOpacity = 1.0;
780
+ if (layerConfig.opacity !== undefined) {
781
+ this.setOpacityByLayer(layer, layerConfig.opacity);
782
+ }
783
+ if (layerConfig.zIndex !== undefined) {
784
+ layer.setZIndex?.(layerConfig.zIndex);
785
+ }
786
+ if (layerConfig.visible) {
787
+ this.setVisibleByLayer(layer, true);
788
+ }
789
+ else if (layerConfig.visible === false) {
790
+ this.setVisibleByLayer(layer, false);
791
+ }
792
+ return layerId;
793
+ }
794
+ // async addLayer(config: LayerConfig): Promise<string> {
795
+ // if (!this.map) return;
796
+ // let layer: L.Layer = null;
797
+ // if ('groupId' in config && config.groupId) {
798
+ // try {
799
+ // layer = await this.addLayerToGroup(
800
+ // config as LayerConfig & { groupId: string },
801
+ // );
802
+ // } catch (ex) {
803
+ // error('addLayer - Unerwarteter Fehler:', ex);
804
+ // return null;
805
+ // }
806
+ // } else {
807
+ // try {
808
+ // layer = await this.addStandaloneLayer(config);
809
+ // } catch (ex) {
810
+ // error('addLayer - Unerwarteter Fehler:', ex);
811
+ // return null;
812
+ // }
813
+ // }
814
+ // if (layer == null) {
815
+ // return null;
816
+ // }
817
+ // const layerId = L.Util.stamp(layer); //layer._leaflet_id;
818
+ // layer.vmapVisible = true;
819
+ // layer.vmapOpacity = 1.0;
820
+ // if (config.opacity !== undefined) {
821
+ // this.setOpacityByLayer(layer, config.opacity);
822
+ // }
823
+ // if (config.zIndex !== undefined) {
824
+ // layer.setZIndex(config.zIndex);
825
+ // }
826
+ // if (config.visible) {
827
+ // this.setVisibleByLayer(layer, true);
828
+ // } else if (config.visible === false) {
829
+ // this.setVisibleByLayer(layer, false);
830
+ // }
831
+ // return layerId;
832
+ // }
833
+ async addBaseLayer(layerConfig, basemapid, layerElementId) {
834
+ if (layerElementId === undefined || layerElementId === null) {
835
+ log('leaflet - addBaseLayer - layerElementId not set.');
836
+ return null;
837
+ }
838
+ if (basemapid === undefined || basemapid === null) {
839
+ log('leaflet - addBaseLayer - basemapid not set.');
840
+ }
841
+ const group = await this._ensureGroup(layerConfig.groupId, layerConfig.groupVisible);
842
+ group.basemap = true;
843
+ const layer = await this.createLayer(layerConfig);
844
+ // layer.group = group;
845
+ this.baseLayers.push(layer);
846
+ if (layer == null) {
847
+ return null;
848
+ }
849
+ layer.layerElementId = layerElementId;
850
+ const layerId = this.getLayerId(layer);
851
+ layer.vmapVisible = true;
852
+ layer.vmapOpacity = 1.0;
853
+ if (layerConfig.opacity !== undefined) {
854
+ this.setOpacityByLayer(layer, layerConfig.opacity);
855
+ }
856
+ if (layerConfig.zIndex !== undefined) {
857
+ layer.setZIndex?.(layerConfig.zIndex);
858
+ }
859
+ if (layerConfig.visible) {
860
+ this.setVisibleByLayer(layer, true);
861
+ }
862
+ else if (layerConfig.visible === false) {
863
+ this.setVisibleByLayer(layer, false);
864
+ }
865
+ if (basemapid === layerElementId) {
866
+ const prev_layer = group.getLayers()[0];
867
+ if (prev_layer) {
868
+ this.map.removeLayer(prev_layer);
869
+ group.clearLayers();
870
+ }
871
+ group.addLayer(layer);
872
+ if (group.visible) {
873
+ layer.addTo(this.map);
874
+ }
875
+ //group.layerId = layerId;
876
+ }
877
+ return layerId;
878
+ }
879
+ async setBaseLayer(groupId, layerElementId) {
880
+ if (layerElementId === null) {
881
+ log('leaflet - setBaseLayer - layerElementId is null.');
882
+ return;
883
+ }
884
+ const group = this.layers.find(l => l._groupId === groupId);
885
+ const layer = this.baseLayers.find(l => l.layerElementId === layerElementId);
886
+ if (layer === undefined) {
887
+ log('leaflet - setBaseLayer - layer not found. layerElementId: ' +
888
+ layerElementId);
889
+ return;
890
+ }
891
+ if (!group) {
892
+ return;
893
+ }
894
+ const prev_layer = group.getLayers()[0];
895
+ if (prev_layer) {
896
+ this.map.removeLayer(prev_layer);
897
+ group.clearLayers();
898
+ }
899
+ group.addLayer(layer);
900
+ ////layer.addTo(this.map!);
901
+ //group.layerId = layerId;
902
+ //group.set('layerId', layerId, false);
903
+ }
904
+ getLayerId(layer) {
905
+ return String(L.Util.stamp(layer));
906
+ }
907
+ normalizeAttribution(attribution) {
908
+ if (Array.isArray(attribution)) {
909
+ return attribution.join(', ');
910
+ }
911
+ return attribution;
912
+ }
913
+ async _getLayerById(layerId) {
914
+ let layerFound = null;
915
+ this.map?.eachLayer(layer => {
916
+ if (this.getLayerId(layer) === layerId) {
917
+ layerFound = layer;
918
+ }
919
+ });
920
+ if (layerFound)
921
+ return layerFound;
922
+ layerFound =
923
+ this.baseLayers.find(l => this.getLayerId(l) === layerId) ?? null;
924
+ if (layerFound === undefined)
925
+ return null;
926
+ return layerFound;
927
+ }
928
+ async createLayer(layerConfig) {
929
+ switch (layerConfig.type) {
930
+ case 'geojson':
931
+ return this.createGeoJSONLayer(layerConfig);
932
+ case 'xyz':
933
+ return this.createXYZLayer(layerConfig);
934
+ case 'osm':
935
+ return this.createOSMLayer(layerConfig);
936
+ case 'wms':
937
+ return this.createWMSLayer(layerConfig);
938
+ case 'wcs':
939
+ return this.createWCSLayer(layerConfig);
940
+ case 'wfs':
941
+ return this.createWFSLayer(layerConfig);
942
+ case 'arcgis':
943
+ return this.createArcGISLayer(layerConfig);
944
+ case 'google':
945
+ return this.createGoogleLayer(layerConfig);
946
+ case 'wkt':
947
+ return this.createWKTLayer(layerConfig);
948
+ case 'geotiff':
949
+ return this.createGeoTIFFLayer(layerConfig);
950
+ default:
951
+ throw new Error(`Unsupported layer type: ${layerConfig.type}`);
952
+ }
953
+ }
954
+ async updateGeoJSONLayer(layer, data) {
955
+ if (!(layer instanceof L.GeoJSON))
956
+ return;
957
+ let geoJsonData = null;
958
+ if (data.geojson) {
959
+ geoJsonData = JSON.parse(data.geojson);
960
+ }
961
+ else if (data.url) {
962
+ const res = await fetch(data.url);
963
+ if (!res.ok)
964
+ throw new Error(`GeoJSON fetch failed: ${res.status} ${res.statusText}`);
965
+ geoJsonData = await res.json();
966
+ }
967
+ layer.clearLayers();
968
+ layer.addData(geoJsonData);
969
+ }
970
+ async createGeoJSONLayer(config) {
971
+ let data = null;
972
+ if (config.geojson) {
973
+ data = JSON.parse(config.geojson);
974
+ }
975
+ else if (config.url) {
976
+ const res = await fetch(config.url);
977
+ if (!res.ok)
978
+ throw new Error(`GeoJSON fetch failed: ${res.status} ${res.statusText}`);
979
+ data = await res.json();
980
+ }
981
+ if (data) {
982
+ // Use geostyler style if available, otherwise use provided style or default style
983
+ let layerOptions = {};
984
+ if (config.geostylerStyle) {
985
+ layerOptions = await this.createGeostylerLeafletOptions(config.geostylerStyle);
986
+ }
987
+ else {
988
+ const style = config.style
989
+ ? { ...DEFAULT_STYLE, ...config.style }
990
+ : DEFAULT_STYLE;
991
+ layerOptions = {
992
+ style: this.createLeafletStyle(style),
993
+ pointToLayer: (feature, latlng) => this.createLeafletPoint(feature, latlng, style),
994
+ onEachFeature: (feature, layer) => this.bindLeafletPopup(feature, layer, style),
995
+ };
996
+ }
997
+ const layer = L.geoJSON(data, layerOptions);
998
+ return layer;
999
+ }
1000
+ return null;
1001
+ }
1002
+ async createXYZLayer(config) {
1003
+ const layer = L.tileLayer(config.url, {
1004
+ attribution: this.normalizeAttribution(config.attributions),
1005
+ maxZoom: config.maxZoom ?? 19,
1006
+ ...(config.options ?? {}),
1007
+ });
1008
+ return layer;
1009
+ }
1010
+ async updateOSMLayer(layer, data) {
1011
+ if (!('setUrl' in layer) || typeof layer.setUrl !== 'function')
1012
+ return;
1013
+ let url = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png';
1014
+ if (data.url) {
1015
+ url = data.url + '/{z}/{x}/{y}.png';
1016
+ }
1017
+ layer.setUrl(url);
1018
+ }
1019
+ async createOSMLayer(cfg) {
1020
+ let url = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png';
1021
+ if (cfg.url) {
1022
+ url = cfg.url + '/{z}/{x}/{y}.png';
1023
+ }
1024
+ return L.tileLayer(url, {
1025
+ attribution: '© OpenStreetMap contributors',
1026
+ maxZoom: 19,
1027
+ });
1028
+ }
1029
+ async createWMSLayer(config) {
1030
+ return L.tileLayer.wms(config.url, {
1031
+ layers: config.layers,
1032
+ format: config.format ?? 'image/png',
1033
+ transparent: config.transparent ?? true,
1034
+ ...(config.extraParams ?? {}),
1035
+ });
1036
+ }
1037
+ buildArcGISUrl(url, params) {
1038
+ if (!params || Object.keys(params).length === 0)
1039
+ return url;
1040
+ const query = new URLSearchParams();
1041
+ Object.entries(params).forEach(([key, value]) => {
1042
+ if (value !== undefined && value !== null) {
1043
+ query.set(key, String(value));
1044
+ }
1045
+ });
1046
+ if (query.toString().length === 0)
1047
+ return url;
1048
+ return `${url}${url.includes('?') ? '&' : '?'}${query.toString()}`;
1049
+ }
1050
+ async createArcGISLayer(config) {
1051
+ const params = {
1052
+ ...(config.params ?? {}),
1053
+ };
1054
+ if (config.token) {
1055
+ params.token = config.token;
1056
+ }
1057
+ const arcgisUrl = this.buildArcGISUrl(config.url, params);
1058
+ const options = {
1059
+ attribution: this.normalizeAttribution(config.attributions),
1060
+ minZoom: config.minZoom,
1061
+ maxZoom: config.maxZoom,
1062
+ ...(config.options ?? {}),
1063
+ };
1064
+ return L.tileLayer(arcgisUrl, options);
1065
+ }
1066
+ async updateArcGISLayer(layer, data) {
1067
+ const params = {
1068
+ ...(data?.params ?? {}),
1069
+ };
1070
+ if (data?.token) {
1071
+ params.token = data.token;
1072
+ }
1073
+ const tileLayer = layer;
1074
+ const targetUrl = data?.url ?? tileLayer.options?.url ?? '';
1075
+ const nextUrl = this.buildArcGISUrl(targetUrl, params);
1076
+ if ('setUrl' in tileLayer && typeof tileLayer.setUrl === 'function') {
1077
+ tileLayer.setUrl(nextUrl);
1078
+ }
1079
+ }
1080
+ async createGoogleLayer(config) {
1081
+ if (!this.map)
1082
+ throw new Error('Map not initialized');
1083
+ if (!config.apiKey)
1084
+ throw new Error("Google-Layer benötigt 'apiKey' (Google Maps Platform).");
1085
+ const parsedStyles = typeof config.styles === 'string'
1086
+ ? this.tryParseStyles(config.styles)
1087
+ : config.styles;
1088
+ const googleLayer = new GoogleMapTilesLayer({
1089
+ apiKey: config.apiKey,
1090
+ mapType: config.mapType ?? 'roadmap',
1091
+ language: config.language,
1092
+ region: config.region,
1093
+ scale: config.scale,
1094
+ highDpi: config.highDpi,
1095
+ layerTypes: config.layerTypes,
1096
+ overlay: config.overlay,
1097
+ styles: Array.isArray(parsedStyles) ? parsedStyles : undefined,
1098
+ imageFormat: config.imageFormat,
1099
+ apiOptions: config.apiOptions,
1100
+ maxZoom: config.maxZoom ?? 22,
1101
+ });
1102
+ ensureGoogleLogo(this.map, () => {
1103
+ this.googleLogoAdded = true;
1104
+ log('v-map - provider - leaflet - googleLogoAdded: ', this.googleLogoAdded);
1105
+ });
1106
+ return googleLayer;
1107
+ }
1108
+ tryParseStyles(value) {
1109
+ try {
1110
+ const parsed = JSON.parse(value);
1111
+ return Array.isArray(parsed) ? parsed : undefined;
1112
+ }
1113
+ catch {
1114
+ error('Failed to parse Google styles JSON');
1115
+ return undefined;
1116
+ }
1117
+ }
1118
+ async destroy() {
1119
+ this.unsubscribeResize?.();
1120
+ removeInjectedCss(this.shadowRoot, this.injectedStyle);
1121
+ for (const l of this.layers) {
1122
+ this.map?.removeLayer(l);
1123
+ }
1124
+ this.layers = [];
1125
+ this.map?.remove();
1126
+ this.map = undefined;
1127
+ }
1128
+ async setView([lon, lat], zoom) {
1129
+ this.map?.setView([lat, lon], zoom, { animate: false });
1130
+ }
1131
+ onLayerError(layerId, callback) {
1132
+ this.layerErrorCallbacks.set(layerId, callback);
1133
+ this._getLayerById(layerId).then(layer => {
1134
+ if (!layer)
1135
+ return;
1136
+ const handler = () => { callback({ type: 'network', message: 'Tile load error' }); };
1137
+ layer.on('tileerror', handler);
1138
+ this.layerErrorCleanups.set(layerId, () => layer.off('tileerror', handler));
1139
+ });
1140
+ }
1141
+ offLayerError(layerId) {
1142
+ this.layerErrorCleanups.get(layerId)?.();
1143
+ this.layerErrorCleanups.delete(layerId);
1144
+ this.layerErrorCallbacks.delete(layerId);
1145
+ }
1146
+ async removeLayer(layerId) {
1147
+ if (!layerId) {
1148
+ return;
1149
+ }
1150
+ this.offLayerError(layerId);
1151
+ const layer = await this._getLayerById(layerId);
1152
+ if (layer) {
1153
+ this.map.removeLayer(layer);
1154
+ }
1155
+ }
1156
+ async setZIndex(layerId, zIndex) {
1157
+ if (!layerId) {
1158
+ return;
1159
+ }
1160
+ const layer = await this._getLayerById(layerId);
1161
+ if (layer) {
1162
+ if (typeof layer.setZIndex === 'function') {
1163
+ layer.setZIndex(zIndex);
1164
+ } //todo
1165
+ }
1166
+ }
1167
+ async setOpacity(layerId, opacity) {
1168
+ if (!layerId)
1169
+ return;
1170
+ const layer = await this._getLayerById(layerId);
1171
+ this.setOpacityByLayer(layer, opacity);
1172
+ }
1173
+ setOpacityByLayer(layer, opacity) {
1174
+ if (!layer)
1175
+ return;
1176
+ // 1. Speichere die Ziel-Opazität (auch wenn Layer unsichtbar)
1177
+ layer.vmapOpacity = opacity;
1178
+ if (layer.vmapVisible === undefined) {
1179
+ layer.vmapVisible = true;
1180
+ }
1181
+ // 2. Wende sie nur an, wenn der Layer sichtbar IST ODER GEMACHT WIRD
1182
+ // (vermeidet unnötige setOpacity-Aufrufe, wenn vmapVisible=false)
1183
+ if (layer.vmapVisible !== false) {
1184
+ this.setLayerOpacity(layer, opacity);
1185
+ }
1186
+ }
1187
+ async setVisible(layerId, visible) {
1188
+ if (!layerId)
1189
+ return;
1190
+ const layer = await this._getLayerById(layerId);
1191
+ this.setVisibleByLayer(layer, visible);
1192
+ }
1193
+ setVisibleByLayer(layer, visible) {
1194
+ if (!layer)
1195
+ return;
1196
+ // 1. Aktualisiere den Sichtbarkeitszustand
1197
+ layer.vmapVisible = visible;
1198
+ if (layer.vmapOpacity === undefined) {
1199
+ layer.vmapOpacity = 1.0;
1200
+ }
1201
+ // 2. Setze die Opazität basierend auf dem neuen Zustand:
1202
+ const targetOpacity = visible ? layer.vmapOpacity : 0.0;
1203
+ this.setLayerOpacity(layer, targetOpacity);
1204
+ }
1205
+ setLayerOpacity(layer, options) {
1206
+ if (!layer)
1207
+ return;
1208
+ const opacity = typeof options === 'number' ? options : options.opacity ?? 1;
1209
+ const fillOpacity = typeof options === 'number' ? options : options.fillOpacity ?? opacity;
1210
+ const hasLeafletClass = (candidate, className) => {
1211
+ if (!(className in L))
1212
+ return false;
1213
+ const ctor = L[className];
1214
+ return (typeof ctor === 'function' &&
1215
+ candidate instanceof ctor);
1216
+ };
1217
+ const isLayerCollection = (candidate) => hasLeafletClass(candidate, 'GeoJSON') ||
1218
+ hasLeafletClass(candidate, 'LayerGroup');
1219
+ const isPathLayer = (candidate) => hasLeafletClass(candidate, 'Path');
1220
+ const isMarkerLayer = (candidate) => hasLeafletClass(candidate, 'Marker');
1221
+ if (isLayerCollection(layer)) {
1222
+ layer.eachLayer(subLayer => this.setLayerOpacity(subLayer, options));
1223
+ }
1224
+ else if (isPathLayer(layer)) {
1225
+ layer.setStyle({ opacity, fillOpacity });
1226
+ }
1227
+ else if (isMarkerLayer(layer)) {
1228
+ layer.setOpacity(opacity);
1229
+ }
1230
+ else if ('setOpacity' in layer) {
1231
+ layer.setOpacity(opacity);
1232
+ }
1233
+ }
1234
+ async ensureGroup(groupId, visible, _opts) {
1235
+ await this._ensureGroup(groupId, visible);
1236
+ }
1237
+ async _ensureGroup(groupId, visible) {
1238
+ let group = await this._getLayerGroupById(groupId);
1239
+ if (!group) {
1240
+ group = L.layerGroup();
1241
+ group._groupId = groupId;
1242
+ group.visible = true;
1243
+ group.addTo(this.map);
1244
+ this.layers.push(group);
1245
+ }
1246
+ this.setGroupVisible(groupId, visible !== undefined ? visible : true);
1247
+ return group;
1248
+ }
1249
+ async _getLayerGroupById(groupId) {
1250
+ if (!this.map) {
1251
+ return null;
1252
+ }
1253
+ let group = this.layers.find(l => l instanceof L.LayerGroup && l._groupId === groupId);
1254
+ if (!group) {
1255
+ group = this.hiddenLayerGroups.find(lg => lg._groupId === groupId);
1256
+ if (!group)
1257
+ return null;
1258
+ }
1259
+ return group;
1260
+ }
1261
+ async setGroupVisible(groupId, visible) {
1262
+ const layerGroup = await this._getLayerGroupById(groupId);
1263
+ if (layerGroup) {
1264
+ if (layerGroup.visible === visible)
1265
+ return;
1266
+ if (layerGroup.visible === false) {
1267
+ layerGroup.addTo(this.map);
1268
+ // remove layergroup from hidden list
1269
+ this.hiddenLayerGroups = this.hiddenLayerGroups.filter(lg => lg._groupId !== groupId);
1270
+ layerGroup.visible = visible;
1271
+ }
1272
+ else if (layerGroup.visible === true) {
1273
+ this.map.removeLayer(layerGroup);
1274
+ // add layergroup to hidden list
1275
+ layerGroup.visible = visible;
1276
+ this.hiddenLayerGroups.push(layerGroup);
1277
+ }
1278
+ }
1279
+ }
1280
+ async updateWKTLayer(layer, data) {
1281
+ if (!(layer instanceof L.GeoJSON))
1282
+ return;
1283
+ let geoJsonData = null;
1284
+ if (data.wkt) {
1285
+ geoJsonData = await this.wktToGeoJSON(data.wkt);
1286
+ }
1287
+ else if (data.url) {
1288
+ try {
1289
+ const response = await fetch(data.url);
1290
+ if (!response.ok)
1291
+ throw new Error(`Failed to fetch WKT: ${response.status}`);
1292
+ const wktText = await response.text();
1293
+ geoJsonData = await this.wktToGeoJSON(wktText);
1294
+ }
1295
+ catch (e) {
1296
+ error('Failed to load WKT from URL:', e);
1297
+ return;
1298
+ }
1299
+ }
1300
+ if (geoJsonData) {
1301
+ layer.clearLayers();
1302
+ // Update layer options to use enhanced styling
1303
+ const geoJsonLayer = layer;
1304
+ geoJsonLayer.options.style = this.createLeafletStyle(data.style);
1305
+ geoJsonLayer.options.pointToLayer = (feature, latlng) => this.createLeafletPoint(feature, latlng, data.style);
1306
+ geoJsonLayer.options.onEachFeature = (feature, layer) => this.bindLeafletPopup(feature, layer, data.style);
1307
+ geoJsonLayer.addData(geoJsonData);
1308
+ }
1309
+ }
1310
+ async createWKTLayer(config) {
1311
+ let geoJsonData = null;
1312
+ const emptyCollection = { type: 'FeatureCollection', features: [] };
1313
+ if (config.wkt) {
1314
+ geoJsonData = await this.wktToGeoJSON(config.wkt);
1315
+ }
1316
+ else if (config.url) {
1317
+ try {
1318
+ const response = await fetch(config.url);
1319
+ if (!response.ok)
1320
+ throw new Error(`Failed to fetch WKT: ${response.status}`);
1321
+ const wktText = await response.text();
1322
+ geoJsonData = await this.wktToGeoJSON(wktText);
1323
+ }
1324
+ catch (e) {
1325
+ error('Failed to load WKT from URL:', e);
1326
+ geoJsonData = emptyCollection;
1327
+ }
1328
+ }
1329
+ else {
1330
+ geoJsonData = emptyCollection;
1331
+ }
1332
+ log('[Leaflet WKT] Creating layer with GeoJSON data:', geoJsonData);
1333
+ log('[Leaflet WKT] Config:', config);
1334
+ // Use geostyler style if available, otherwise use config style or default
1335
+ let layerOptions = {};
1336
+ if (config.geostylerStyle) {
1337
+ layerOptions = await this.createGeostylerLeafletOptions(config.geostylerStyle);
1338
+ }
1339
+ else {
1340
+ const style = config.style
1341
+ ? { ...DEFAULT_STYLE, ...config.style }
1342
+ : DEFAULT_STYLE;
1343
+ layerOptions = {
1344
+ style: this.createLeafletStyle(style),
1345
+ pointToLayer: (feature, latlng) => this.createLeafletPoint(feature, latlng, style),
1346
+ onEachFeature: (feature, layer) => this.bindLeafletPopup(feature, layer, style),
1347
+ };
1348
+ }
1349
+ log('[Leaflet WKT] Layer options:', layerOptions);
1350
+ const layer = L.geoJSON(geoJsonData, layerOptions);
1351
+ log('[Leaflet WKT] Created layer:', layer);
1352
+ if (typeof layer.getBounds === 'function') {
1353
+ log('[Leaflet WKT] Layer bounds:', layer.getBounds());
1354
+ }
1355
+ return layer;
1356
+ }
1357
+ async wktToGeoJSON(wkt) {
1358
+ try {
1359
+ // Use wellknown library to parse WKT into GeoJSON (browser-compatible)
1360
+ const geoJSON = wellknownExports.wellknown.parse(wkt);
1361
+ if (!geoJSON) {
1362
+ throw new Error('Failed to parse WKT - returned null');
1363
+ }
1364
+ // Return as a Feature
1365
+ const feature = {
1366
+ type: 'Feature',
1367
+ geometry: geoJSON,
1368
+ properties: {},
1369
+ };
1370
+ // Debug output to browser console
1371
+ log('[Leaflet WKT] Input WKT:', wkt);
1372
+ log('[Leaflet WKT] Generated GeoJSON:', JSON.stringify(feature, null, 2));
1373
+ const fc = {
1374
+ type: 'FeatureCollection',
1375
+ features: [feature],
1376
+ };
1377
+ return fc;
1378
+ }
1379
+ catch (e) {
1380
+ error('[Leaflet WKT] Failed to parse WKT:', wkt, e);
1381
+ // If parsing fails, return empty FeatureCollection
1382
+ const empty = { type: 'FeatureCollection', features: [] };
1383
+ return empty;
1384
+ }
1385
+ }
1386
+ async createGeoTIFFLayer(config) {
1387
+ if (!config.url) {
1388
+ throw new Error('GeoTIFF layer requires a URL');
1389
+ }
1390
+ try {
1391
+ const layer = new GeoTIFFGridLayer({
1392
+ url: config.url,
1393
+ tileSize: 256,
1394
+ colorMap: config.colorMap,
1395
+ valueRange: config.valueRange,
1396
+ nodata: config.nodata,
1397
+ resolution: config.resolution,
1398
+ resampleMethod: config.resampleMethod,
1399
+ viewProjection: this.map.options.crs.code,
1400
+ });
1401
+ if (config.opacity !== undefined) {
1402
+ layer.setOpacity?.(config.opacity);
1403
+ }
1404
+ if (config.zIndex !== undefined) {
1405
+ layer.setZIndex?.(config.zIndex);
1406
+ }
1407
+ return layer;
1408
+ }
1409
+ catch (err) {
1410
+ error('Failed to create GeoTIFF layer:', err);
1411
+ // Return a placeholder layer in case of error
1412
+ return L.layerGroup([]);
1413
+ }
1414
+ }
1415
+ async updateGeoTIFFLayer(layer, data) {
1416
+ if (!data.url) {
1417
+ throw new Error('GeoTIFF update requires a URL');
1418
+ }
1419
+ if (!layer)
1420
+ return;
1421
+ if (!(layer instanceof GeoTIFFGridLayer))
1422
+ return;
1423
+ const extData = data;
1424
+ await layer.updateSource({
1425
+ url: data.url,
1426
+ colorMap: data.colorMap,
1427
+ valueRange: data.valueRange,
1428
+ nodata: data.nodata,
1429
+ resolution: extData.resolution,
1430
+ resampleMethod: extData.resampleMethod,
1431
+ });
1432
+ }
1433
+ async createWCSLayer(config) {
1434
+ if (!config.url) {
1435
+ throw new Error('WCS layer requires a URL');
1436
+ }
1437
+ if (!config.coverageName) {
1438
+ throw new Error('WCS layer requires a coverageName');
1439
+ }
1440
+ try {
1441
+ const wcsOptions = {
1442
+ url: config.url,
1443
+ coverageName: config.coverageName,
1444
+ version: config.version ?? '2.0.1',
1445
+ format: config.format ?? 'image/tiff',
1446
+ projection: config.projection ?? 'EPSG:4326',
1447
+ params: config.params,
1448
+ };
1449
+ // Add GridLayer options
1450
+ if (config.tileSize)
1451
+ wcsOptions.tileSize = config.tileSize;
1452
+ if (config.minZoom !== undefined)
1453
+ wcsOptions.minZoom = config.minZoom;
1454
+ if (config.maxZoom !== undefined)
1455
+ wcsOptions.maxZoom = config.maxZoom;
1456
+ const layer = new WCSGridLayer(wcsOptions);
1457
+ if (config.opacity !== undefined) {
1458
+ layer.setOpacity?.(config.opacity);
1459
+ }
1460
+ if (config.zIndex !== undefined) {
1461
+ layer.setZIndex?.(config.zIndex);
1462
+ }
1463
+ return layer;
1464
+ }
1465
+ catch (err) {
1466
+ error('[Leaflet WCS] Failed to create WCS layer:', err);
1467
+ // Return a placeholder layer in case of error
1468
+ return L.layerGroup([]);
1469
+ }
1470
+ }
1471
+ async updateWCSLayer(layer, data) {
1472
+ if (!layer)
1473
+ return;
1474
+ if (layer instanceof WCSGridLayer) {
1475
+ const updateOptions = {};
1476
+ if (data.url)
1477
+ updateOptions.url = data.url;
1478
+ if (data.coverageName)
1479
+ updateOptions.coverageName = data.coverageName;
1480
+ if (data.version)
1481
+ updateOptions.version = data.version;
1482
+ if (data.format)
1483
+ updateOptions.format = data.format;
1484
+ if (data.projection)
1485
+ updateOptions.projection = data.projection;
1486
+ if (data.params)
1487
+ updateOptions.params = data.params;
1488
+ layer.updateOptions(updateOptions);
1489
+ }
1490
+ }
1491
+ // ========== Enhanced Styling Methods ==========
1492
+ /**
1493
+ * Convert a Geostyler style to Leaflet GeoJSON options
1494
+ */
1495
+ async createGeostylerLeafletOptions(geostylerStyle) {
1496
+ // Helper to extract static value from GeoStyler property
1497
+ const getValue = (prop, defaultValue = undefined) => {
1498
+ if (prop === undefined || prop === null)
1499
+ return defaultValue;
1500
+ // If it's a GeoStyler function object, we can't evaluate it here - return default
1501
+ if (typeof prop === 'object' && prop.name)
1502
+ return defaultValue;
1503
+ return prop;
1504
+ };
1505
+ const options = {
1506
+ style: (feature) => {
1507
+ const geometryType = feature?.geometry?.type;
1508
+ let leafletStyle = {};
1509
+ if (geostylerStyle.rules) {
1510
+ for (const rule of geostylerStyle.rules) {
1511
+ if (rule.symbolizers) {
1512
+ for (const symbolizer of rule.symbolizers) {
1513
+ switch (symbolizer.kind) {
1514
+ case 'Fill':
1515
+ if (geometryType === 'Polygon' ||
1516
+ geometryType === 'MultiPolygon') {
1517
+ const fillColor = getValue(symbolizer.color, 'rgba(0,100,255,0.3)');
1518
+ const fillOpacity = getValue(symbolizer.opacity, 0.3);
1519
+ const outlineColor = getValue(symbolizer.outlineColor, 'rgba(0,100,255,1)');
1520
+ const outlineWidth = getValue(symbolizer.outlineWidth, 1);
1521
+ leafletStyle = {
1522
+ ...leafletStyle,
1523
+ fillColor: fillColor,
1524
+ fillOpacity: fillOpacity,
1525
+ color: outlineColor,
1526
+ weight: outlineWidth,
1527
+ };
1528
+ }
1529
+ break;
1530
+ case 'Line':
1531
+ const lineColor = getValue(symbolizer.color, 'rgba(0,100,255,1)');
1532
+ const lineWidth = getValue(symbolizer.width, 2);
1533
+ const dashArray = symbolizer.dasharray
1534
+ ? Array.isArray(symbolizer.dasharray)
1535
+ ? symbolizer.dasharray
1536
+ .map((v) => getValue(v, 0))
1537
+ .join(',')
1538
+ : undefined
1539
+ : undefined;
1540
+ leafletStyle = {
1541
+ ...leafletStyle,
1542
+ color: lineColor,
1543
+ weight: lineWidth,
1544
+ dashArray: dashArray,
1545
+ };
1546
+ break;
1547
+ }
1548
+ }
1549
+ }
1550
+ }
1551
+ }
1552
+ return leafletStyle;
1553
+ },
1554
+ pointToLayer: (_feature, latlng) => {
1555
+ if (geostylerStyle.rules) {
1556
+ for (const rule of geostylerStyle.rules) {
1557
+ if (rule.symbolizers) {
1558
+ for (const symbolizer of rule.symbolizers) {
1559
+ switch (symbolizer.kind) {
1560
+ case 'Mark':
1561
+ const markColor = getValue(symbolizer.color, 'rgba(0,100,255,1)');
1562
+ const markRadius = getValue(symbolizer.radius, 6);
1563
+ const strokeColor = getValue(symbolizer.strokeColor, 'rgba(0,100,255,1)');
1564
+ const strokeWidth = getValue(symbolizer.strokeWidth, 2);
1565
+ return L.circleMarker(latlng, {
1566
+ radius: markRadius,
1567
+ fillColor: markColor,
1568
+ fillOpacity: 1,
1569
+ color: strokeColor,
1570
+ weight: strokeWidth,
1571
+ });
1572
+ case 'Icon':
1573
+ const iconSrc = getValue(symbolizer.image);
1574
+ const iconSize = getValue(symbolizer.size, 32);
1575
+ if (iconSrc && typeof iconSrc === 'string') {
1576
+ const icon = L.icon({
1577
+ iconUrl: iconSrc,
1578
+ iconSize: [iconSize, iconSize],
1579
+ iconAnchor: [iconSize / 2, iconSize],
1580
+ });
1581
+ return L.marker(latlng, { icon });
1582
+ }
1583
+ break;
1584
+ }
1585
+ }
1586
+ }
1587
+ }
1588
+ }
1589
+ // Default point style
1590
+ return L.circleMarker(latlng, {
1591
+ radius: 6,
1592
+ fillColor: 'rgba(0,100,255,1)',
1593
+ fillOpacity: 1,
1594
+ color: 'rgba(0,100,255,1)',
1595
+ weight: 2,
1596
+ });
1597
+ },
1598
+ onEachFeature: (feature, layer) => {
1599
+ if (geostylerStyle.rules) {
1600
+ for (const rule of geostylerStyle.rules) {
1601
+ if (rule.symbolizers) {
1602
+ for (const symbolizer of rule.symbolizers) {
1603
+ if (symbolizer.kind === 'Text') {
1604
+ const labelProp = symbolizer.label;
1605
+ if (labelProp &&
1606
+ typeof labelProp === 'string' &&
1607
+ feature.properties &&
1608
+ feature.properties[labelProp]) {
1609
+ const textContent = String(feature.properties[labelProp]);
1610
+ const textColor = getValue(symbolizer.color, '#000000');
1611
+ const textSize = getValue(symbolizer.size, 12);
1612
+ const styledText = `<div style="color: ${textColor}; font-size: ${textSize}px; font-family: Arial, sans-serif;">${textContent}</div>`;
1613
+ layer.bindTooltip(styledText, {
1614
+ permanent: true,
1615
+ direction: 'center',
1616
+ className: 'leaflet-tooltip-custom',
1617
+ });
1618
+ }
1619
+ }
1620
+ }
1621
+ }
1622
+ }
1623
+ }
1624
+ },
1625
+ };
1626
+ return options;
1627
+ }
1628
+ createLeafletStyle(style) {
1629
+ return (feature) => {
1630
+ const geometryType = feature?.geometry?.type;
1631
+ const fillColor = style?.fillColor ?? 'rgba(0,100,255,0.3)';
1632
+ const fillOpacity = style?.fillOpacity ?? 0.3;
1633
+ const strokeColor = style?.strokeColor ?? 'rgba(0,100,255,1)';
1634
+ const strokeOpacity = style?.strokeOpacity ?? 1;
1635
+ const strokeWidth = style?.strokeWidth ?? 2;
1636
+ if (geometryType === 'Polygon' || geometryType === 'MultiPolygon') {
1637
+ return {
1638
+ fillColor,
1639
+ fillOpacity,
1640
+ color: strokeColor,
1641
+ opacity: strokeOpacity,
1642
+ weight: strokeWidth,
1643
+ dashArray: style?.strokeDashArray
1644
+ ? style.strokeDashArray.join(',')
1645
+ : undefined,
1646
+ };
1647
+ }
1648
+ if (geometryType === 'LineString' || geometryType === 'MultiLineString') {
1649
+ return {
1650
+ color: strokeColor,
1651
+ opacity: strokeOpacity,
1652
+ weight: strokeWidth,
1653
+ dashArray: style?.strokeDashArray
1654
+ ? style.strokeDashArray.join(',')
1655
+ : undefined,
1656
+ };
1657
+ }
1658
+ return {};
1659
+ };
1660
+ }
1661
+ createLeafletPoint(feature, latlng, style) {
1662
+ let finalStyle = { ...(style ?? {}) };
1663
+ if (style?.styleFunction) {
1664
+ const conditionalStyle = style.styleFunction(feature);
1665
+ if (conditionalStyle) {
1666
+ finalStyle = {
1667
+ ...style,
1668
+ ...conditionalStyle,
1669
+ };
1670
+ }
1671
+ }
1672
+ if (finalStyle?.iconUrl) {
1673
+ // Create icon marker
1674
+ const iconSize = finalStyle.iconSize || [32, 32];
1675
+ const iconAnchor = finalStyle.iconAnchor || [
1676
+ iconSize[0] / 2,
1677
+ iconSize[1],
1678
+ ];
1679
+ const icon = L.icon({
1680
+ iconUrl: finalStyle.iconUrl,
1681
+ iconSize: iconSize,
1682
+ iconAnchor: iconAnchor,
1683
+ });
1684
+ return L.marker(latlng, { icon });
1685
+ }
1686
+ else {
1687
+ // Create circle marker
1688
+ const pointColor = finalStyle?.pointColor ?? 'rgba(0,100,255,1)';
1689
+ const pointOpacity = finalStyle?.pointOpacity ?? 1;
1690
+ const pointRadius = finalStyle?.pointRadius ?? 6;
1691
+ const strokeColor = finalStyle?.strokeColor ?? 'rgba(0,100,255,1)';
1692
+ const strokeOpacity = finalStyle?.strokeOpacity ?? 1;
1693
+ const strokeWidth = finalStyle?.strokeWidth ?? 2;
1694
+ return L.circleMarker(latlng, {
1695
+ radius: pointRadius,
1696
+ fillColor: pointColor,
1697
+ fillOpacity: pointOpacity,
1698
+ color: strokeColor,
1699
+ opacity: strokeOpacity,
1700
+ weight: strokeWidth,
1701
+ });
1702
+ }
1703
+ }
1704
+ bindLeafletPopup(feature, layer, style) {
1705
+ // Text labeling via popup or tooltip - handle undefined style
1706
+ if (style?.textProperty &&
1707
+ feature.properties &&
1708
+ feature.properties[style.textProperty]) {
1709
+ const textContent = String(feature.properties[style.textProperty]);
1710
+ const textColor = style?.textColor ?? '#000000';
1711
+ const textSize = style?.textSize ?? 12;
1712
+ // Create styled text content
1713
+ const styledText = `<div style="color: ${textColor}; font-size: ${textSize}px; font-family: Arial, sans-serif;">${textContent}</div>`;
1714
+ // Bind as permanent tooltip for labels or popup for clickable info
1715
+ layer.bindTooltip(styledText, {
1716
+ permanent: true,
1717
+ direction: 'center',
1718
+ className: 'leaflet-tooltip-custom',
1719
+ });
1720
+ }
1721
+ }
1722
+ async createWFSLayer(config) {
1723
+ const geojson = await this.fetchWFSFromUrl(config);
1724
+ // Use geostyler style if available, otherwise use provided style or default style
1725
+ let layerOptions = {};
1726
+ if (config.geostylerStyle) {
1727
+ layerOptions = await this.createGeostylerLeafletOptions(config.geostylerStyle);
1728
+ }
1729
+ else {
1730
+ const style = config.style
1731
+ ? { ...DEFAULT_STYLE, ...config.style }
1732
+ : DEFAULT_STYLE;
1733
+ layerOptions = {
1734
+ style: this.createLeafletStyle(style),
1735
+ pointToLayer: (feature, latlng) => this.createLeafletPoint(feature, latlng, style),
1736
+ onEachFeature: (feature, layer) => this.bindLeafletPopup(feature, layer, style),
1737
+ };
1738
+ }
1739
+ const layer = L.geoJSON(geojson, layerOptions);
1740
+ return layer;
1741
+ }
1742
+ async updateWFSLayer(layer, data) {
1743
+ const geojson = await this.fetchWFSFromUrl(data);
1744
+ layer.clearLayers();
1745
+ layer.addData(geojson);
1746
+ }
1747
+ async fetchWFSFromUrl(config) {
1748
+ const baseParams = {
1749
+ service: 'WFS',
1750
+ request: 'GetFeature',
1751
+ version: config.version ?? '1.1.0',
1752
+ typeName: config.typeName,
1753
+ outputFormat: config.outputFormat ?? 'application/json',
1754
+ srsName: config.srsName ?? 'EPSG:4326',
1755
+ };
1756
+ const params = { ...baseParams, ...(config.params ?? {}) };
1757
+ const requestUrl = this.appendParams(config.url, params);
1758
+ const response = await fetch(requestUrl);
1759
+ if (!response.ok) {
1760
+ throw new Error(`WFS request failed (${response.status} ${response.statusText})`);
1761
+ }
1762
+ const outputFormat = (config.outputFormat ?? 'application/json').toLowerCase();
1763
+ // Handle JSON formats
1764
+ if (outputFormat.includes('json') ||
1765
+ outputFormat.includes('geojson') ||
1766
+ outputFormat === 'application/json') {
1767
+ return (await response.json());
1768
+ }
1769
+ // Handle GML formats - parse XML to GeoJSON using gml2geojson
1770
+ if (outputFormat.includes('gml') || outputFormat.includes('xml')) {
1771
+ const xml = await response.text();
1772
+ const parser = new GmlParser();
1773
+ return (await parser.parse(xml));
1774
+ }
1775
+ // Default: try to parse as JSON
1776
+ return (await response.json());
1777
+ }
1778
+ appendParams(baseUrl, params) {
1779
+ const query = new URLSearchParams();
1780
+ Object.entries(params).forEach(([key, value]) => {
1781
+ if (value !== undefined && value !== null) {
1782
+ query.set(key, String(value));
1783
+ }
1784
+ });
1785
+ if (!query.toString())
1786
+ return baseUrl;
1787
+ return `${baseUrl}${baseUrl.includes('?') ? '&' : '?'}${query.toString()}`;
1788
+ }
1789
+ getMap() {
1790
+ return this.map;
1791
+ }
1792
+ }
1793
+
1794
+ export { LeafletProvider };