@kalisio/kdk 2.6.4 → 2.7.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 (398) hide show
  1. package/core/api/application.js +2 -4
  2. package/core/api/authentication.js +2 -3
  3. package/core/api/db.js +10 -2
  4. package/core/api/hooks/hooks.authorisations.js +4 -2
  5. package/core/api/hooks/hooks.push.js +6 -2
  6. package/core/api/hooks/hooks.query.js +29 -12
  7. package/core/api/hooks/hooks.users.js +30 -17
  8. package/core/api/models/configurations.model.mongodb.js +4 -0
  9. package/core/api/services/authorisations/authorisations.service.js +1 -1
  10. package/core/api/services/configurations/configurations.hooks.js +33 -0
  11. package/core/api/services/index.js +41 -7
  12. package/core/api/services/messages/messages.hooks.js +9 -3
  13. package/core/client/api.js +14 -1
  14. package/core/client/capabilities.js +1 -6
  15. package/core/client/components/KAvatar.vue +24 -20
  16. package/core/client/components/account/KProfile.vue +10 -71
  17. package/core/client/components/account/index.js +0 -2
  18. package/core/client/components/app/KSettings.vue +1 -0
  19. package/core/client/components/collection/KBoard.vue +4 -3
  20. package/core/client/components/collection/KCardSection.vue +1 -0
  21. package/core/client/components/collection/KGrid.vue +2 -0
  22. package/core/client/components/collection/KTable.vue +5 -1
  23. package/core/client/components/collection/KTimeLine.vue +9 -1
  24. package/core/client/components/collection/index.js +0 -2
  25. package/core/client/components/form/KChipsField.vue +2 -1
  26. package/core/client/components/form/KEmailField.vue +1 -0
  27. package/core/client/components/form/KFileField.vue +22 -1
  28. package/core/client/components/form/KForm.vue +2 -0
  29. package/core/client/components/form/KItemField.vue +1 -0
  30. package/core/client/components/form/KNumberField.vue +1 -0
  31. package/core/client/components/form/KPasswordField.vue +1 -0
  32. package/core/client/components/form/KPhoneField.vue +1 -0
  33. package/core/client/components/form/KPropertyItemField.vue +1 -0
  34. package/core/client/components/form/KResolutionField.vue +1 -0
  35. package/core/client/components/form/KSelectField.vue +31 -0
  36. package/core/client/components/form/KTagField.vue +1 -0
  37. package/core/client/components/form/KTextField.vue +1 -0
  38. package/core/client/components/form/KTokenField.vue +1 -0
  39. package/core/client/components/form/KUnitField.vue +1 -0
  40. package/core/client/components/form/KUrlField.vue +1 -0
  41. package/core/client/components/graphics/KIcon.vue +3 -4
  42. package/core/client/components/layout/KPage.vue +1 -0
  43. package/core/client/components/layout/KWindow.vue +6 -3
  44. package/core/client/components/messages/KMessageComposer.vue +2 -1
  45. package/core/client/components/messages/KMessagesTimeLine.vue +1 -1
  46. package/core/client/components/time/KDate.vue +1 -2
  47. package/core/client/components/time/KDateTime.vue +11 -11
  48. package/core/client/components/time/KTime.vue +1 -1
  49. package/core/client/composables/collection.js +33 -8
  50. package/core/client/composables/errors.js +1 -1
  51. package/core/client/composables/layout.js +9 -9
  52. package/core/client/configurations.js +50 -0
  53. package/core/client/exporter.js +1 -1
  54. package/core/client/i18n/core_en.json +6 -39
  55. package/core/client/i18n/core_fr.json +6 -39
  56. package/core/client/index.js +2 -0
  57. package/core/client/layout.js +8 -8
  58. package/core/client/mixins/mixin.base-activity.js +5 -2
  59. package/core/client/mixins/mixin.base-field.js +3 -3
  60. package/core/client/search.js +2 -1
  61. package/core/client/utils/utils.collection.js +8 -8
  62. package/core/client/utils/utils.items.js +4 -0
  63. package/core/client/utils/utils.push.js +3 -3
  64. package/core/client/utils/utils.session.js +7 -5
  65. package/core/client/utils/utils.shapes.js +38 -7
  66. package/core/client/utils/utils.time.js +21 -22
  67. package/core/common/schemas/users.update-profile.json +3 -2
  68. package/coverage/core/api/application.js.html +392 -398
  69. package/coverage/core/api/authentication.js.html +352 -187
  70. package/coverage/core/api/db.js.html +165 -126
  71. package/coverage/core/api/hooks/hooks.authentication.js.html +22 -196
  72. package/coverage/core/api/hooks/hooks.authorisations.js.html +383 -662
  73. package/coverage/core/api/hooks/hooks.logger.js.html +41 -41
  74. package/coverage/core/api/hooks/hooks.model.js.html +113 -101
  75. package/coverage/core/api/hooks/hooks.push.js.html +124 -97
  76. package/coverage/core/api/hooks/hooks.query.js.html +292 -217
  77. package/coverage/core/api/hooks/hooks.schemas.js.html +123 -123
  78. package/coverage/core/api/hooks/hooks.service.js.html +1 -1
  79. package/coverage/core/api/hooks/hooks.storage.js.html +1 -1
  80. package/coverage/core/api/hooks/{hooks.groups.js.html → hooks.tags.js.html} +100 -76
  81. package/coverage/core/api/hooks/hooks.users.js.html +255 -447
  82. package/coverage/core/api/hooks/index.html +107 -122
  83. package/coverage/core/api/hooks/index.js.html +4 -10
  84. package/coverage/core/api/index.html +46 -61
  85. package/coverage/core/api/index.js.html +9 -9
  86. package/coverage/core/api/marshall.js.html +9 -9
  87. package/coverage/core/api/models/{organisations.model.mongodb.js.html → configurations.model.mongodb.js.html} +10 -7
  88. package/coverage/core/api/models/index.html +35 -50
  89. package/coverage/core/api/models/messages.model.mongodb.js.html +39 -27
  90. package/coverage/core/api/models/tags.model.mongodb.js.html +26 -32
  91. package/coverage/core/api/models/users.model.mongodb.js.html +10 -10
  92. package/coverage/core/api/services/account/account.hooks.js.html +5 -5
  93. package/coverage/core/api/services/account/account.service.js.html +127 -127
  94. package/coverage/core/api/services/account/index.html +22 -22
  95. package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +1 -1
  96. package/coverage/core/api/services/authorisations/authorisations.service.js.html +213 -222
  97. package/coverage/core/api/services/authorisations/index.html +21 -21
  98. package/coverage/core/api/services/{organisations/organisations.hooks.js.html → configurations/configurations.hooks.js.html} +16 -10
  99. package/coverage/core/api/services/{groups → configurations}/index.html +8 -8
  100. package/coverage/core/api/services/databases/databases.hooks.js.html +1 -1
  101. package/coverage/core/api/services/databases/databases.service.js.html +1 -1
  102. package/coverage/core/api/services/databases/index.html +1 -1
  103. package/coverage/core/api/services/import-export/import-export.hooks.js.html +76 -76
  104. package/coverage/core/api/services/import-export/import-export.service.js.html +32 -32
  105. package/coverage/core/api/services/import-export/index.html +32 -32
  106. package/coverage/core/api/services/index.html +21 -21
  107. package/coverage/core/api/services/index.js.html +313 -142
  108. package/coverage/core/api/services/mailer/index.html +32 -32
  109. package/coverage/core/api/services/mailer/mailer.hooks.js.html +80 -80
  110. package/coverage/core/api/services/mailer/mailer.service.js.html +32 -32
  111. package/coverage/core/api/services/messages/index.html +21 -21
  112. package/coverage/core/api/services/messages/messages.hooks.js.html +112 -76
  113. package/coverage/core/api/services/push/index.html +32 -32
  114. package/coverage/core/api/services/push/push.hooks.js.html +80 -80
  115. package/coverage/core/api/services/push/push.service.js.html +34 -34
  116. package/coverage/core/api/services/storage/index.html +29 -29
  117. package/coverage/core/api/services/storage/storage.hooks.js.html +80 -80
  118. package/coverage/core/api/services/storage/storage.service.js.html +29 -29
  119. package/coverage/core/api/services/tags/index.html +21 -21
  120. package/coverage/core/api/services/tags/tags.hooks.js.html +119 -71
  121. package/coverage/core/api/services/users/index.html +27 -12
  122. package/coverage/core/api/services/users/users.hooks.js.html +14 -11
  123. package/coverage/core/api/services/users/users.service.js.html +100 -0
  124. package/coverage/core/common/errors.js.html +1 -1
  125. package/coverage/core/common/index.html +42 -27
  126. package/coverage/core/common/index.js.html +1 -1
  127. package/coverage/core/common/permissions.js.html +166 -472
  128. package/coverage/core/common/schema.js.html +4 -4
  129. package/coverage/core/common/utils.js.html +31 -25
  130. package/coverage/core/common/utils.offline.js.html +199 -0
  131. package/coverage/index.html +192 -192
  132. package/coverage/lcov-report/core/api/application.js.html +392 -398
  133. package/coverage/lcov-report/core/api/authentication.js.html +352 -187
  134. package/coverage/lcov-report/core/api/db.js.html +165 -126
  135. package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +22 -196
  136. package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +383 -662
  137. package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +41 -41
  138. package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +113 -101
  139. package/coverage/lcov-report/core/api/hooks/hooks.push.js.html +124 -97
  140. package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +292 -217
  141. package/coverage/lcov-report/core/api/hooks/hooks.schemas.js.html +123 -123
  142. package/coverage/lcov-report/core/api/hooks/hooks.service.js.html +1 -1
  143. package/coverage/lcov-report/core/api/hooks/hooks.storage.js.html +1 -1
  144. package/coverage/lcov-report/core/api/hooks/{hooks.groups.js.html → hooks.tags.js.html} +100 -76
  145. package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +255 -447
  146. package/coverage/lcov-report/core/api/hooks/index.html +107 -122
  147. package/coverage/lcov-report/core/api/hooks/index.js.html +4 -10
  148. package/coverage/lcov-report/core/api/index.html +46 -61
  149. package/coverage/lcov-report/core/api/index.js.html +9 -9
  150. package/coverage/lcov-report/core/api/marshall.js.html +9 -9
  151. package/coverage/lcov-report/core/api/models/{organisations.model.mongodb.js.html → configurations.model.mongodb.js.html} +10 -7
  152. package/coverage/lcov-report/core/api/models/index.html +35 -50
  153. package/coverage/lcov-report/core/api/models/messages.model.mongodb.js.html +39 -27
  154. package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +26 -32
  155. package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +10 -10
  156. package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +5 -5
  157. package/coverage/lcov-report/core/api/services/account/account.service.js.html +127 -127
  158. package/coverage/lcov-report/core/api/services/account/index.html +22 -22
  159. package/coverage/lcov-report/core/api/services/authorisations/authorisations.hooks.js.html +1 -1
  160. package/coverage/lcov-report/core/api/services/authorisations/authorisations.service.js.html +213 -222
  161. package/coverage/lcov-report/core/api/services/authorisations/index.html +21 -21
  162. package/coverage/lcov-report/core/api/services/{groups/groups.hooks.js.html → configurations/configurations.hooks.js.html} +16 -10
  163. package/coverage/lcov-report/core/api/services/{groups → configurations}/index.html +8 -8
  164. package/coverage/lcov-report/core/api/services/databases/databases.hooks.js.html +1 -1
  165. package/coverage/lcov-report/core/api/services/databases/databases.service.js.html +1 -1
  166. package/coverage/lcov-report/core/api/services/databases/index.html +1 -1
  167. package/coverage/lcov-report/core/api/services/import-export/import-export.hooks.js.html +76 -76
  168. package/coverage/lcov-report/core/api/services/import-export/import-export.service.js.html +32 -32
  169. package/coverage/lcov-report/core/api/services/import-export/index.html +32 -32
  170. package/coverage/lcov-report/core/api/services/index.html +21 -21
  171. package/coverage/lcov-report/core/api/services/index.js.html +313 -142
  172. package/coverage/lcov-report/core/api/services/mailer/index.html +32 -32
  173. package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +80 -80
  174. package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +32 -32
  175. package/coverage/lcov-report/core/api/services/messages/index.html +21 -21
  176. package/coverage/lcov-report/core/api/services/messages/messages.hooks.js.html +112 -76
  177. package/coverage/lcov-report/core/api/services/push/index.html +32 -32
  178. package/coverage/lcov-report/core/api/services/push/push.hooks.js.html +80 -80
  179. package/coverage/lcov-report/core/api/services/push/push.service.js.html +34 -34
  180. package/coverage/lcov-report/core/api/services/storage/index.html +29 -29
  181. package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +80 -80
  182. package/coverage/lcov-report/core/api/services/storage/storage.service.js.html +29 -29
  183. package/coverage/lcov-report/core/api/services/tags/index.html +21 -21
  184. package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +119 -71
  185. package/coverage/lcov-report/core/api/services/users/index.html +27 -12
  186. package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +14 -11
  187. package/coverage/lcov-report/core/api/services/users/users.service.js.html +100 -0
  188. package/coverage/lcov-report/core/common/errors.js.html +1 -1
  189. package/coverage/lcov-report/core/common/index.html +42 -27
  190. package/coverage/lcov-report/core/common/index.js.html +1 -1
  191. package/coverage/lcov-report/core/common/permissions.js.html +166 -472
  192. package/coverage/lcov-report/core/common/schema.js.html +4 -4
  193. package/coverage/lcov-report/core/common/utils.js.html +31 -25
  194. package/coverage/lcov-report/core/common/utils.offline.js.html +199 -0
  195. package/coverage/lcov-report/index.html +192 -192
  196. package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +169 -31
  197. package/coverage/lcov-report/map/api/hooks/hooks.features.js.html +1 -1
  198. package/coverage/lcov-report/map/api/hooks/hooks.query.js.html +215 -35
  199. package/coverage/lcov-report/map/api/hooks/index.html +7 -7
  200. package/coverage/lcov-report/map/api/hooks/index.js.html +1 -1
  201. package/coverage/lcov-report/map/api/index.html +1 -1
  202. package/coverage/lcov-report/map/api/index.js.html +1 -1
  203. package/coverage/lcov-report/map/api/marshall.js.html +1 -1
  204. package/coverage/lcov-report/map/api/models/alerts.model.mongodb.js.html +1 -1
  205. package/coverage/lcov-report/map/api/models/catalog.model.mongodb.js.html +82 -7
  206. package/coverage/lcov-report/map/api/models/features.model.mongodb.js.html +1 -1
  207. package/coverage/lcov-report/map/api/models/index.html +22 -7
  208. package/coverage/lcov-report/map/api/models/projects.model.mongodb.js.html +1 -1
  209. package/coverage/lcov-report/{core/api/models/groups.model.mongodb.js.html → map/api/models/styles.model.mongodb.js.html} +10 -7
  210. package/coverage/lcov-report/map/api/services/alerts/alerts.hooks.js.html +1 -1
  211. package/coverage/lcov-report/map/api/services/alerts/alerts.service.js.html +1 -1
  212. package/coverage/lcov-report/map/api/services/alerts/index.html +1 -1
  213. package/coverage/lcov-report/map/api/services/catalog/catalog.hooks.js.html +39 -12
  214. package/coverage/lcov-report/map/api/services/catalog/index.html +5 -5
  215. package/coverage/lcov-report/map/api/services/daptiles/daptiles.service.js.html +1 -1
  216. package/coverage/lcov-report/map/api/services/daptiles/index.html +1 -1
  217. package/coverage/lcov-report/map/api/services/features/features.hooks.js.html +86 -11
  218. package/coverage/lcov-report/map/api/services/features/features.service.js.html +307 -4
  219. package/coverage/lcov-report/map/api/services/features/index.html +7 -7
  220. package/coverage/lcov-report/map/api/services/index.html +5 -5
  221. package/coverage/lcov-report/map/api/services/index.js.html +326 -50
  222. package/coverage/lcov-report/map/api/services/projects/index.html +1 -1
  223. package/coverage/lcov-report/map/api/services/projects/projects.hooks.js.html +1 -1
  224. package/coverage/{core/api/services/organisations → lcov-report/map/api/services/styles}/index.html +10 -25
  225. package/coverage/lcov-report/{core/api/services/organisations/organisations.hooks.js.html → map/api/services/styles/styles.hooks.js.html} +45 -12
  226. package/coverage/lcov-report/map/common/dynamic-grid-source.js.html +1 -1
  227. package/coverage/lcov-report/map/common/errors.js.html +1 -1
  228. package/coverage/lcov-report/map/common/geotiff-grid-source.js.html +7 -10
  229. package/coverage/lcov-report/map/common/grid.js.html +1 -1
  230. package/coverage/lcov-report/map/common/index.html +19 -19
  231. package/coverage/lcov-report/map/common/index.js.html +1 -1
  232. package/coverage/lcov-report/map/common/meteo-model-grid-source.js.html +1 -1
  233. package/coverage/lcov-report/map/common/moment-utils.js.html +1 -1
  234. package/coverage/lcov-report/map/common/opendap-grid-source.js.html +1 -1
  235. package/coverage/lcov-report/map/common/opendap-utils.js.html +4 -7
  236. package/coverage/lcov-report/map/common/permissions.js.html +10 -4
  237. package/coverage/lcov-report/map/common/time-based-grid-source.js.html +1 -1
  238. package/coverage/lcov-report/map/common/tms-utils.js.html +9 -12
  239. package/coverage/lcov-report/map/common/wcs-grid-source.js.html +3 -3
  240. package/coverage/lcov-report/map/common/wcs-utils.js.html +12 -15
  241. package/coverage/lcov-report/map/common/weacast-grid-source.js.html +2 -2
  242. package/coverage/lcov-report/map/common/wfs-utils.js.html +14 -17
  243. package/coverage/lcov-report/map/common/wms-utils.js.html +30 -12
  244. package/coverage/lcov-report/map/common/wmts-utils.js.html +10 -13
  245. package/coverage/lcov.info +4157 -3816
  246. package/coverage/map/api/hooks/hooks.catalog.js.html +169 -31
  247. package/coverage/map/api/hooks/hooks.features.js.html +1 -1
  248. package/coverage/map/api/hooks/hooks.query.js.html +215 -35
  249. package/coverage/map/api/hooks/index.html +7 -7
  250. package/coverage/map/api/hooks/index.js.html +1 -1
  251. package/coverage/map/api/index.html +1 -1
  252. package/coverage/map/api/index.js.html +1 -1
  253. package/coverage/map/api/marshall.js.html +1 -1
  254. package/coverage/map/api/models/alerts.model.mongodb.js.html +1 -1
  255. package/coverage/map/api/models/catalog.model.mongodb.js.html +82 -7
  256. package/coverage/map/api/models/features.model.mongodb.js.html +1 -1
  257. package/coverage/map/api/models/index.html +22 -7
  258. package/coverage/map/api/models/projects.model.mongodb.js.html +1 -1
  259. package/coverage/{core/api/models/groups.model.mongodb.js.html → map/api/models/styles.model.mongodb.js.html} +10 -7
  260. package/coverage/map/api/services/alerts/alerts.hooks.js.html +1 -1
  261. package/coverage/map/api/services/alerts/alerts.service.js.html +1 -1
  262. package/coverage/map/api/services/alerts/index.html +1 -1
  263. package/coverage/map/api/services/catalog/catalog.hooks.js.html +39 -12
  264. package/coverage/map/api/services/catalog/index.html +5 -5
  265. package/coverage/map/api/services/daptiles/daptiles.service.js.html +1 -1
  266. package/coverage/map/api/services/daptiles/index.html +1 -1
  267. package/coverage/map/api/services/features/features.hooks.js.html +86 -11
  268. package/coverage/map/api/services/features/features.service.js.html +307 -4
  269. package/coverage/map/api/services/features/index.html +7 -7
  270. package/coverage/map/api/services/index.html +5 -5
  271. package/coverage/map/api/services/index.js.html +326 -50
  272. package/coverage/map/api/services/projects/index.html +1 -1
  273. package/coverage/map/api/services/projects/projects.hooks.js.html +1 -1
  274. package/coverage/{lcov-report/core/api/services/organisations → map/api/services/styles}/index.html +10 -25
  275. package/coverage/{core/api/services/groups/groups.hooks.js.html → map/api/services/styles/styles.hooks.js.html} +45 -12
  276. package/coverage/map/common/dynamic-grid-source.js.html +1 -1
  277. package/coverage/map/common/errors.js.html +1 -1
  278. package/coverage/map/common/geotiff-grid-source.js.html +7 -10
  279. package/coverage/map/common/grid.js.html +1 -1
  280. package/coverage/map/common/index.html +19 -19
  281. package/coverage/map/common/index.js.html +1 -1
  282. package/coverage/map/common/meteo-model-grid-source.js.html +1 -1
  283. package/coverage/map/common/moment-utils.js.html +1 -1
  284. package/coverage/map/common/opendap-grid-source.js.html +1 -1
  285. package/coverage/map/common/opendap-utils.js.html +4 -7
  286. package/coverage/map/common/permissions.js.html +10 -4
  287. package/coverage/map/common/time-based-grid-source.js.html +1 -1
  288. package/coverage/map/common/tms-utils.js.html +9 -12
  289. package/coverage/map/common/wcs-grid-source.js.html +3 -3
  290. package/coverage/map/common/wcs-utils.js.html +12 -15
  291. package/coverage/map/common/weacast-grid-source.js.html +2 -2
  292. package/coverage/map/common/wfs-utils.js.html +14 -17
  293. package/coverage/map/common/wms-utils.js.html +30 -12
  294. package/coverage/map/common/wmts-utils.js.html +10 -13
  295. package/coverage/tmp/coverage-1028514-1773134124472-0.json +1 -0
  296. package/coverage/tmp/coverage-1028526-1773134124448-0.json +1 -0
  297. package/coverage/tmp/coverage-1028537-1773134124431-0.json +1 -0
  298. package/coverage/tmp/coverage-1028549-1773134124401-0.json +1 -0
  299. package/coverage/tmp/coverage-1028556-1773134124353-0.json +1 -0
  300. package/extras/configs/widgets.top.js +3 -3
  301. package/extras/tests/core/collection.mjs +2 -9
  302. package/extras/tours/pane.top.js +0 -9
  303. package/map/api/hooks/hooks.catalog.js +18 -4
  304. package/map/api/services/catalog/catalog.hooks.js +3 -0
  305. package/map/api/services/features/features.hooks.js +3 -1
  306. package/map/api/services/index.js +2 -6
  307. package/map/api/services/styles/styles.hooks.js +6 -1
  308. package/map/client/components/KFeatureActionButton.vue +9 -3
  309. package/map/client/components/KFeaturesFilterManager.vue +5 -5
  310. package/map/client/components/KFilterCondition.vue +17 -10
  311. package/map/client/components/KLayerEditor.vue +49 -39
  312. package/map/client/components/KMeasureTool.vue +7 -1
  313. package/map/client/components/KTimezoneMap.vue +29 -9
  314. package/map/client/components/catalog/KLayersPanel.vue +26 -16
  315. package/map/client/components/catalog/KLayersSelector.vue +13 -2
  316. package/map/client/components/catalog/KViewsPanel.vue +5 -4
  317. package/map/client/components/form/KSelectLayersField.vue +28 -17
  318. package/map/client/components/form/KSelectViewsField.vue +18 -9
  319. package/map/client/components/form/KTimezoneField.vue +1 -2
  320. package/map/client/components/legend/KVariablesLegend.vue +10 -1
  321. package/map/client/components/location/KLocationCardSection.vue +7 -2
  322. package/map/client/components/location/KLocationMap.vue +31 -7
  323. package/map/client/components/selection/KSelectedLayerFeatures.vue +2 -2
  324. package/map/client/components/stickies/KZoomControl.vue +1 -1
  325. package/map/client/components/styles/KStyleManager.vue +4 -1
  326. package/map/client/components/widget/KTimeSeries.vue +174 -497
  327. package/map/client/components/widget/KTimeSeriesSelector.vue +72 -0
  328. package/map/client/components/widget/KTimeSeriesToolbar.vue +83 -0
  329. package/map/client/composables/catalog.js +6 -10
  330. package/map/client/composables/highlight.js +12 -9
  331. package/map/client/composables/project.js +1 -1
  332. package/map/client/composables/selection.js +8 -7
  333. package/map/client/composables/weather.js +9 -2
  334. package/map/client/geolocation.js +8 -5
  335. package/map/client/i18n/map_en.json +11 -10
  336. package/map/client/i18n/map_fr.json +10 -9
  337. package/map/client/leaflet/TiledFeatureLayer.js +85 -82
  338. package/map/client/leaflet/utils/utils.geojson.js +3 -3
  339. package/map/client/mixins/globe/mixin.base-globe.js +15 -6
  340. package/map/client/mixins/globe/mixin.geojson-layers.js +27 -18
  341. package/map/client/mixins/map/mixin.edit-layers.js +9 -1
  342. package/map/client/mixins/map/mixin.pmtiles-layers.js +118 -29
  343. package/map/client/mixins/map/mixin.tiled-mesh-layers.js +12 -5
  344. package/map/client/mixins/map/mixin.tiled-wind-layers.js +19 -10
  345. package/map/client/mixins/mixin.activity.js +23 -30
  346. package/map/client/mixins/mixin.feature-selection.js +41 -5
  347. package/map/client/planets.js +1 -1
  348. package/map/client/readers/reader.kml.js +2 -3
  349. package/map/client/utils/utils.catalog.js +36 -10
  350. package/map/client/utils/utils.layers.js +39 -8
  351. package/map/client/utils/utils.project.js +4 -0
  352. package/map/client/utils/utils.style.js +37 -7
  353. package/map/client/utils/utils.time-series.js +215 -6
  354. package/map/common/schemas/catalog.update.json +1 -1
  355. package/map/common/weacast-grid-source.js +1 -1
  356. package/package.json +3 -3
  357. package/scripts/kash/CHANGELOG.md +0 -4
  358. package/scripts/kash/README.md +0 -9
  359. package/scripts/kash/kash.sh +45 -40
  360. package/scripts/kash/scripts/run_tests.sh +1 -4
  361. package/test/api/core/authentication.test.js +9 -4
  362. package/test/api/core/config/default.cjs +1 -0
  363. package/test/api/core/hooks.test.js +6 -0
  364. package/test/api/core/index.test.js +43 -18
  365. package/test/api/core/push.test.js +8 -8
  366. package/test/api/core/test-log-2026-03-10.log +60 -0
  367. package/test/api/core/users.test.js +384 -0
  368. package/test/api/map/grid-sources.test.js +1 -1
  369. package/test/api/map/test-log-2026-03-10.log +56 -0
  370. package/vite/package.json +11 -2
  371. package/vite/test/core/composables.test.js +77 -0
  372. package/vite/vitest.config.js +13 -0
  373. package/vite/yarn.lock +1096 -18
  374. package/.vscode/settings.json +0 -5
  375. package/core/client/components/account/KAccount.vue +0 -68
  376. package/core/client/components/account/KDeleteAccountManager.vue +0 -62
  377. package/core/client/components/account/KEmailManager.vue +0 -128
  378. package/core/client/components/account/KPasswordManager.vue +0 -90
  379. package/core/client/components/account/KVerifyEmailManager.vue +0 -105
  380. package/core/client/components/collection/KColumn.vue +0 -227
  381. package/core/client/components/collection/KHistory.vue +0 -113
  382. package/core/client/components/collection/KHistoryEntry.vue +0 -109
  383. package/coverage/core/api/hooks/hooks.organisations.js.html +0 -541
  384. package/coverage/core/api/services/organisations/organisations.service.js.html +0 -343
  385. package/coverage/core/api/utils.js.html +0 -118
  386. package/coverage/lcov-report/core/api/hooks/hooks.organisations.js.html +0 -541
  387. package/coverage/lcov-report/core/api/services/organisations/organisations.service.js.html +0 -343
  388. package/coverage/lcov-report/core/api/utils.js.html +0 -118
  389. package/coverage/tmp/coverage-151166-1723543324307-0.json +0 -1
  390. package/coverage/tmp/coverage-151178-1723543324283-0.json +0 -1
  391. package/coverage/tmp/coverage-151189-1723543324271-0.json +0 -1
  392. package/coverage/tmp/coverage-151201-1723543324248-0.json +0 -1
  393. package/coverage/tmp/coverage-151208-1723543324227-0.json +0 -1
  394. package/scripts/kash/LICENSE +0 -21
  395. package/test/api/core/test-log-2024-04-22.log +0 -84
  396. package/test/api/core/test-log-2024-04-23.log +0 -23
  397. package/test/api/core/test-log-2024-08-13.log +0 -3
  398. package/test/api/map/test-log-2025-03-08.log +0 -0
@@ -10,6 +10,8 @@ import { getFeatureId } from '../utils.js'
10
10
  const TiledFeatureLayer = L.GridLayer.extend({
11
11
  initialize (options) {
12
12
  this.enableDebug = _.get(options, 'enableDebug', false)
13
+ this.enableMergeRequests = _.get(options, 'enableMergeRequests', true)
14
+
13
15
  // this.enableDebug = true
14
16
  L.GridLayer.prototype.initialize.call(this, options)
15
17
 
@@ -168,98 +170,99 @@ const TiledFeatureLayer = L.GridLayer.extend({
168
170
  mergeRequests (tiles) {
169
171
  const requests = []
170
172
 
171
- // Try to merge tiles vertically, then horizontally
172
- const sortedTiles = tiles.sort((a, b) => {
173
- if (a.coords.x === b.coords.x) {
174
- return a.coords.y < b.coords.y ? -1 : a.coords.y !== b.coords.y ? 1 : 0
175
- }
176
- return a.coords.x < b.coords.x ? -1 : 1
177
- })
173
+ if (this.enableMergeRequests) {
174
+ // Try to merge tiles vertically, then horizontally
175
+ const sortedTiles = tiles.sort((a, b) => {
176
+ if (a.coords.x === b.coords.x) {
177
+ return a.coords.y < b.coords.y ? -1 : a.coords.y !== b.coords.y ? 1 : 0
178
+ }
179
+ return a.coords.x < b.coords.x ? -1 : 1
180
+ })
178
181
 
179
- if (sortedTiles.length) {
180
- const z = sortedTiles[0].coords.z
181
- const vrequests = []
182
- sortedTiles.forEach((tile) => {
183
- let newRequest = true
184
- if (vrequests.length) {
185
- const r = vrequests[vrequests.length - 1]
186
- if (tile.coords.x === r.x) {
187
- if (tile.coords.y === r.maxy + 1) {
188
- r.tiles.push(tile)
189
- r.maxy = tile.coords.y
190
- newRequest = false
182
+ if (sortedTiles.length) {
183
+ const z = sortedTiles[0].coords.z
184
+ const vrequests = []
185
+ sortedTiles.forEach((tile) => {
186
+ let newRequest = true
187
+ if (vrequests.length) {
188
+ const r = vrequests[vrequests.length - 1]
189
+ if (tile.coords.x === r.x) {
190
+ if (tile.coords.y === r.maxy + 1) {
191
+ r.tiles.push(tile)
192
+ r.maxy = tile.coords.y
193
+ newRequest = false
194
+ }
191
195
  }
192
196
  }
193
- }
194
- if (newRequest) {
195
- vrequests.push({
196
- x: tile.coords.x,
197
- miny: tile.coords.y,
198
- maxy: tile.coords.y,
199
- tiles: [tile]
200
- })
201
- }
202
- })
197
+ if (newRequest) {
198
+ vrequests.push({
199
+ x: tile.coords.x,
200
+ miny: tile.coords.y,
201
+ maxy: tile.coords.y,
202
+ tiles: [tile]
203
+ })
204
+ }
205
+ })
203
206
 
204
- // Now try to merge horizontally adjacent vertical requests
205
- vrequests.forEach((v) => {
206
- let newRequest = true
207
- if (requests.length) {
208
- const h = requests[requests.length - 1]
209
- if (v.miny === h.miny && v.maxy === h.maxy && v.x === h.maxx + 1) {
210
- h.tiles.push(...v.tiles)
211
- h.maxx = v.x
212
- newRequest = false
207
+ // Now try to merge horizontally adjacent vertical requests
208
+ vrequests.forEach((v) => {
209
+ let newRequest = true
210
+ if (requests.length) {
211
+ const h = requests[requests.length - 1]
212
+ if (v.miny === h.miny && v.maxy === h.maxy && v.x === h.maxx + 1) {
213
+ h.tiles.push(...v.tiles)
214
+ h.maxx = v.x
215
+ newRequest = false
216
+ }
213
217
  }
214
- }
215
- if (newRequest) {
216
- requests.push({
217
- minx: v.x,
218
- maxx: v.x,
219
- miny: v.miny,
220
- maxy: v.maxy,
221
- tiles: [].concat(v.tiles)
222
- })
223
- }
224
- })
218
+ if (newRequest) {
219
+ requests.push({
220
+ minx: v.x,
221
+ maxx: v.x,
222
+ miny: v.miny,
223
+ maxy: v.maxy,
224
+ tiles: [].concat(v.tiles)
225
+ })
226
+ }
227
+ })
225
228
 
226
- // Compute final query
227
- requests.forEach((r) => {
228
- const minp = L.point(r.minx, r.miny); const maxp = L.point(r.maxx, r.maxy)
229
- minp.z = maxp.z = z
230
- const bounds = this._tileCoordsToBounds(minp)
231
- bounds.extend(this._tileCoordsToBounds(maxp))
232
- r.query = {
233
- south: bounds.getSouth(),
234
- north: bounds.getNorth(),
235
- west: bounds.getWest(),
236
- east: bounds.getEast()
237
- }
238
- })
229
+ // Compute final query
230
+ requests.forEach((r) => {
231
+ const minp = L.point(r.minx, r.miny); const maxp = L.point(r.maxx, r.maxy)
232
+ minp.z = maxp.z = z
233
+ const bounds = this._tileCoordsToBounds(minp)
234
+ bounds.extend(this._tileCoordsToBounds(maxp))
235
+ r.query = {
236
+ south: bounds.getSouth(),
237
+ north: bounds.getNorth(),
238
+ west: bounds.getWest(),
239
+ east: bounds.getEast()
240
+ }
241
+ })
239
242
 
240
- if (this.enableDebug) {
241
- let numTilesR = 0
242
- requests.forEach((r) => { numTilesR += r.tiles.length })
243
- if (numTilesR !== tiles.length) {
244
- logger.debug('TiledFeatureLayer: less requested tiles than expected !')
243
+ if (this.enableDebug) {
244
+ let numTilesR = 0
245
+ requests.forEach((r) => { numTilesR += r.tiles.length })
246
+ if (numTilesR !== tiles.length) {
247
+ logger.debug('TiledFeatureLayer: less requested tiles than expected !')
248
+ }
245
249
  }
246
250
  }
247
- }
248
-
249
- /* One request per tile
250
- tiles.forEach((tile) => {
251
- const r = {
252
- tiles: [tile],
253
- query: {
254
- south: tile.bbox.getSouth(),
255
- north: tile.bbox.getNorth(),
256
- west: tile.bbox.getWest(),
257
- east: tile.bbox.getEast()
251
+ } else {
252
+ // Request merging disabled => one request per tile
253
+ tiles.forEach((tile) => {
254
+ const r = {
255
+ tiles: [tile],
256
+ query: {
257
+ south: tile.bbox.getSouth(),
258
+ north: tile.bbox.getNorth(),
259
+ west: tile.bbox.getWest(),
260
+ east: tile.bbox.getEast()
261
+ }
258
262
  }
259
- }
260
- requests.push(r)
261
- })
262
- */
263
+ requests.push(r)
264
+ })
265
+ }
263
266
 
264
267
  if (this.enableDebug && tiles.length) {
265
268
  logger.debug(`TiledFeatureLayer: ${tiles.length} requests reduced to ${requests.length}`)
@@ -112,13 +112,13 @@ L.GeoJSON.geometryToLayer = function (geojson, options) {
112
112
  if (geometry && properties && properties.geodesic) {
113
113
  if (geometry.type === 'LineString') {
114
114
  return new L.Geodesic([L.GeoJSON.coordsToLatLngs(geometry.coordinates, 0)],
115
- Object.assign({ steps: 4 }, options.style(geojson)))
115
+ Object.assign({ steps: properties.steps || 4, wrap: properties.wrap }, options.style(geojson)))
116
116
  } else if (geometry.type === 'MultiLineString') {
117
117
  const coords = geometry.coordinates.map((lineString) => L.GeoJSON.coordsToLatLngs(lineString, 0))
118
- return new L.Geodesic(coords, Object.assign({ steps: 4 }, options.style(geojson)))
118
+ return new L.Geodesic(coords, Object.assign({ steps: properties.steps || 4, wrap: properties.wrap }, options.style(geojson)))
119
119
  } else if (geometry.type === 'Point') {
120
120
  const layer = new L.GeodesicCircle(L.GeoJSON.coordsToLatLng(geometry.coordinates),
121
- Object.assign({ fill: true, steps: 360, radius: properties.radius }, options.style(geojson)))
121
+ Object.assign({ fill: true, steps: properties.steps || 360, wrap: properties.wrap, radius: properties.radius }, options.style(geojson)))
122
122
  return layer
123
123
  }
124
124
  }
@@ -318,7 +318,7 @@ export const baseGlobe = {
318
318
  this.$emit('layer-added', layer)
319
319
  this.$engineEvents.emit('layer-added', layer)
320
320
  },
321
- async addGeoJsonLayer (layerSpec, geoJson, zoom) {
321
+ async addGeoJsonLayer (layerSpec, geoJson, zoom = true) {
322
322
  if (!generateLayerDefinition(layerSpec, geoJson)) return
323
323
  // Create an empty layer
324
324
  await this.addLayer(layerSpec)
@@ -379,12 +379,11 @@ export const baseGlobe = {
379
379
  },
380
380
  zoomIn () {
381
381
  const center = this.getCenter()
382
- this.center(center.longitude, center.latitude, center.altitude * 0.5)
382
+ this.center(center.longitude, center.latitude, center.altitude * 0.8)
383
383
  },
384
384
  zoomOut () {
385
- const inertiaZoom = this.viewer.scene.screenSpaceCameraController.inertiaZoom
386
385
  const center = this.getCenter()
387
- this.center(center.longitude, center.latitude, center.altitude / 2.0)
386
+ this.center(center.longitude, center.latitude, center.altitude / 0.8)
388
387
  },
389
388
  zoomToBounds (bounds, heading = 0, pitch = -90, roll = 0, duration = 0) {
390
389
  this.viewer.camera.flyTo({
@@ -863,16 +862,26 @@ export const baseGlobe = {
863
862
  const fs = `
864
863
  uniform sampler2D colorTexture;
865
864
  in vec2 v_textureCoordinates;
865
+
866
+ uniform float desaturation;
867
+ uniform float brightness;
868
+
866
869
  void main() {
867
870
  vec4 color = texture(colorTexture, v_textureCoordinates);
868
871
  if (czm_selected()) {
869
872
  out_FragColor = color;
870
873
  } else {
871
- out_FragColor = vec4(czm_saturation(color.rgb, 0.0), color.a);
874
+ out_FragColor = vec4(czm_saturation(color.rgb, desaturation) * brightness, color.a);
872
875
  }
873
876
  }
874
877
  `
875
- stage = this.viewer.scene.postProcessStages.add(new Cesium.PostProcessStage({ fragmentShader: fs }))
878
+ stage = this.viewer.scene.postProcessStages.add(new Cesium.PostProcessStage({
879
+ fragmentShader: fs,
880
+ uniforms: {
881
+ desaturation: _.get(options, 'desaturation', 1.0),
882
+ brightness: _.get(options, 'brightness', 1.0)
883
+ }
884
+ }))
876
885
  stage.selected = [] // Initialize empty selected set for postprocess.
877
886
  this.cesiumPostProcessStages[effect] = stage
878
887
  }
@@ -1,9 +1,8 @@
1
- import { GeoJsonDataSource, ColorMaterialProperty, ConstantProperty, Math as CesiumMath, HeadingPitchRoll, Quaternion } from 'cesium'
1
+ import { GeoJsonDataSource, ColorMaterialProperty, ConstantProperty, Math as CesiumMath, HeadingPitchRoll, Quaternion, Cartographic, EllipsoidRhumbLine } from 'cesium'
2
2
  import _ from 'lodash'
3
3
  import logger from 'loglevel'
4
4
  import sift from 'sift'
5
5
  import { uid } from 'quasar'
6
- import { point, rhumbDistance, rhumbBearing, rhumbDestination } from '@turf/turf'
7
6
  import { Time, Units, Events } from '../../../../core.client.js'
8
7
  import { fetchGeoJson, getFeatureId, processFeatures, getFeatureStyleType, isInMemoryLayer, getGeoJsonFeatures } from '../../utils.js'
9
8
  import { convertSimpleStyleToPointStyle, convertSimpleStyleToLineStyle, convertSimpleStyleToPolygonStyle } from '../../utils/utils.style.js'
@@ -95,7 +94,10 @@ export const geojsonLayers = {
95
94
  entities.forEach(entity => {
96
95
  // Find matching feature if any and keep track of it as Cesium only keeps properties
97
96
  entity.feature = features.find(feature => getFeatureId(feature, options) === entity.id)
98
- const previousEntity = dataSource.entities.getById(entity.id)
97
+ let previousEntity = dataSource.entities.getById(entity.id)
98
+ CustomTypes.forEach(type => {
99
+ previousEntity = previousEntity || dataSource.entities.getById(getCustomEntityId(entity.id, type))
100
+ })
99
101
  if (previousEntity) {
100
102
  const isAnimatedLayer = _.get(updateOptions, 'duration') && _.get(entity, 'feature') && _.get(previousEntity, 'feature')
101
103
  if (isAnimatedLayer) {
@@ -328,7 +330,7 @@ export const geojsonLayers = {
328
330
  } else if (options.service) { // Check for feature service layers only, in this case update in place
329
331
  // If no probe reference, nothing to be initialized
330
332
  // Get original layer options to ensure we have the latest ones while getting features (e.g. filters toggle)
331
- await this.loadGeoJson(dataSource, this.getFeatures(Object.assign({}, options, this.getLayerByName(options.name))), options, updateOptions)
333
+ await this.loadGeoJson(dataSource, await this.getFeatures(Object.assign({}, options, this.getLayerByName(options.name))), options, updateOptions)
332
334
  } else if (sourceTemplate) {
333
335
  const sourceToFetch = dataSource.sourceCompiler({ time: Time.getCurrentTime() })
334
336
  if (!dataSource.lastFetchedSource || (dataSource.lastFetchedSource !== sourceToFetch)) {
@@ -641,32 +643,39 @@ export const geojsonLayers = {
641
643
  // Store animation information in properties so that we don't need to recompute it for next steps
642
644
  if (!currFeature.properties.animation || !currFeature.properties.animation.geometry) {
643
645
  if (!currFeature.properties.animation) currFeature.properties.animation = {}
644
- const startCoordinates = { lon: prevFeature.geometry.coordinates[0], lat: prevFeature.geometry.coordinates[1] }
645
- const endCoordinates = { lon: currFeature.geometry.coordinates[0], lat: currFeature.geometry.coordinates[1] }
646
+ const startCoordinates = { lon: prevFeature.geometry.coordinates[0], lat: prevFeature.geometry.coordinates[1], alt: prevFeature.geometry.coordinates[2] || null }
647
+ const endCoordinates = { lon: currFeature.geometry.coordinates[0], lat: currFeature.geometry.coordinates[1], alt: currFeature.geometry.coordinates[2] || null }
646
648
  currFeature.properties.animation.geometry = {
647
649
  startCoordinates,
648
650
  endCoordinates
649
651
  }
650
652
  if (animateProperty.rhumb) {
651
- const start = point([startCoordinates.lon, startCoordinates.lat])
652
- const end = point([endCoordinates.lon, endCoordinates.lat])
653
- currFeature.properties.animation.geometry.rhumb = {
654
- start,
655
- distance: rhumbDistance(start, end),
656
- bearing: rhumbBearing(start, end)
653
+ try {
654
+ const start = new Cartographic(startCoordinates.lon, startCoordinates.lat, startCoordinates.alt || 0)
655
+ const end = new Cartographic(endCoordinates.lon, endCoordinates.lat, endCoordinates.alt || 0)
656
+ currFeature.properties.animation.geometry.rhumbLine = new EllipsoidRhumbLine(start, end)
657
+ } catch (e) {
658
+ // Fallback to null if we cannot compute rhumb line (e.g. start = end)
659
+ currFeature.properties.animation.geometry.rhumbLine = null
657
660
  }
658
661
  }
659
662
  }
660
663
  // Interpolate position
661
- if (animateProperty.rhumb) {
662
- const rhumbData = currFeature.properties.animation.geometry.rhumb
663
- const destination = rhumbDestination(rhumbData.start, rhumbData.distance * tEasing, rhumbData.bearing)
664
- animatedFeature.geometry.coordinates[0] = destination.geometry.coordinates[0]
665
- animatedFeature.geometry.coordinates[1] = destination.geometry.coordinates[1]
664
+ const geometryData = currFeature.properties.animation.geometry
665
+ if (animateProperty.rhumb && currFeature.properties.animation.geometry.rhumbLine) {
666
+ const rhumbLine = currFeature.properties.animation.geometry.rhumbLine
667
+ const destination = rhumbLine.interpolateUsingFraction(tEasing, new Cartographic())
668
+ animatedFeature.geometry.coordinates[0] = destination.longitude
669
+ animatedFeature.geometry.coordinates[1] = destination.latitude
670
+ if (geometryData.startCoordinates.alt !== null && geometryData.endCoordinates.alt !== null) {
671
+ animatedFeature.geometry.coordinates[2] = destination.height
672
+ }
666
673
  } else {
667
- const geometryData = currFeature.properties.animation.geometry
668
674
  animatedFeature.geometry.coordinates[0] = lerp(geometryData.startCoordinates.lon, geometryData.endCoordinates.lon, tEasing)
669
675
  animatedFeature.geometry.coordinates[1] = lerp(geometryData.startCoordinates.lat, geometryData.endCoordinates.lat, tEasing)
676
+ if (geometryData.startCoordinates.alt !== null && geometryData.endCoordinates.alt !== null) {
677
+ animatedFeature.geometry.coordinates[2] = lerp(geometryData.startCoordinates.alt, geometryData.endCoordinates.alt, tEasing)
678
+ }
670
679
  }
671
680
  } else if (property === 'orientation') {
672
681
  // Store animation information in properties so that we don't need to recompute it for next steps
@@ -1,8 +1,10 @@
1
1
  import _ from 'lodash'
2
2
  import L from 'leaflet'
3
+ import logger from 'loglevel'
3
4
  import bearing from '@turf/bearing'
4
5
  import { getType, getCoords, getGeom } from '@turf/invariant'
5
6
  import { uid } from 'quasar'
7
+ import { Context } from '../../../../core/client/context.js'
6
8
  import { Store } from '../../../../core/client/store.js'
7
9
  import { Units } from '../../../../core/client/units.js'
8
10
  import { api } from '../../../../core/client/api.js'
@@ -98,6 +100,12 @@ export const editLayers = {
98
100
  if (!_.isEmpty(geometryTypes) && !geometryTypes.includes('Polygon') && !geometryTypes.includes('MultiPolygon')) return style(feature)
99
101
  else return getDefaultPolygonStyle(feature, layerStyle, _.get(this, 'activityOptions.engine.style.edition.polygon'))
100
102
  }
103
+ const isPoint = ((feature.geometry.type === 'Point') || (feature.geometry.type === 'MultiPoint'))
104
+ if (isPoint) {
105
+ // Skip point editing style if not editing points
106
+ if (!_.isEmpty(geometryTypes) && !geometryTypes.includes('Point') && !geometryTypes.includes('MultiPoint')) return style(feature)
107
+ else return getDefaultPointStyle(feature, layerStyle, _.get(this, 'activityOptions.engine.style.edition.point'))
108
+ }
101
109
  logger.warn(`[KDK] the geometry of type of ${feature.geometry.type} is not supported`)
102
110
  },
103
111
  pointToLayer: (feature, latlng) => {
@@ -400,7 +408,7 @@ export const editLayers = {
400
408
  layerId: this.editedLayer._id,
401
409
  layerName: this.editedLayer.name,
402
410
  featureId: feature._id,
403
- contextId: Store.get('context')
411
+ contextId: Context.get()
404
412
  })
405
413
  })
406
414
  },
@@ -4,39 +4,74 @@ import moment from 'moment'
4
4
  import sift from 'sift'
5
5
  import L from 'leaflet'
6
6
  import * as protomaps from 'protomaps-leaflet'
7
- import { mapbox_style } from '@kalisio/leaflet-pmtiles'
7
+ import { mapbox_style, kdk_style } from '@kalisio/leaflet-pmtiles'
8
8
  import { api, Time, Units, Events, TemplateContext } from '../../../../core/client/index.js'
9
+ import * as time from '../../../../core/client/utils/utils.time.js'
10
+ import * as layers from '../../utils/utils.layers.js'
11
+
12
+ function detectStyleType (style) {
13
+ // `style` field on pmtile layer definition can be one of:
14
+ // - string => in this case we assume this is a mapbox json style
15
+ // - kdk style object
16
+ // - protomaps style object
17
+
18
+ if (typeof style === 'string') return 'mapbox'
19
+ // Look for 'symbolizer' keys in the object, if we find one, this is a protomaps style
20
+ if (_.some(style, (rule) => rule.symbolizer !== undefined)) return 'protomaps'
21
+ // Otherwise we assume this is a kdk style object
22
+ return style ? 'kdk' : 'empty'
23
+ }
9
24
 
10
25
  export const pmtilesLayers = {
11
26
  methods: {
12
- async createLeafletPMTilesLayer (options) {
27
+ async processLeafletPMTilesLayer (options, properties = ['urlTemplate', 'styleTemplate', 'template']) {
13
28
  const leafletOptions = options.leaflet || options
14
- // Check for valid types
15
- if (leafletOptions.type !== 'pmtiles') return
16
-
29
+
17
30
  // Token required by templating
18
31
  const planetApi = (typeof options.getPlanetApi === 'function' ? options.getPlanetApi() : api)
19
32
  const apiJwt = (planetApi.hasConfig('apiJwt') ? await planetApi.get('storage').getItem(planetApi.getConfig('apiJwt')) : null)
20
33
  const gatewayJwt = (planetApi.hasConfig('gatewayJwt') ? await planetApi.get('storage').getItem(planetApi.getConfig('gatewayJwt')) : null)
21
34
 
22
- const urlTemplate = _.get(leafletOptions, 'urlTemplate')
23
- if (urlTemplate) leafletOptions.url = _.template(urlTemplate)({ apiJwt, gatewayJwt })
24
- const styleTemplate = _.get(leafletOptions, 'styleTemplate')
25
- if (styleTemplate) leafletOptions.style = _.template(styleTemplate)({ apiJwt, gatewayJwt })
26
-
27
- // Optimize templating by creating compilers up-front
28
- const layerStyleTemplate = _.get(leafletOptions, 'template')
29
- if (layerStyleTemplate) {
30
- // We allow to template style properties according to feature, because it can be slow you have to specify a subset of properties
31
- leafletOptions.template = layerStyleTemplate.map(property => ({
32
- property, compiler: _.template(_.get(leafletOptions, property))
33
- }))
35
+ if (properties.includes('urlTemplate')) {
36
+ const urlTemplate = _.get(leafletOptions, 'urlTemplate')
37
+ if (urlTemplate) {
38
+ const context = Object.assign({
39
+ apiJwt, gatewayJwt, moment, Units, Time, level: this.selectedLevel, ...time
40
+ }, TemplateContext.get())
41
+ leafletOptions.url = _.template(urlTemplate)(context)
42
+ }
34
43
  }
35
-
44
+ if (properties.includes('styleTemplate')) {
45
+ const styleTemplate = _.get(leafletOptions, 'styleTemplate')
46
+ if (styleTemplate) {
47
+ const context = Object.assign({
48
+ apiJwt, gatewayJwt, moment, Units, Time, level: this.selectedLevel, ...time
49
+ }, TemplateContext.get())
50
+ leafletOptions.style = _.template(styleTemplate)(context)
51
+ }
52
+ }
53
+ if (properties.includes('template')) {
54
+ // Optimize templating by creating compilers up-front
55
+ const layerStyleTemplate = _.get(leafletOptions, 'template')
56
+ if (layerStyleTemplate) {
57
+ // We allow to template style properties according to feature, because it can be slow you have to specify a subset of properties
58
+ leafletOptions.template = layerStyleTemplate.map(property => ({
59
+ property, compiler: _.template(_.get(leafletOptions, property))
60
+ }))
61
+ }
62
+ }
63
+ },
64
+ async createLeafletPMTilesLayer (options) {
65
+ const leafletOptions = options.leaflet || options
66
+ // Check for valid types
67
+ if (leafletOptions.type !== 'pmtiles') return
68
+ // Process main options
69
+ await this.processLeafletPMTilesLayer(options)
70
+ // Then create rendering rules
36
71
  let rules = {}
37
- // Check for style information given as object or URL
38
72
  let style = _.get(leafletOptions, 'style')
39
- if (typeof style === 'string') {
73
+ const styleType = detectStyleType(style)
74
+ if (styleType === 'mapbox') {
40
75
  const response = await fetch(style)
41
76
  if (response.status !== 200) {
42
77
  throw new Error(`Impossible to fetch style ${style}: ` + response.status)
@@ -48,24 +83,49 @@ export const pmtilesLayers = {
48
83
  rules = mapbox_style(style, {})
49
84
  } else {
50
85
  // Manage templating
51
- _.get(leafletOptions, 'template', []).forEach(entry => {
52
- // protomaps allows property functions with zomm/feature as input
86
+ const templates = _.get(leafletOptions, 'template', [])
87
+ templates.forEach(entry => {
88
+ // protomaps allows property functions with zoom/feature as input
53
89
  const f = (zoom, feature) => {
54
90
  const context = Object.assign({ properties: feature.props, feature, chroma, moment, Units, Time, level: this.selectedLevel }, TemplateContext.get())
55
- return entry.property.endsWith('filter') ? (entry.compiler(context) === 'true'): entry.compiler(context)
91
+ if (entry.property.endsWith('filter')) {
92
+ const result = entry.compiler(context)
93
+ return (result === 'true')
94
+ } else {
95
+ return entry.compiler(context)
96
+ }
56
97
  }
57
98
  _.set(leafletOptions, entry.property, f)
58
99
  })
59
- if (style) {
100
+ if (styleType === 'protomaps') {
60
101
  const styleRules = _.map(style, rule => Object.assign(_.omit(rule, ['symbolizer']), {
61
- symbolizer: new protomaps[rule.symbolizer.type](rule.symbolizer)
62
- })
102
+ symbolizer: new protomaps[rule.symbolizer.type](rule.symbolizer)
103
+ })
63
104
  )
64
105
  const isLabelSymbolizer = (rule) => typeof rule.symbolizer.place === 'function'
65
106
  const isNotLabelSymbolizer = (rule) => !isLabelSymbolizer(rule)
66
107
  // Support v1.x as well as v2.x
67
108
  rules.paint_rules = rules.paintRules = _.filter(styleRules, isNotLabelSymbolizer)
68
109
  rules.label_rules = rules.labelRules = _.filter(styleRules, isLabelSymbolizer)
110
+ } else if (styleType === 'kdk') {
111
+ // Translate kdk style to protomap rules
112
+ rules = kdk_style(style, leafletOptions.dataLayer)
113
+ }
114
+ if (options.filters) {
115
+ // Translate layer filters to filter function
116
+ const filterFn = layers.getFilterFunctionFromLayerFilters(options)
117
+ rules.paintRules.forEach(rule => {
118
+ // kdkFilter member may not be present, this is added by kdk_style when translating kdk style
119
+ // to leaflet-protomaps rules
120
+ if (rule.kdkFilter) {
121
+ rule.filter = (zoom, feature) => {
122
+ // Final filter = kdk style filter + updated filter
123
+ return rule.kdkFilter(zoom, feature) && filterFn({ zoom, feature, properties: feature.props })
124
+ }
125
+ } else {
126
+ rule.filter = (zoom, feature) => filterFn({ zoom, feature, properties: feature.props })
127
+ }
128
+ })
69
129
  }
70
130
  }
71
131
 
@@ -82,9 +142,16 @@ export const pmtilesLayers = {
82
142
  // Skip invisible layers
83
143
  isVisible: true
84
144
  }))
85
- pmtileslayers.forEach(async pmtileslayer => {
145
+ pmtileslayers.forEach(async pmtilesLayer => {
86
146
  // Retrieve the layer
87
- const layer = this.getLeafletLayerByName(pmtileslayer.name)
147
+ const layer = this.getLeafletLayerByName(pmtilesLayer.name)
148
+ const leafletOptions = pmtilesLayer.leaflet || pmtilesLayer
149
+ const urlTemplate = _.get(leafletOptions, 'urlTemplate')
150
+ if (urlTemplate) {
151
+ await this.processLeafletPMTilesLayer(pmtilesLayer, ['urlTemplate'])
152
+ // Need to update underlying PMTiles source
153
+ layer.views = protomaps.sourcesToViews(leafletOptions)
154
+ }
88
155
  layer.redraw()
89
156
  })
90
157
  },
@@ -100,20 +167,42 @@ export const pmtilesLayers = {
100
167
  layer.redraw()
101
168
  }
102
169
  }
170
+ },
171
+ onLayerFilterToggledPMTilesLayers (layer, filter) {
172
+ // Filtering is managed by mongodb query syntax, we need to update the filter function
173
+ const filterFn = layers.getFilterFunctionFromLayerFilters(layer)
174
+ // Retrieve the engine layer and update the filter function directly
175
+ layer = this.getLeafletLayerByName(layer. name)
176
+ if (!layer) return
177
+ layer.paintRules.forEach(rule => {
178
+ // kdkFilter member may not be present, this is added by kdk_style when translating kdk style
179
+ // to leaflet-protomaps rules
180
+ if (rule.kdkFilter) {
181
+ rule.filter = (zoom, feature) => {
182
+ // Final filter = kdk style filter + updated filter
183
+ return rule.kdkFilter(zoom, feature) && filterFn({ zoom, feature, properties: feature.props })
184
+ }
185
+ } else {
186
+ rule.filter = (zoom, feature) => filterFn({ zoom, feature, properties: feature.props })
187
+ }
188
+ })
189
+ layer.redraw()
103
190
  }
104
191
  },
105
192
  created () {
106
193
  this.registerLeafletConstructor(this.createLeafletPMTilesLayer)
107
194
  Events.on('time-current-time-changed', this.onCurrentTimeChangedPMTilesLayers)
108
195
  this.$engineEvents.on('selected-level-changed', this.onCurrentLevelChangedPMTilesLayers)
196
+ this.$engineEvents.on('layer-filter-toggled', this.onLayerFilterToggledPMTilesLayers)
109
197
  },
110
198
  beforeUnmount () {
111
199
  Events.off('time-current-time-changed', this.onCurrentTimeChangedPMTilesLayers)
112
200
  this.$engineEvents.off('selected-level-changed', this.onCurrentLevelChangedPMTilesLayers)
201
+ this.$engineEvents.off('layer-filter-toggled', this.onLayerFilterToggledPMTilesLayers)
113
202
  }
114
203
  }
115
204
 
116
205
  // Not automatically declared by leaflet plugin
117
206
  L.pmtiles = function (options) {
118
207
  return protomaps.leafletLayer(options)
119
- }
208
+ }
@@ -1,6 +1,8 @@
1
1
  import _ from 'lodash'
2
+ import moment from 'moment'
2
3
  import { Time } from '../../../../core/client/time.js'
3
4
  import { Events } from '../../../../core/client/events.js'
5
+ import * as time from '../../../../core/client/utils/utils.time.js'
4
6
  import { makeGridSource, extractGridSourceConfig } from '../../../common/grid.js'
5
7
  import { TiledMeshLayer } from '../../leaflet/TiledMeshLayer.js'
6
8
 
@@ -18,14 +20,19 @@ export const tiledMeshLayers = {
18
20
 
19
21
  // Build grid source
20
22
  const [gridKey, gridConf] = extractGridSourceConfig(options)
21
- const weacastApi = (typeof options.getPlanetApi === 'function' ? options.getPlanetApi() : this.getWeacastApi())
22
- const apiToken = (weacastApi.hasConfig('gatewayJwt') ? await weacastApi.get('storage').getItem(weacastApi.getConfig('gatewayJwt')) : null)
23
- const gridSource = makeGridSource(gridKey, { weacastApi, apiToken })
23
+ const planetApi = (typeof options.getPlanetApi === 'function' ? options.getPlanetApi() : this.getWeacastApi())
24
+ const apiJwt = (planetApi.hasConfig('apiJwt') ? await planetApi.get('storage').getItem(planetApi.getConfig('apiJwt')) : null)
25
+ const gatewayJwt = (planetApi.hasConfig('gatewayJwt') ? await planetApi.get('storage').getItem(planetApi.getConfig('gatewayJwt')) : null)
26
+ const gridSource = makeGridSource(gridKey, { planetApi })
24
27
  gridSource.setup(gridConf)
25
28
  if (gridSource.updateCtx) {
26
29
  // define variables for source's dynamic properties
27
- if (apiToken) gridSource.updateCtx.jwtToken = apiToken
28
- gridSource.updateCtx.meteoElements = _.get(options, 'meteoElements')
30
+ Object.assign(gridSource.updateCtx, {
31
+ apiJwt, gatewayJwt, moment, Time, ...time,
32
+ // This one is for backward compatibility
33
+ jwtToken: gatewayJwt,
34
+ meteoElements: _.get(options, 'meteoElements')
35
+ })
29
36
  }
30
37
 
31
38
  return new TiledMeshLayer(layerOptions, gridSource)