@kalisio/kdk 2.5.3 → 2.6.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 (545) hide show
  1. package/.github/workflows/main.yaml +35 -6
  2. package/client.globe.js +8 -0
  3. package/client.js +8 -0
  4. package/client.map.js +8 -0
  5. package/core/api/hooks/hooks.push.js +3 -2
  6. package/core/api/hooks/hooks.tags.js +56 -0
  7. package/core/api/models/tags.model.mongodb.js +8 -0
  8. package/core/api/services/index.js +33 -2
  9. package/core/api/services/tags/tags.hooks.js +47 -0
  10. package/core/client/api.js +5 -5
  11. package/core/client/components/KActivity.vue +3 -2
  12. package/core/client/components/KChip.vue +2 -2
  13. package/core/client/components/KEditor.vue +3 -1
  14. package/core/client/components/KFollower.vue +4 -4
  15. package/core/client/components/KStore.vue +1 -1
  16. package/core/client/components/KTab.vue +20 -7
  17. package/core/client/components/account/KProfile.vue +9 -25
  18. package/core/client/components/action/KAction.vue +10 -10
  19. package/core/client/components/action/KToggleFullscreenAction.vue +2 -11
  20. package/core/client/components/app/KHome.vue +3 -2
  21. package/core/client/components/collection/KFilter.vue +5 -4
  22. package/core/client/components/collection/KGrid.vue +5 -1
  23. package/core/client/components/collection/KItemsFilter.vue +47 -0
  24. package/core/client/components/collection/KItemsSorter.vue +42 -0
  25. package/core/client/components/collection/KScrollDown.vue +2 -2
  26. package/core/client/components/collection/KSearchFilterControl.vue +3 -2
  27. package/core/client/components/collection/KSorter.vue +33 -37
  28. package/core/client/components/collection/KTagsFilterControl.vue +14 -40
  29. package/core/client/components/collection/KTagsFilterView.vue +10 -45
  30. package/core/client/components/collection/KTimeFilterControl.vue +6 -7
  31. package/core/client/components/collection/KTimeFilterView.vue +13 -22
  32. package/core/client/components/collection/KTimeLine.vue +18 -9
  33. package/core/client/components/form/KColorField.vue +13 -6
  34. package/core/client/components/form/KColorScaleField.vue +7 -12
  35. package/core/client/components/form/KFileField.vue +118 -89
  36. package/core/client/components/form/KForm.vue +30 -18
  37. package/core/client/components/form/KIconField.vue +4 -1
  38. package/core/client/components/form/KNumberField.vue +9 -2
  39. package/core/client/components/form/KSelectField.vue +1 -4
  40. package/core/client/components/form/KTagField.vue +229 -0
  41. package/core/client/components/form/KTextField.vue +4 -0
  42. package/core/client/components/form/KTextareaField.vue +3 -1
  43. package/core/client/components/input/KShapePicker.vue +3 -3
  44. package/core/client/components/layout/KFab.vue +32 -20
  45. package/core/client/components/layout/KPage.vue +11 -6
  46. package/core/client/components/layout/KWindow.vue +5 -0
  47. package/core/client/components/media/index.js +2 -6
  48. package/core/client/components/menu/KMenu.vue +12 -10
  49. package/core/client/components/menu/KSubMenu.vue +12 -12
  50. package/core/client/components/messages/KMessageCard.vue +13 -12
  51. package/core/client/components/messages/KMessageComposer.vue +13 -9
  52. package/core/client/components/messages/KMessagesTimeLine.vue +16 -8
  53. package/core/client/components/tags/KTagFilter.vue +99 -0
  54. package/core/client/components/tags/KTagItem.vue +65 -0
  55. package/core/client/components/tags/KTagManager.vue +198 -0
  56. package/core/client/components/tags/KTagSelection.vue +82 -0
  57. package/core/client/components/time/KDate.vue +3 -17
  58. package/core/client/components/time/KDateTime.vue +1 -1
  59. package/core/client/components/time/KTime.vue +0 -4
  60. package/core/client/composables/collection-filter.js +41 -2
  61. package/core/client/composables/collection.js +3 -3
  62. package/core/client/composables/index.js +1 -0
  63. package/core/client/composables/pwa.js +13 -0
  64. package/core/client/composables/session.js +7 -8
  65. package/core/client/composables/user.js +36 -0
  66. package/core/client/directives/index.js +1 -0
  67. package/core/client/directives/v-drop-file.js +174 -0
  68. package/core/client/document.js +2 -1
  69. package/core/client/exporter.js +17 -3
  70. package/core/client/i18n/core_en.json +34 -7
  71. package/core/client/i18n/core_fr.json +36 -9
  72. package/core/client/i18n.js +26 -11
  73. package/core/client/layout.js +5 -5
  74. package/core/client/mixins/mixin.base-activity.js +8 -5
  75. package/core/client/mixins/mixin.base-editor.js +2 -1
  76. package/core/client/mixins/mixin.base-field.js +3 -2
  77. package/core/client/mixins/mixin.base-item.js +12 -10
  78. package/core/client/mixins/mixin.service.js +3 -1
  79. package/core/client/platform.js +0 -3
  80. package/core/client/readers/reader.json.js +2 -2
  81. package/core/client/utils/index.js +2 -0
  82. package/core/client/utils/utils.collection.js +6 -6
  83. package/core/client/utils/utils.colors.js +46 -19
  84. package/core/client/utils/utils.files.js +19 -0
  85. package/core/client/utils/utils.locale.js +13 -17
  86. package/core/client/utils/utils.services.js +27 -0
  87. package/core/client/utils/utils.shapes.js +2 -2
  88. package/core/client/utils/utils.tags.js +17 -0
  89. package/core/client/utils/utils.tours.js +31 -0
  90. package/core/common/permissions.js +3 -0
  91. package/core/common/schemas/tags.update.json +35 -0
  92. package/core/common/schemas/users.update-profile.json +1 -1
  93. package/core/common/utils.js +5 -5
  94. package/extras/configs/panes.top.js +11 -0
  95. package/extras/configs/stickies.js +1 -1
  96. package/extras/configs/widgets.left.js +13 -1
  97. package/extras/libs/jsts.min.js +8 -0
  98. package/{test/client/core/account.js → extras/tests/core/account.mjs} +4 -4
  99. package/extras/tests/core/api.mjs +114 -0
  100. package/{test/client/core/collection.js → extras/tests/core/collection.mjs} +8 -8
  101. package/{test/client/core/dialogs.js → extras/tests/core/dialogs.mjs} +1 -1
  102. package/extras/tests/core/index.mjs +9 -0
  103. package/{test/client/core/layout.js → extras/tests/core/layout.mjs} +7 -3
  104. package/{test/client/core/runner.js → extras/tests/core/runner.mjs} +3 -3
  105. package/{test/client/core/screens.js → extras/tests/core/screens.mjs} +1 -1
  106. package/{test/client/core/utils.js → extras/tests/core/utils.mjs} +79 -26
  107. package/extras/tests/index.mjs +4 -0
  108. package/{test/client/map/api.js → extras/tests/map/api.mjs} +1 -1
  109. package/{test/client/map/catalog.js → extras/tests/map/catalog.mjs} +18 -18
  110. package/{test/client/map/controls.js → extras/tests/map/controls.mjs} +3 -3
  111. package/extras/tests/map/index.mjs +5 -0
  112. package/{test/client/map/time.js → extras/tests/map/time.mjs} +3 -3
  113. package/{test/client/map/utils.js → extras/tests/map/utils.mjs} +6 -5
  114. package/extras/tours/fab.js +36 -0
  115. package/extras/tours/layout.js +49 -0
  116. package/extras/tours/pane.left.js +78 -0
  117. package/extras/tours/pane.right.js +145 -0
  118. package/extras/tours/pane.top.js +239 -0
  119. package/map/api/config/layers.cjs +28 -13
  120. package/map/api/hooks/hooks.query.js +12 -7
  121. package/map/api/models/catalog.model.mongodb.js +17 -6
  122. package/map/api/services/catalog/catalog.hooks.js +1 -1
  123. package/map/api/services/index.js +18 -1
  124. package/map/client/cesium/utils/utils.cesium.js +25 -65
  125. package/map/client/cesium/utils/utils.features.js +1 -0
  126. package/map/client/cesium/utils/utils.geojson.js +1 -0
  127. package/map/client/cesium/utils/utils.style.js +7 -6
  128. package/map/client/components/KFeatureEditor.vue +3 -3
  129. package/map/client/components/KFeaturesChart.vue +4 -4
  130. package/map/client/components/KFeaturesFilterEditor.vue +19 -13
  131. package/map/client/components/KFeaturesFilterManager.vue +7 -4
  132. package/map/client/components/KFeaturesTable.vue +2 -2
  133. package/map/client/components/KLayerEditor.vue +6 -6
  134. package/map/client/components/KMeasureTool.vue +2 -1
  135. package/map/client/components/catalog/KBaseLayersSelector.vue +1 -1
  136. package/map/client/components/catalog/KCategoryItem.vue +15 -1
  137. package/map/client/components/catalog/KConnectLayer.vue +2 -2
  138. package/map/client/components/catalog/KCreateView.vue +3 -2
  139. package/map/client/components/catalog/KFilteredLayerItem.vue +26 -6
  140. package/map/client/components/catalog/KImportLayer.vue +6 -3
  141. package/map/client/components/catalog/KLayerCategories.vue +6 -6
  142. package/map/client/components/catalog/KLayerItem.vue +12 -2
  143. package/map/client/components/catalog/KLayersList.vue +180 -0
  144. package/map/client/components/catalog/KLayersPanel.vue +146 -36
  145. package/map/client/components/catalog/KLayersSelector.vue +96 -48
  146. package/map/client/components/catalog/KProjectEditor.vue +0 -9
  147. package/map/client/components/catalog/KProjectSelector.vue +3 -2
  148. package/map/client/components/catalog/KProjectsPanel.vue +23 -8
  149. package/map/client/components/catalog/KViewsPanel.vue +18 -8
  150. package/map/client/components/catalog/KWeatherLayersSelector.vue +3 -3
  151. package/map/client/components/form/KDirectionField.vue +3 -6
  152. package/map/client/components/form/KLayerCategoryField.vue +2 -2
  153. package/map/client/components/form/KOwsServiceField.vue +25 -24
  154. package/map/client/components/form/KSelectLayersField.vue +4 -4
  155. package/map/client/components/form/KSelectViewsField.vue +4 -4
  156. package/map/client/components/legend/KLayerLegend.vue +11 -2
  157. package/map/client/components/legend/KLegend.vue +44 -51
  158. package/map/client/components/location/KLocationCardSection.vue +6 -7
  159. package/map/client/components/location/KLocationMap.vue +23 -13
  160. package/map/client/components/stickies/KPosition.vue +5 -0
  161. package/map/client/components/styles/KLayerStyleAction.vue +59 -12
  162. package/map/client/components/styles/KStyleEditor.vue +71 -8
  163. package/map/client/components/styles/KStyleEditorSection.vue +82 -33
  164. package/map/client/components/styles/KStyleManager.vue +119 -59
  165. package/map/client/components/styles/KStylePreview.vue +9 -25
  166. package/map/client/components/styles/KStylePreviewItem.vue +22 -1
  167. package/map/client/components/tools/KSearchTool.vue +1 -1
  168. package/map/client/components/widget/KElevationProfile.vue +20 -17
  169. package/map/client/components/widget/KInformationBox.vue +5 -5
  170. package/map/client/components/widget/KMapillaryViewer.vue +2 -1
  171. package/map/client/components/widget/KTimeSeries.vue +11 -9
  172. package/map/client/globe.js +2 -0
  173. package/map/client/i18n/map_en.json +29 -7
  174. package/map/client/i18n/map_fr.json +29 -7
  175. package/map/client/leaflet/GradientPath.js +61 -24
  176. package/map/client/leaflet/ShapeMarker.js +12 -5
  177. package/map/client/leaflet/TiledMeshLayer.js +3 -3
  178. package/map/client/leaflet/utils/utils.geojson.js +66 -8
  179. package/map/client/leaflet/utils/utils.style.js +14 -15
  180. package/map/client/mixins/globe/mixin.base-globe.js +181 -34
  181. package/map/client/mixins/globe/mixin.file-layers.js +3 -0
  182. package/map/client/mixins/globe/mixin.geojson-layers.js +179 -31
  183. package/map/client/mixins/globe/mixin.opendap-layers.js +2 -1
  184. package/map/client/mixins/globe/mixin.style.js +23 -1
  185. package/map/client/mixins/globe/mixin.tooltip.js +14 -2
  186. package/map/client/mixins/map/mixin.base-map.js +146 -58
  187. package/map/client/mixins/map/mixin.edit-layers.js +18 -15
  188. package/map/client/mixins/map/mixin.geojson-layers.js +181 -106
  189. package/map/client/mixins/map/mixin.heatmap-layers.js +3 -2
  190. package/map/client/mixins/map/mixin.map-activity.js +6 -1
  191. package/map/client/mixins/map/mixin.mapillary-layers.js +2 -1
  192. package/map/client/mixins/map/mixin.pmtiles-layers.js +3 -3
  193. package/map/client/mixins/map/mixin.tiled-mesh-layers.js +3 -2
  194. package/map/client/mixins/map/mixin.tiled-wind-layers.js +3 -2
  195. package/map/client/mixins/mixin.activity.js +197 -51
  196. package/map/client/mixins/mixin.context.js +11 -11
  197. package/map/client/mixins/mixin.feature-service.js +11 -9
  198. package/map/client/mixins/mixin.weacast.js +5 -3
  199. package/map/client/readers/reader.geojson.js +3 -1
  200. package/map/client/utils/utils.capture.js +3 -3
  201. package/map/client/utils/utils.catalog.js +9 -5
  202. package/map/client/utils/utils.features.js +120 -54
  203. package/map/client/utils/utils.js +25 -10
  204. package/map/client/utils/utils.layers.js +148 -24
  205. package/map/client/utils/utils.location.js +26 -9
  206. package/map/client/utils/utils.schema.js +2 -1
  207. package/map/client/utils/utils.style.js +53 -9
  208. package/map/common/geotiff-grid-source.js +1 -3
  209. package/map/common/opendap-utils.js +0 -1
  210. package/map/common/tms-utils.js +0 -1
  211. package/map/common/wcs-utils.js +0 -1
  212. package/map/common/wfs-utils.js +0 -1
  213. package/map/common/wms-utils.js +7 -1
  214. package/map/common/wmts-utils.js +0 -1
  215. package/package.json +12 -12
  216. package/scripts/init_runner.sh +3 -3
  217. package/scripts/kash/CHANGELOG.md +27 -0
  218. package/scripts/kash/kash.sh +556 -237
  219. package/scripts/kash/scripts/run_tests.sh +44 -5
  220. package/scripts/setup_workspace.sh +23 -13
  221. package/test/api/core/config/default.cjs +2 -1
  222. package/test/api/core/tags.test.js +62 -0
  223. package/test/api/map/config/default.cjs +2 -1
  224. package/test/api/map/config/layers.json +9 -0
  225. package/test/api/map/data/openradiation.json +13811 -0
  226. package/test/api/map/grid-sources.test.js +1 -3
  227. package/test/api/map/index.test.js +60 -1
  228. package/test/api/map/style.test.js +30 -1
  229. package/test.api.js +1 -1
  230. package/vite/App.vue +18 -0
  231. package/vite/AppWithGlobe.vue +84 -0
  232. package/vite/GlobeActivity.vue +58 -0
  233. package/vite/MapActivity.vue +63 -0
  234. package/vite/MapActivityWithGlobe.vue +63 -0
  235. package/vite/README.md +169 -0
  236. package/vite/config.js +221 -0
  237. package/vite/index_with_globe.html +50 -0
  238. package/vite/index_with_map.html +50 -0
  239. package/vite/package.json +173 -0
  240. package/vite/quasar.variables.scss +17 -0
  241. package/vite/vite.config.js +166 -0
  242. package/vite/yarn.lock +11641 -0
  243. package/core/client/components/media/KImageViewer.vue +0 -68
  244. package/core/client/components/media/KMarkdownViewer.vue +0 -55
  245. package/core/client/components/media/KMediaBrowser.vue +0 -301
  246. package/coverage/base.css +0 -224
  247. package/coverage/block-navigation.js +0 -87
  248. package/coverage/core/api/application.js.html +0 -1870
  249. package/coverage/core/api/authentication.js.html +0 -874
  250. package/coverage/core/api/db.js.html +0 -793
  251. package/coverage/core/api/hooks/hooks.authentication.js.html +0 -139
  252. package/coverage/core/api/hooks/hooks.authorisations.js.html +0 -958
  253. package/coverage/core/api/hooks/hooks.groups.js.html +0 -229
  254. package/coverage/core/api/hooks/hooks.logger.js.html +0 -163
  255. package/coverage/core/api/hooks/hooks.model.js.html +0 -967
  256. package/coverage/core/api/hooks/hooks.organisations.js.html +0 -541
  257. package/coverage/core/api/hooks/hooks.push.js.html +0 -265
  258. package/coverage/core/api/hooks/hooks.query.js.html +0 -862
  259. package/coverage/core/api/hooks/hooks.schemas.js.html +0 -298
  260. package/coverage/core/api/hooks/hooks.service.js.html +0 -319
  261. package/coverage/core/api/hooks/hooks.storage.js.html +0 -193
  262. package/coverage/core/api/hooks/hooks.users.js.html +0 -595
  263. package/coverage/core/api/hooks/index.html +0 -266
  264. package/coverage/core/api/hooks/index.js.html +0 -115
  265. package/coverage/core/api/index.html +0 -176
  266. package/coverage/core/api/index.js.html +0 -148
  267. package/coverage/core/api/marshall.js.html +0 -448
  268. package/coverage/core/api/models/groups.model.mongodb.js.html +0 -109
  269. package/coverage/core/api/models/index.html +0 -131
  270. package/coverage/core/api/models/messages.model.mongodb.js.html +0 -121
  271. package/coverage/core/api/models/organisations.model.mongodb.js.html +0 -94
  272. package/coverage/core/api/models/tags.model.mongodb.js.html +0 -115
  273. package/coverage/core/api/models/users.model.mongodb.js.html +0 -115
  274. package/coverage/core/api/services/account/account.hooks.js.html +0 -208
  275. package/coverage/core/api/services/account/account.service.js.html +0 -436
  276. package/coverage/core/api/services/account/index.html +0 -131
  277. package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +0 -184
  278. package/coverage/core/api/services/authorisations/authorisations.service.js.html +0 -520
  279. package/coverage/core/api/services/authorisations/index.html +0 -131
  280. package/coverage/core/api/services/databases/databases.hooks.js.html +0 -193
  281. package/coverage/core/api/services/databases/databases.service.js.html +0 -100
  282. package/coverage/core/api/services/databases/index.html +0 -131
  283. package/coverage/core/api/services/groups/groups.hooks.js.html +0 -178
  284. package/coverage/core/api/services/groups/index.html +0 -116
  285. package/coverage/core/api/services/import-export/import-export.hooks.js.html +0 -184
  286. package/coverage/core/api/services/import-export/import-export.service.js.html +0 -118
  287. package/coverage/core/api/services/import-export/index.html +0 -131
  288. package/coverage/core/api/services/index.html +0 -116
  289. package/coverage/core/api/services/index.js.html +0 -532
  290. package/coverage/core/api/services/mailer/index.html +0 -131
  291. package/coverage/core/api/services/mailer/mailer.hooks.js.html +0 -190
  292. package/coverage/core/api/services/mailer/mailer.service.js.html +0 -118
  293. package/coverage/core/api/services/messages/index.html +0 -116
  294. package/coverage/core/api/services/messages/messages.hooks.js.html +0 -202
  295. package/coverage/core/api/services/organisations/index.html +0 -131
  296. package/coverage/core/api/services/organisations/organisations.hooks.js.html +0 -178
  297. package/coverage/core/api/services/organisations/organisations.service.js.html +0 -343
  298. package/coverage/core/api/services/push/index.html +0 -131
  299. package/coverage/core/api/services/push/push.hooks.js.html +0 -190
  300. package/coverage/core/api/services/push/push.service.js.html +0 -121
  301. package/coverage/core/api/services/storage/index.html +0 -131
  302. package/coverage/core/api/services/storage/storage.hooks.js.html +0 -190
  303. package/coverage/core/api/services/storage/storage.service.js.html +0 -172
  304. package/coverage/core/api/services/tags/index.html +0 -116
  305. package/coverage/core/api/services/tags/tags.hooks.js.html +0 -178
  306. package/coverage/core/api/services/users/index.html +0 -131
  307. package/coverage/core/api/services/users/users.hooks.js.html +0 -310
  308. package/coverage/core/api/services/users/users.service.js.html +0 -100
  309. package/coverage/core/api/utils.js.html +0 -118
  310. package/coverage/core/common/errors.js.html +0 -88
  311. package/coverage/core/common/index.html +0 -191
  312. package/coverage/core/common/index.js.html +0 -115
  313. package/coverage/core/common/permissions.js.html +0 -733
  314. package/coverage/core/common/schema.js.html +0 -190
  315. package/coverage/core/common/utils.js.html +0 -226
  316. package/coverage/core/common/utils.offline.js.html +0 -199
  317. package/coverage/favicon.png +0 -0
  318. package/coverage/index.html +0 -476
  319. package/coverage/lcov-report/base.css +0 -224
  320. package/coverage/lcov-report/block-navigation.js +0 -87
  321. package/coverage/lcov-report/core/api/application.js.html +0 -1870
  322. package/coverage/lcov-report/core/api/authentication.js.html +0 -874
  323. package/coverage/lcov-report/core/api/db.js.html +0 -793
  324. package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +0 -139
  325. package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +0 -958
  326. package/coverage/lcov-report/core/api/hooks/hooks.groups.js.html +0 -229
  327. package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +0 -163
  328. package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +0 -967
  329. package/coverage/lcov-report/core/api/hooks/hooks.organisations.js.html +0 -541
  330. package/coverage/lcov-report/core/api/hooks/hooks.push.js.html +0 -265
  331. package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +0 -862
  332. package/coverage/lcov-report/core/api/hooks/hooks.schemas.js.html +0 -298
  333. package/coverage/lcov-report/core/api/hooks/hooks.service.js.html +0 -319
  334. package/coverage/lcov-report/core/api/hooks/hooks.storage.js.html +0 -193
  335. package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +0 -595
  336. package/coverage/lcov-report/core/api/hooks/index.html +0 -266
  337. package/coverage/lcov-report/core/api/hooks/index.js.html +0 -115
  338. package/coverage/lcov-report/core/api/index.html +0 -176
  339. package/coverage/lcov-report/core/api/index.js.html +0 -148
  340. package/coverage/lcov-report/core/api/marshall.js.html +0 -448
  341. package/coverage/lcov-report/core/api/models/groups.model.mongodb.js.html +0 -109
  342. package/coverage/lcov-report/core/api/models/index.html +0 -131
  343. package/coverage/lcov-report/core/api/models/messages.model.mongodb.js.html +0 -121
  344. package/coverage/lcov-report/core/api/models/organisations.model.mongodb.js.html +0 -94
  345. package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +0 -115
  346. package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +0 -115
  347. package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +0 -208
  348. package/coverage/lcov-report/core/api/services/account/account.service.js.html +0 -436
  349. package/coverage/lcov-report/core/api/services/account/index.html +0 -131
  350. package/coverage/lcov-report/core/api/services/authorisations/authorisations.hooks.js.html +0 -184
  351. package/coverage/lcov-report/core/api/services/authorisations/authorisations.service.js.html +0 -520
  352. package/coverage/lcov-report/core/api/services/authorisations/index.html +0 -131
  353. package/coverage/lcov-report/core/api/services/databases/databases.hooks.js.html +0 -193
  354. package/coverage/lcov-report/core/api/services/databases/databases.service.js.html +0 -100
  355. package/coverage/lcov-report/core/api/services/databases/index.html +0 -131
  356. package/coverage/lcov-report/core/api/services/groups/groups.hooks.js.html +0 -178
  357. package/coverage/lcov-report/core/api/services/groups/index.html +0 -116
  358. package/coverage/lcov-report/core/api/services/import-export/import-export.hooks.js.html +0 -184
  359. package/coverage/lcov-report/core/api/services/import-export/import-export.service.js.html +0 -118
  360. package/coverage/lcov-report/core/api/services/import-export/index.html +0 -131
  361. package/coverage/lcov-report/core/api/services/index.html +0 -116
  362. package/coverage/lcov-report/core/api/services/index.js.html +0 -532
  363. package/coverage/lcov-report/core/api/services/mailer/index.html +0 -131
  364. package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +0 -190
  365. package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +0 -118
  366. package/coverage/lcov-report/core/api/services/messages/index.html +0 -116
  367. package/coverage/lcov-report/core/api/services/messages/messages.hooks.js.html +0 -202
  368. package/coverage/lcov-report/core/api/services/organisations/index.html +0 -131
  369. package/coverage/lcov-report/core/api/services/organisations/organisations.hooks.js.html +0 -178
  370. package/coverage/lcov-report/core/api/services/organisations/organisations.service.js.html +0 -343
  371. package/coverage/lcov-report/core/api/services/push/index.html +0 -131
  372. package/coverage/lcov-report/core/api/services/push/push.hooks.js.html +0 -190
  373. package/coverage/lcov-report/core/api/services/push/push.service.js.html +0 -121
  374. package/coverage/lcov-report/core/api/services/storage/index.html +0 -131
  375. package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +0 -190
  376. package/coverage/lcov-report/core/api/services/storage/storage.service.js.html +0 -172
  377. package/coverage/lcov-report/core/api/services/tags/index.html +0 -116
  378. package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +0 -178
  379. package/coverage/lcov-report/core/api/services/users/index.html +0 -131
  380. package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +0 -310
  381. package/coverage/lcov-report/core/api/services/users/users.service.js.html +0 -100
  382. package/coverage/lcov-report/core/api/utils.js.html +0 -118
  383. package/coverage/lcov-report/core/common/errors.js.html +0 -88
  384. package/coverage/lcov-report/core/common/index.html +0 -191
  385. package/coverage/lcov-report/core/common/index.js.html +0 -115
  386. package/coverage/lcov-report/core/common/permissions.js.html +0 -733
  387. package/coverage/lcov-report/core/common/schema.js.html +0 -190
  388. package/coverage/lcov-report/core/common/utils.js.html +0 -226
  389. package/coverage/lcov-report/core/common/utils.offline.js.html +0 -199
  390. package/coverage/lcov-report/favicon.png +0 -0
  391. package/coverage/lcov-report/index.html +0 -476
  392. package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +0 -553
  393. package/coverage/lcov-report/map/api/hooks/hooks.features.js.html +0 -397
  394. package/coverage/lcov-report/map/api/hooks/hooks.query.js.html +0 -1294
  395. package/coverage/lcov-report/map/api/hooks/index.html +0 -161
  396. package/coverage/lcov-report/map/api/hooks/index.js.html +0 -94
  397. package/coverage/lcov-report/map/api/index.html +0 -131
  398. package/coverage/lcov-report/map/api/index.js.html +0 -139
  399. package/coverage/lcov-report/map/api/marshall.js.html +0 -178
  400. package/coverage/lcov-report/map/api/models/alerts.model.mongodb.js.html +0 -106
  401. package/coverage/lcov-report/map/api/models/catalog.model.mongodb.js.html +0 -169
  402. package/coverage/lcov-report/map/api/models/features.model.mongodb.js.html +0 -196
  403. package/coverage/lcov-report/map/api/models/index.html +0 -176
  404. package/coverage/lcov-report/map/api/models/projects.model.mongodb.js.html +0 -109
  405. package/coverage/lcov-report/map/api/models/styles.model.mongodb.js.html +0 -112
  406. package/coverage/lcov-report/map/api/services/alerts/alerts.hooks.js.html +0 -274
  407. package/coverage/lcov-report/map/api/services/alerts/alerts.service.js.html +0 -610
  408. package/coverage/lcov-report/map/api/services/alerts/index.html +0 -131
  409. package/coverage/lcov-report/map/api/services/catalog/catalog.hooks.js.html +0 -328
  410. package/coverage/lcov-report/map/api/services/catalog/index.html +0 -116
  411. package/coverage/lcov-report/map/api/services/daptiles/daptiles.service.js.html +0 -1510
  412. package/coverage/lcov-report/map/api/services/daptiles/index.html +0 -116
  413. package/coverage/lcov-report/map/api/services/features/features.hooks.js.html +0 -310
  414. package/coverage/lcov-report/map/api/services/features/features.service.js.html +0 -544
  415. package/coverage/lcov-report/map/api/services/features/index.html +0 -131
  416. package/coverage/lcov-report/map/api/services/index.html +0 -116
  417. package/coverage/lcov-report/map/api/services/index.js.html +0 -1054
  418. package/coverage/lcov-report/map/api/services/projects/index.html +0 -116
  419. package/coverage/lcov-report/map/api/services/projects/projects.hooks.js.html +0 -439
  420. package/coverage/lcov-report/map/api/services/styles/index.html +0 -116
  421. package/coverage/lcov-report/map/api/services/styles/styles.hooks.js.html +0 -196
  422. package/coverage/lcov-report/map/common/dynamic-grid-source.js.html +0 -466
  423. package/coverage/lcov-report/map/common/errors.js.html +0 -94
  424. package/coverage/lcov-report/map/common/geotiff-grid-source.js.html +0 -544
  425. package/coverage/lcov-report/map/common/grid.js.html +0 -1612
  426. package/coverage/lcov-report/map/common/index.html +0 -371
  427. package/coverage/lcov-report/map/common/index.js.html +0 -172
  428. package/coverage/lcov-report/map/common/meteo-model-grid-source.js.html +0 -556
  429. package/coverage/lcov-report/map/common/moment-utils.js.html +0 -157
  430. package/coverage/lcov-report/map/common/opendap-grid-source.js.html +0 -868
  431. package/coverage/lcov-report/map/common/opendap-utils.js.html +0 -826
  432. package/coverage/lcov-report/map/common/permissions.js.html +0 -130
  433. package/coverage/lcov-report/map/common/time-based-grid-source.js.html +0 -418
  434. package/coverage/lcov-report/map/common/tms-utils.js.html +0 -274
  435. package/coverage/lcov-report/map/common/wcs-grid-source.js.html +0 -364
  436. package/coverage/lcov-report/map/common/wcs-utils.js.html +0 -586
  437. package/coverage/lcov-report/map/common/weacast-grid-source.js.html +0 -1033
  438. package/coverage/lcov-report/map/common/wfs-utils.js.html +0 -574
  439. package/coverage/lcov-report/map/common/wms-utils.js.html +0 -451
  440. package/coverage/lcov-report/map/common/wmts-utils.js.html +0 -547
  441. package/coverage/lcov-report/prettify.css +0 -1
  442. package/coverage/lcov-report/prettify.js +0 -2
  443. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  444. package/coverage/lcov-report/sorter.js +0 -196
  445. package/coverage/lcov.info +0 -11520
  446. package/coverage/map/api/hooks/hooks.catalog.js.html +0 -553
  447. package/coverage/map/api/hooks/hooks.features.js.html +0 -397
  448. package/coverage/map/api/hooks/hooks.query.js.html +0 -1294
  449. package/coverage/map/api/hooks/index.html +0 -161
  450. package/coverage/map/api/hooks/index.js.html +0 -94
  451. package/coverage/map/api/index.html +0 -131
  452. package/coverage/map/api/index.js.html +0 -139
  453. package/coverage/map/api/marshall.js.html +0 -178
  454. package/coverage/map/api/models/alerts.model.mongodb.js.html +0 -106
  455. package/coverage/map/api/models/catalog.model.mongodb.js.html +0 -169
  456. package/coverage/map/api/models/features.model.mongodb.js.html +0 -196
  457. package/coverage/map/api/models/index.html +0 -176
  458. package/coverage/map/api/models/projects.model.mongodb.js.html +0 -109
  459. package/coverage/map/api/models/styles.model.mongodb.js.html +0 -112
  460. package/coverage/map/api/services/alerts/alerts.hooks.js.html +0 -274
  461. package/coverage/map/api/services/alerts/alerts.service.js.html +0 -610
  462. package/coverage/map/api/services/alerts/index.html +0 -131
  463. package/coverage/map/api/services/catalog/catalog.hooks.js.html +0 -328
  464. package/coverage/map/api/services/catalog/index.html +0 -116
  465. package/coverage/map/api/services/daptiles/daptiles.service.js.html +0 -1510
  466. package/coverage/map/api/services/daptiles/index.html +0 -116
  467. package/coverage/map/api/services/features/features.hooks.js.html +0 -310
  468. package/coverage/map/api/services/features/features.service.js.html +0 -544
  469. package/coverage/map/api/services/features/index.html +0 -131
  470. package/coverage/map/api/services/index.html +0 -116
  471. package/coverage/map/api/services/index.js.html +0 -1054
  472. package/coverage/map/api/services/projects/index.html +0 -116
  473. package/coverage/map/api/services/projects/projects.hooks.js.html +0 -439
  474. package/coverage/map/api/services/styles/index.html +0 -116
  475. package/coverage/map/api/services/styles/styles.hooks.js.html +0 -196
  476. package/coverage/map/common/dynamic-grid-source.js.html +0 -466
  477. package/coverage/map/common/errors.js.html +0 -94
  478. package/coverage/map/common/geotiff-grid-source.js.html +0 -544
  479. package/coverage/map/common/grid.js.html +0 -1612
  480. package/coverage/map/common/index.html +0 -371
  481. package/coverage/map/common/index.js.html +0 -172
  482. package/coverage/map/common/meteo-model-grid-source.js.html +0 -556
  483. package/coverage/map/common/moment-utils.js.html +0 -157
  484. package/coverage/map/common/opendap-grid-source.js.html +0 -868
  485. package/coverage/map/common/opendap-utils.js.html +0 -826
  486. package/coverage/map/common/permissions.js.html +0 -130
  487. package/coverage/map/common/time-based-grid-source.js.html +0 -418
  488. package/coverage/map/common/tms-utils.js.html +0 -274
  489. package/coverage/map/common/wcs-grid-source.js.html +0 -364
  490. package/coverage/map/common/wcs-utils.js.html +0 -586
  491. package/coverage/map/common/weacast-grid-source.js.html +0 -1033
  492. package/coverage/map/common/wfs-utils.js.html +0 -574
  493. package/coverage/map/common/wms-utils.js.html +0 -451
  494. package/coverage/map/common/wmts-utils.js.html +0 -547
  495. package/coverage/prettify.css +0 -1
  496. package/coverage/prettify.js +0 -2
  497. package/coverage/sort-arrow-sprite.png +0 -0
  498. package/coverage/sorter.js +0 -196
  499. package/coverage/tmp/coverage-151198-1753351220086-0.json +0 -1
  500. package/coverage/tmp/coverage-151210-1753351220070-0.json +0 -1
  501. package/coverage/tmp/coverage-151221-1753351129816-0.json +0 -1
  502. package/coverage/tmp/coverage-151233-1753351129803-0.json +0 -1
  503. package/coverage/tmp/coverage-151240-1753351129770-0.json +0 -1
  504. package/coverage/tmp/coverage-151307-1753351220058-0.json +0 -1
  505. package/coverage/tmp/coverage-151319-1753351220044-0.json +0 -1
  506. package/coverage/tmp/coverage-151326-1753351220010-0.json +0 -1
  507. package/extras/tours/core/account-profile.js +0 -32
  508. package/extras/tours/core/account.js +0 -143
  509. package/extras/tours/core/add-member.js +0 -75
  510. package/extras/tours/core/add-tag.js +0 -13
  511. package/extras/tours/core/create-group.js +0 -19
  512. package/extras/tours/core/create-organisation.js +0 -19
  513. package/extras/tours/core/create-tag.js +0 -26
  514. package/extras/tours/core/edit-member-role.js +0 -13
  515. package/extras/tours/core/groups.js +0 -65
  516. package/extras/tours/core/join-group.js +0 -13
  517. package/extras/tours/core/login.js +0 -41
  518. package/extras/tours/core/members.js +0 -108
  519. package/extras/tours/core/register.js +0 -61
  520. package/extras/tours/core/send-reset-password.js +0 -14
  521. package/extras/tours/core/tags.js +0 -65
  522. package/extras/tours/map/catalog-panel.js +0 -112
  523. package/extras/tours/map/fab.js +0 -26
  524. package/extras/tours/map/navigation-bar.js +0 -187
  525. package/extras/tours/map/side-nav.js +0 -36
  526. package/test/api/core/test-log-2025-02-05.log +0 -23
  527. package/test/api/core/test-log-2025-05-21.log +0 -15
  528. package/test/api/core/test-log-2025-06-25.log +0 -9
  529. package/test/api/core/test-log-2025-07-24.log +0 -44
  530. package/test/api/map/test-log-2025-05-27.log +0 -13
  531. package/test/api/map/test-log-2025-06-23.log +0 -7
  532. package/test/api/map/test-log-2025-07-24.log +0 -11
  533. package/test/client/core/api.js +0 -361
  534. package/test/client/core/index.js +0 -9
  535. package/test/client/index.js +0 -4
  536. package/test/client/map/index.js +0 -5
  537. package/test.client.js +0 -1
  538. /package/{test/client/core/time.js → extras/tests/core/time.mjs} +0 -0
  539. /package/extras/tours/{map/add-layer.js → add-layer.js} +0 -0
  540. /package/extras/tours/{map/catalog-categories.js → catalog-categories.js} +0 -0
  541. /package/extras/tours/{map/connect-layer.js → connect-layer.js} +0 -0
  542. /package/extras/tours/{map/create-layer.js → create-layer.js} +0 -0
  543. /package/extras/tours/{map/create-view.js → create-view.js} +0 -0
  544. /package/extras/tours/{map/import-layer.js → import-layer.js} +0 -0
  545. /package/extras/tours/{map/timeline.js → pane.bottom.js} +0 -0
@@ -1,5 +1,6 @@
1
1
  import _ from 'lodash'
2
2
  import moment from 'moment'
3
+ import { Entity } from 'cesium'
3
4
  import { Time, Units } from '../../../../core/client/index.js'
4
5
 
5
6
  export const tooltip = {
@@ -7,15 +8,26 @@ export const tooltip = {
7
8
  applyTooltips (entities, options) {
8
9
  for (let i = 0; i < entities.values.length; i++) {
9
10
  const entity = entities.values[i]
11
+ // Get any previous tooltip entity
12
+ const previousTooltipEntity = this.getChildForEntity(entity)
10
13
  const tooltip = this.generateStyle('tooltip', entity, options)
11
14
  if (tooltip) {
12
15
  // Default tooltip position (can change in sticky mode)
13
16
  const position = this.getPositionForEntity(entity)
14
17
  if (position) {
15
- const tooltipEntity = this.viewer.entities.add({ parent: entity, position, label: tooltip })
18
+ const tooltipEntity = new Entity({ parent: entity, position, label: tooltip })
16
19
  // This option is not cesium specific so we have to manage it manually
17
- if (tooltip.sticky) tooltipEntity.sticky = true
20
+ tooltipEntity.sticky = true
21
+ if (!previousTooltipEntity) {
22
+ this.viewer.entities.add(tooltipEntity)
23
+ } else {
24
+ previousTooltipEntity.position = tooltipEntity.position
25
+ previousTooltipEntity.label = tooltipEntity.label
26
+ tooltipEntity.parent = null
27
+ }
18
28
  }
29
+ } else if (previousTooltipEntity) {
30
+ this.viewer.entities.remove(previousTooltipEntity)
19
31
  }
20
32
  }
21
33
  },
@@ -2,16 +2,13 @@ import _ from 'lodash'
2
2
  import sift from 'sift'
3
3
  import logger from 'loglevel'
4
4
  import moment from 'moment'
5
- import L from 'leaflet'
6
- import Emitter from 'tiny-emitter'
5
+ import { EventBus } from 'quasar'
7
6
  import { point, rhumbDistance, rhumbBearing, rhumbDestination } from '@turf/turf'
7
+ import L from 'leaflet'
8
8
  import 'leaflet/dist/leaflet.css'
9
9
  // This ensure we have all required plugins
10
10
  import 'leaflet-fullscreen'
11
11
  import 'leaflet-fullscreen/dist/leaflet.fullscreen.css'
12
- import 'leaflet.markercluster/dist/MarkerCluster.css'
13
- import 'leaflet.markercluster/dist/MarkerCluster.Default.css'
14
- import 'leaflet.markercluster'
15
12
  import '@kalisio/leaflet.donutcluster/src/Leaflet.DonutCluster.css'
16
13
  import '@kalisio/leaflet.donutcluster'
17
14
  import 'leaflet.vectorgrid/dist/Leaflet.VectorGrid.bundled.js'
@@ -27,12 +24,14 @@ import 'leaflet-timedimension/dist/leaflet.timedimension.control.css'
27
24
  import '@geoman-io/leaflet-geoman-free'
28
25
  import '@geoman-io/leaflet-geoman-free/dist/leaflet-geoman.css'
29
26
  import 'leaflet-rotate/dist/leaflet-rotate-src.js'
27
+
30
28
  import { Time } from '../../../../core/client/time.js'
31
- import { getAppLocale } from '../../../../core/client/utils/index.js'
29
+ import { Events } from '../../../../core/client/events.js'
30
+ import { getLocale } from '../../../../core/client/utils/index.js'
32
31
  import '../../leaflet/BoxSelection.js'
33
32
  import '../../leaflet/WindBarb.js'
34
33
  import { Geolocation } from '../../geolocation.js'
35
- import { LeafletEvents, TouchEvents, bindLeafletEvents } from '../../utils.map.js' // https://github.com/socib/Leaflet.TimeDimension/issues/124
34
+ import { LeafletEvents, TouchEvents, bindLeafletEvents, getNearestTime } from '../../utils.map.js' // https://github.com/socib/Leaflet.TimeDimension/issues/124
36
35
  import { generateLayerDefinition } from '../../utils/utils.layers.js'
37
36
  import * as maths from '../../../../core/client/utils/utils.math.js'
38
37
 
@@ -117,7 +116,7 @@ export const baseMap = {
117
116
  if (this.map.pm === undefined) {
118
117
  this.map.options.pmIgnore = false
119
118
  L.PM.reInitLayer(this.map)
120
- this.map.pm.setLang(getAppLocale())
119
+ this.map.pm.setLang(getLocale())
121
120
  }
122
121
  // Leaflet does not really manage touch events, it provides compatibility mapping with mouse events
123
122
  // but it will not really trigger touch event from the map object, as a consequence we manage this by ourselves
@@ -331,30 +330,35 @@ export const baseMap = {
331
330
  })
332
331
  },
333
332
  createLeafletLayer (options) {
333
+ const name = options.name
334
334
  const leafletOptions = options.leaflet || options
335
- // Manage panes to make z-index work for all types of layers
335
+ // Manage panes to make z-index work for all types of layers.
336
336
  // Indeed, although DOM-based layers can use setZIndex() to manage rendering order
337
- // SVG/Canvas-based layers provide no mean to manage render order except using bringToFront() or bringToBack()
337
+ // SVG/Canvas-based layers provide no mean to manage render order except using bringToFront() or bringToBack().
338
338
  // This is why Leaflet 1.0 introduced panes: https://leafletjs.com/reference.html#map-pane & https://leafletjs.com/examples/map-panes/
339
- // By implicitely create a pane for each provided z-index makes this transparent for the user
340
- let zIndex = _.has(leafletOptions, 'zIndex')
341
- let pane = _.has(leafletOptions, 'pane')
342
- // Avoid erasing any existing pane, if so the pane should have been created taken into account the layer zIndex up-front
343
- if (zIndex && !pane) {
344
- zIndex = _.get(leafletOptions, 'zIndex')
345
- this.createLeafletPane(zIndex)
346
- // Set layer to use target pane
347
- _.set(leafletOptions, 'pane', zIndex.toString())
339
+ // By implicitely create a pane for each provided z-index makes this transparent for the user.
340
+ const layerPane = { name }
341
+ const hasMinZoom = !!_.get(leafletOptions, 'minZoom')
342
+ const hasMaxZoom = !!_.get(leafletOptions, 'maxZoom')
343
+ const hasZIndex = !!_.get(leafletOptions, 'zIndex')
344
+ if (hasMinZoom) layerPane.minZoom = _.get(leafletOptions, 'minZoom')
345
+ if (hasMaxZoom) layerPane.maxZoom = _.get(leafletOptions, 'maxZoom')
346
+ if (hasZIndex) layerPane.zIndex = _.get(leafletOptions, 'zIndex')
347
+ if (hasZIndex) {
348
+ this.createLeafletPane(layerPane)
349
+ // Set layer to use its default pane as target
350
+ // Avoid erasing any existing pane, if so the pane should have been created taken into account the layer zIndex up-front
351
+ if (!_.has(leafletOptions, 'pane')) _.set(leafletOptions, 'pane', layerPane.name)
348
352
  }
349
353
  // Different panes inside a layer can be used to manage visibility according to zoom level
350
- const panes = _.get(leafletOptions, 'panes')
354
+ const panes = _.get(leafletOptions, 'panes', [])
351
355
  if (panes) {
352
356
  panes.forEach(paneOptions => {
353
357
  const pane = this.createLeafletPane(paneOptions)
354
358
  Object.assign(pane, paneOptions)
355
359
  })
356
- this.updateLeafletPanesVisibility()
357
360
  }
361
+ this.updateLeafletPanesVisibility()
358
362
 
359
363
  // Some Leaflet constructors can have additional arguments given as options
360
364
  let args = _.get(leafletOptions, 'options', [])
@@ -402,7 +406,14 @@ export const baseMap = {
402
406
  _.set(timeDimension, 'period', 'P1D')
403
407
  const timeRange = _.get(timeDimension, 'times')
404
408
  const timeRangeComponents = (typeof timeRange === 'string' ? timeRange.split('/') : [])
405
- if (timeRangeComponents.length === 2) {
409
+ const timeList = (typeof timeRange === 'string' ? timeRange.split(',') : [])
410
+ let times = [] // Time list as moment objects to ease search
411
+ if (!_.isEmpty(timeList)) {
412
+ // In this case there is no period as time list should be ISO
413
+ _.unset(timeDimension, 'period')
414
+ // Convert to moment objects
415
+ times = _.sortBy(timeList.map(time => moment.utc(time)), (time) => time.valueOf())
416
+ } else if (timeRangeComponents.length === 2) {
406
417
  _.set(timeDimension, 'times', `${timeRange}/P1D`)
407
418
  } else if (timeRangeComponents.length === 3) {
408
419
  _.set(timeDimension, 'period', timeRangeComponents[2])
@@ -417,16 +428,30 @@ export const baseMap = {
417
428
  currentTime: Time.getCurrentTime().toDate().getTime()
418
429
  })
419
430
  // This allow the layer to conform our internal time interface
420
- layer.setCurrentTime = (datetime) => { layer._timeDimension.setCurrentTime(datetime.toDate().getTime()) }
431
+ layer.setCurrentTime = (datetime) => {
432
+ layer._timeDimension.setCurrentTime(datetime.toDate().getTime())
433
+ }
421
434
  // Default implementation always generate ISO datetime that might break some servers with eg day period only
422
435
  layer._createLayerForTime = (time) => {
436
+ time = moment.utc(time)
423
437
  // Remove some internals to avoid polluting request
424
438
  const wmsParams = _.omit(layer._baseLayer.options, ['timeDimension', 'isVisible', 'type'])
425
439
  // Format time according to period
426
- if (periodAsDuration.years() > 0) wmsParams.time = moment.utc(time).format('YYYY').toISOString()
427
- else if (periodAsDuration.months() > 0) wmsParams.time = moment.utc(time).format('YYYY-MM')
428
- else if (periodAsDuration.days() > 0) wmsParams.time = moment.utc(time).format('YYYY-MM-DD')
429
- else wmsParams.time = moment.utc(time).toISOString()
440
+ if (periodAsDuration.years() > 0) {
441
+ wmsParams.time = time.format('YYYY').toISOString()
442
+ } else if (periodAsDuration.months() > 0) {
443
+ wmsParams.time = time.format('YYYY-MM')
444
+ } else if (periodAsDuration.days() > 0) {
445
+ wmsParams.time = time.format('YYYY-MM-DD')
446
+ } else if (!_.isEmpty(times)) {
447
+ // Find nearest available time, as we keep the list ordered it could use a faster algorithm in utility function
448
+ const { index, difference } = getNearestTime(time, times, true)
449
+ // Keep original time format in any case it is not ISO
450
+ if (index >= 0) wmsParams.time = timeList[index]
451
+ else wmsParams.time = time.toISOString()
452
+ } else {
453
+ wmsParams.time = time.toISOString()
454
+ }
430
455
  // Some Leaflet constructors can have additional arguments given as options
431
456
  let args = _.get(leafletOptions, 'options', [])
432
457
  // Can be an array or a single object for a single additonnal argument
@@ -506,8 +531,6 @@ export const baseMap = {
506
531
  this.map.addLayer(leafletLayer)
507
532
  layer.isVisible = true
508
533
 
509
- // Ensure base layer will not pop on top of others
510
- if (layer.type === 'BaseLayer') leafletLayer.bringToBack()
511
534
  // Apply the current time if needed
512
535
  if (typeof leafletLayer.setCurrentTime === 'function') leafletLayer.setCurrentTime(Time.getCurrentTime())
513
536
  this.onLayerShown(layer, leafletLayer)
@@ -551,15 +574,17 @@ export const baseMap = {
551
574
  this.$emit('layer-added', layer)
552
575
  this.$engineEvents.emit('layer-added', layer)
553
576
  },
554
- async addGeoJsonLayer (layerSpec, geoJson) {
577
+ async addGeoJsonLayer (layerSpec, geoJson, zoom = true) {
555
578
  if (!generateLayerDefinition(layerSpec, geoJson)) return
556
579
  // Create an empty layer used as a container
557
580
  await this.addLayer(layerSpec)
558
581
  // Set the content
559
582
  await this.updateLayer(layerSpec.name, geoJson)
560
- // Zoom to it
561
- if (geoJson.bbox) this.zoomToBBox(geoJson.bbox)
562
- else this.zoomToLayer(layerSpec.name)
583
+ // Zoom to the layer
584
+ if (zoom) {
585
+ if (geoJson.bbox) this.zoomToBBox(geoJson.bbox)
586
+ else this.zoomToLayer(layerSpec.name)
587
+ }
563
588
  },
564
589
  renameLayer (previousName, newName) {
565
590
  const layer = this.getLayerByName(previousName)
@@ -637,41 +662,98 @@ export const baseMap = {
637
662
  zoomToBBox (bbox) {
638
663
  this.zoomToBounds([[bbox[1], bbox[0]], [bbox[3], bbox[2]]])
639
664
  },
665
+ bringLayerToFront (name) {
666
+ let leafletLayer = this.getLeafletLayerByName(name)
667
+ if (!leafletLayer) return
668
+ // If panes are declared on this layer push it front to make it on top of others should be sufficient.
669
+ const panes = _.get(leafletLayer, 'options.panes')
670
+ if (panes) {
671
+ panes.forEach(paneOptions => {
672
+ const pane = this.getLeafletPaneByName(this.getLeafletPaneName(paneOptions))
673
+ if (pane) L.DomUtil.toFront(pane)
674
+ })
675
+ return
676
+ }
677
+ // Handle case where there's clustering on top (cf. updateLayer)
678
+ if (leafletLayer instanceof L.MarkerClusterGroup) {
679
+ const container = leafletLayer
680
+ leafletLayer = leafletLayer.getLayers().find(layer => layer._container === container)
681
+ }
682
+ if (leafletLayer && (typeof leafletLayer.bringToFront === 'function')) leafletLayer.bringToFront()
683
+ },
684
+ bringLayerToBack (name) {
685
+ let leafletLayer = this.getLeafletLayerByName(name)
686
+ if (!leafletLayer) return
687
+ // If panes are declared on this layer push it back to make it under others should be sufficient.
688
+ const panes = _.get(leafletLayer, 'options.panes')
689
+ if (panes) {
690
+ panes.forEach(paneOptions => {
691
+ const pane = this.getLeafletPaneByName(this.getLeafletPaneName(paneOptions))
692
+ if (pane) L.DomUtil.toBack(pane)
693
+ })
694
+ return
695
+ }
696
+ // Handle case where there's clustering on top (cf. updateLayer)
697
+ if (leafletLayer instanceof L.MarkerClusterGroup) {
698
+ const container = leafletLayer
699
+ leafletLayer = leafletLayer.getLayers().find(layer => layer._container === container)
700
+ }
701
+ if (leafletLayer && (typeof leafletLayer.bringToBack === 'function')) leafletLayer.bringToBack()
702
+ },
640
703
  animateCenter (timestamp) {
704
+ // Note: as this callback is called frequently by the animation system
705
+ // we don't use lodash utility functions like _.get/_.set to improve performances
706
+
641
707
  // Initialize animation time origin
642
708
  if (!this.centerAnimation.startTime) this.centerAnimation.startTime = timestamp
643
- const { id, duration, startTime,
709
+ const { id, duration, startTime, fps,
644
710
  animate: { center, zoom, bearing },
645
711
  startLongitude, endLatitude, startLatitude, startZoom, startBearing,
646
712
  endLongitude, endZoom, endBearing } = this.centerAnimation
647
- const elapsed = timestamp - startTime
648
- const percent = Math.abs(elapsed / (1000 * duration))
713
+ const elapsedSinceStart = timestamp - startTime
714
+ // If we target a specific frame rate check if we need to update or not
715
+ if (fps && this.centerAnimation.lastTime) {
716
+ const elapsedSinceLastFrame = timestamp - this.centerAnimation.lastTime
717
+ const fpsInterval = 1000 / fps
718
+ if (elapsedSinceLastFrame < fpsInterval) {
719
+ this.centerAnimation.id = requestAnimationFrame(this.animateCenter)
720
+ // For debug purpose only, avoid flooding the browser
721
+ //logger.debug('[KDK] Skipping center animation frame')
722
+ return
723
+ } else {
724
+ // For debug purpose only, avoid flooding the browser
725
+ //logger.debug('[KDK] Drawing center animation frame')
726
+ }
727
+ }
728
+ // Else animate if animation not yet finished
729
+ const percent = Math.abs(elapsedSinceStart / (1000 * duration))
649
730
  let percentCenter, percentZoom, percentBearing
650
731
  if (percent <= 1) {
651
732
  const currentCenter = this.getCenter()
652
733
  if (center) {
653
- const easingCenterFunction = _.get(center, 'easing.function')
654
- const easingCenterParameters = _.get(center, 'easing.parameters', [])
734
+ const easingCenterFunction = center.easing.function
735
+ const easingCenterParameters = center.easing.parameters || []
655
736
  percentCenter = maths[easingCenterFunction](percent, ...easingCenterParameters)
656
737
  }
657
738
  if (zoom) {
658
- const easingZoomFunction = _.get(zoom, 'easing.function')
659
- const easingZoomParameters = _.get(zoom, 'easing.parameters', [])
739
+ const easingZoomFunction = zoom.easing.function
740
+ const easingZoomParameters = zoom.easing.parameters || []
660
741
  percentZoom = maths[easingZoomFunction](percent, ...easingZoomParameters)
661
742
  }
662
743
  if (bearing) {
663
- const easingBearingFunction = _.get(bearing, 'easing.function')
664
- const easingBearingParameters = _.get(bearing, 'easing.parameters', [])
744
+ const easingBearingFunction = bearing.easing.function
745
+ const easingBearingParameters = bearing.easing.parameters || []
665
746
  percentBearing = maths[easingBearingFunction](percent, ...easingBearingParameters)
666
747
  }
667
- const dx = (center ? percentCenter * _.get(this.centerAnimation, 'offset.x', 0) : 0)
668
- const dy = (center ? percentCenter * _.get(this.centerAnimation, 'offset.y', 0) : 0)
748
+ const offset = this.centerAnimation.offset
749
+ const dx = (center && offset ? percentCenter * offset.x || 0 : 0)
750
+ const dy = (center && offset ? percentCenter * offset.y || 0 : 0)
669
751
  let dLongitude = currentCenter.longitude, dLatitude = currentCenter.latitude
670
752
  if (center) {
671
753
  if (center.rhumb) {
672
754
  const destination = rhumbDestination(this.centerAnimation.rhumbStart, percentCenter * this.centerAnimation.rhumbDistance, this.centerAnimation.rhumbBearing)
673
- dLongitude = _.get(destination, 'geometry.coordinates[0]')
674
- dLatitude = _.get(destination, 'geometry.coordinates[1]')
755
+ dLongitude = destination.geometry.coordinates[0]
756
+ dLatitude = destination.geometry.coordinates[1]
675
757
  } else {
676
758
  dLongitude = startLongitude + percentCenter * (endLongitude - startLongitude)
677
759
  dLatitude = startLatitude + percentCenter * (endLatitude - startLatitude)
@@ -686,7 +768,8 @@ export const baseMap = {
686
768
  // Then normalize the final result to be between 0 and 360
687
769
  dBearing = (bearing ? (startBearing + percentBearing * bearingDifference + 360) % 360 : null)
688
770
  }
689
- this.center(dLongitude, dLatitude, dZoom, dBearing, { offset: { x: Math.round(dx), y: Math.round(dy) } })
771
+ this.center(dLongitude, dLatitude, dZoom, dBearing, { offset: { x: Math.round(dx), y: Math.round(dy) }, bearingTolerance: this.centerAnimation.bearingTolerance })
772
+ this.centerAnimation.lastTime = timestamp
690
773
  this.centerAnimation.id = requestAnimationFrame(this.animateCenter)
691
774
  } else {
692
775
  this.centerAnimation.id = null
@@ -698,14 +781,15 @@ export const baseMap = {
698
781
  if (_.isNil(bearing)) bearing = this.map.getBearing()
699
782
  // Keep bearing positive, required for interpolation to work correctly
700
783
  if (bearing < 0) bearing += 360
701
-
702
784
  const duration = _.get(options, 'duration', 0)
703
785
  if (duration) {
786
+ // For debug purpose only, avoid flooding the browser
787
+ //logger.debug('Calling center() with', longitude, latitude, options)
704
788
  _.defaultsDeep(options, {
705
789
  animate: {
706
- center: { easing: { function: 'cubicBezier' }, rhumb: true },
707
- zoom: { easing: { function: 'cubicBezier' } },
708
- bearing: { easing: { function: 'cubicBezier' } }
790
+ center: { easing: { function: 'linear' }, rhumb: false },
791
+ zoom: { easing: { function: 'linear' } },
792
+ bearing: { easing: { function: 'linear' } }
709
793
  }
710
794
  })
711
795
  // Leaflet rotate does not manage animation so that we cannot rely on Leaflet built-in animation
@@ -729,13 +813,13 @@ export const baseMap = {
729
813
  }
730
814
  if (typeof this.map.getBearing === 'function') {
731
815
  Object.assign(this.centerAnimation, {
732
- startBearing: this.getBearing(),
816
+ startBearing: this.map.getBearing(),
733
817
  endBearing: bearing
734
818
  })
735
819
  }
736
820
  } else {
737
- if (typeof this.map.getBearing === 'function') {
738
- this.setBearing(bearing, offset)
821
+ if (typeof this.map.setBearing === 'function') {
822
+ this.setBearing(bearing, options)
739
823
  }
740
824
  this.map.setView(new L.LatLng(latitude, longitude), zoomLevel, { animate: false, duration: 0 })
741
825
  this.map.panBy(offset, { animate: false, duration: 0 })
@@ -756,7 +840,11 @@ export const baseMap = {
756
840
  return
757
841
  }
758
842
  const offset = L.point(_.get(options, 'offset.x', 0), _.get(options, 'offset.y', 0))
759
- this.map.setBearing(bearing, offset)
843
+ // As rotating is costly by default we don't really rotate unless the human eye is able to perceive it
844
+ const tolerance = _.get(options, 'bearingTolerance', 0.1)
845
+ if (Math.abs(this.map.getBearing() - bearing) >= tolerance) {
846
+ this.map.setBearing(bearing, offset)
847
+ }
760
848
  },
761
849
  getBearing () {
762
850
  if (typeof this.map.getBearing !== 'function') {
@@ -843,15 +931,15 @@ export const baseMap = {
843
931
  // Register support for WMS-T
844
932
  this.registerLeafletConstructor(this.createLeafletTimedWmsLayer)
845
933
  // Internal event bus
846
- this.$engineEvents = new Emitter()
934
+ this.$engineEvents = new EventBus()
847
935
  this.$engineEvents.on('zoomend', this.onMapZoomChanged)
848
- this.$events.on('time-current-time-changed', this.onCurrentMapTimeChanged)
936
+ Events.on('time-current-time-changed', this.onCurrentMapTimeChanged)
849
937
  },
850
938
  beforeUnmount () {
851
939
  this.clearLayers()
852
940
  L.DomEvent.off(this.map._container, TouchEvents.join(' '), this.onTouchEvent, this)
853
941
  this.$engineEvents.off('zoomend', this.onMapZoomChanged)
854
- this.$events.off('time-current-time-changed', this.onCurrentMapTimeChanged)
942
+ Events.off('time-current-time-changed', this.onCurrentMapTimeChanged)
855
943
  },
856
944
  unmounted () {
857
945
  if (this.map) {
@@ -5,8 +5,9 @@ import { getType, getCoords, getGeom } from '@turf/invariant'
5
5
  import { uid } from 'quasar'
6
6
  import { Store } from '../../../../core/client/store.js'
7
7
  import { Units } from '../../../../core/client/units.js'
8
+ import { api } from '../../../../core/client/api.js'
8
9
  import {
9
- bindLeafletEvents, unbindLeafletEvents,
10
+ getGeoJsonFeatures, bindLeafletEvents, unbindLeafletEvents,
10
11
  getDefaultPointStyle, getDefaultLineStyle, getDefaultPolygonStyle, createMarkerFromPointStyle,
11
12
  convertSimpleStyleToPointStyle, convertSimpleStyleToLineStyle, convertSimpleStyleToPolygonStyle,
12
13
  formatUserCoordinates, getFeatureId, listenToFeaturesServiceEventsForLayer, unlistenToFeaturesServiceEventsForLayer
@@ -46,7 +47,7 @@ export const editLayers = {
46
47
  if (this.editedPopup) this.editedFeature.bindPopup(this.editedPopup)
47
48
  // Update feature after edition from DB or memory
48
49
  const service = (this.editedLayer._id ? _.get(this.editedLayer, 'service', 'features') : 'features-edition')
49
- const feature = await this.$api.getService(service).get(this.editedFeature.feature._id)
50
+ const feature = await api.getService(service).get(this.editedFeature.feature._id)
50
51
  this.editableLayer.removeLayer(this.editedFeature)
51
52
  this.editableLayer.addData(feature)
52
53
  this.editedPopup = null
@@ -56,7 +57,9 @@ export const editLayers = {
56
57
  },
57
58
  methods: {
58
59
  isLayerEdited (layer) {
59
- return this.editedLayer && (this.editedLayer.name === layer.name)
60
+ if (!this.editedLayer) return false
61
+ if (this.editedLayer._id && layer._id) return (this.editedLayer._id === layer._id)
62
+ else return (this.editedLayer.name === layer.name)
60
63
  },
61
64
  getGeoJsonEditOptions (options, geometryTypes) {
62
65
  let filteredOptions = options
@@ -87,20 +90,20 @@ export const editLayers = {
87
90
  if (isLine) {
88
91
  // Skip line editing style if not editing lines
89
92
  if (!_.isEmpty(geometryTypes) && !geometryTypes.includes('LineString') && !geometryTypes.includes('MultiLineString')) return style(feature)
90
- else return getDefaultLineStyle(feature, layerStyle, _.get(this, 'activityOptions.engine'), 'style.edition.line')
93
+ else return getDefaultLineStyle(feature, layerStyle, _.get(this, 'activityOptions.engine.style.edition.line'))
91
94
  }
92
95
  const isPolygon = ((feature.geometry.type === 'Polygon') || (feature.geometry.type === 'MultiPolygon'))
93
96
  if (isPolygon) {
94
97
  // Skip polygon editing style if not editing polygons
95
98
  if (!_.isEmpty(geometryTypes) && !geometryTypes.includes('Polygon') && !geometryTypes.includes('MultiPolygon')) return style(feature)
96
- else return getDefaultPolygonStyle(feature, layerStyle, _.get(this, 'activityOptions.engine'), 'style.edition.polygon')
99
+ else return getDefaultPolygonStyle(feature, layerStyle, _.get(this, 'activityOptions.engine.style.edition.polygon'))
97
100
  }
98
101
  logger.warn(`[KDK] the geometry of type of ${feature.geometry.type} is not supported`)
99
102
  },
100
103
  pointToLayer: (feature, latlng) => {
101
104
  // Skip point editing style if not editing points
102
105
  if (!_.isEmpty(geometryTypes) && !geometryTypes.includes('Point') && !geometryTypes.includes('MultiPoint')) return pointToLayer(feature, layer)
103
- const style = getDefaultPointStyle(feature, layerStyle, _.get(this, 'activityOptions.engine'), 'style.edition.point')
106
+ const style = getDefaultPointStyle(feature, layerStyle, _.get(this, 'activityOptions.engine.style.edition.point'))
104
107
  style.options = { pmIgnore: false } // Allow geoman edition
105
108
  return createMarkerFromPointStyle(latlng, style)
106
109
  }
@@ -194,7 +197,7 @@ export const editLayers = {
194
197
  // Move source layers to edition layers, required as eg clusters are not supported
195
198
  // and also to manage partial edition of large datasets
196
199
  const geoJson = leafletLayer.toGeoJSON()
197
- let editedFeatures = geoJson.type === 'FeatureCollection' ? geoJson.features : [geoJson]
200
+ let editedFeatures = getGeoJsonFeatures(geoJson)
198
201
  if (_.isEmpty(features) && _.isEmpty(geometryTypes)) {
199
202
  leafletLayer.clearLayers()
200
203
  } else if (!_.isEmpty(features)) {
@@ -218,7 +221,7 @@ export const editLayers = {
218
221
  // Generate in memory service _id as string to match what's done with mongo
219
222
  feature._id = uid().toString()
220
223
  // Service will use the provided _id as object key
221
- await this.$api.getService('features-edition').create(feature)
224
+ await api.getService('features-edition').create(feature)
222
225
  }
223
226
  } else {
224
227
  // Listen to layer changes
@@ -290,8 +293,8 @@ export const editLayers = {
290
293
  // for in memory edition, clear service
291
294
  if (this.editedLayer._id === undefined) {
292
295
  const geoJson = this.editableLayer.toGeoJSON()
293
- const features = geoJson.type === 'FeatureCollection' ? geoJson.features : [geoJson]
294
- const service = this.$api.getService('features-edition')
296
+ const features = getGeoJsonFeatures(geoJson)
297
+ const service = api.getService('features-edition')
295
298
  await Promise.all(features.map((f) => service.remove(f._id)))
296
299
  } else {
297
300
  // Clear listeners to layer changes
@@ -424,7 +427,7 @@ export const editLayers = {
424
427
  // Generate in memory service _id as string to match what's done with mongo
425
428
  geoJson._id = idValue
426
429
  // Service will use the provided _id as object key
427
- await this.$api.getService('features-edition').create(geoJson)
430
+ await api.getService('features-edition').create(geoJson)
428
431
  }
429
432
  this.editableLayer.removeLayer(leafletLayer)
430
433
  this.editableLayer.addData(geoJson)
@@ -443,8 +446,8 @@ export const editLayers = {
443
446
  if (this.editedLayer._id) {
444
447
  await this.editFeaturesGeometry(geoJson, this.editedLayer)
445
448
  } else {
446
- const features = geoJson.type === 'FeatureCollection' ? geoJson.features : [geoJson]
447
- const service = this.$api.getService('features-edition')
449
+ const features = getGeoJsonFeatures(geoJson)
450
+ const service = api.getService('features-edition')
448
451
  // Remember those operations because we need to make sure we wait for completion
449
452
  // before clearing the in memory edition service in stopEditLayer
450
453
  const operations = Promise.all(features.map((f) => service.patch(f._id, { geometry: f.geometry })))
@@ -471,8 +474,8 @@ export const editLayers = {
471
474
  if (this.editedLayer._id) {
472
475
  await this.removeFeatures(geoJson, this.editedLayer)
473
476
  } else {
474
- const features = geoJson.type === 'FeatureCollection' ? geoJson.features : [geoJson]
475
- const service = this.$api.getService('features-edition')
477
+ const features = getGeoJsonFeatures(geoJson)
478
+ const service = api.getService('features-edition')
476
479
  await Promise.all(features.map((f) => service.remove(f._id)))
477
480
  }
478
481
  },