@kalisio/kdk 2.3.2 → 2.4.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 (441) hide show
  1. package/.eslintignore +2 -1
  2. package/.github/workflows/main.yaml +3 -3
  3. package/README.md +1 -0
  4. package/core/api/db.js +6 -1
  5. package/core/api/hooks/hooks.model.js +1 -1
  6. package/core/api/hooks/hooks.schemas.js +0 -2
  7. package/core/api/models/messages.model.mongodb.js +13 -0
  8. package/core/api/services/authorisations/authorisations.service.js +13 -4
  9. package/core/api/services/index.js +19 -0
  10. package/core/api/services/messages/messages.hooks.js +38 -0
  11. package/core/client/api.js +7 -32
  12. package/core/client/capabilities.js +2 -2
  13. package/core/client/components/KActivity.vue +29 -6
  14. package/core/client/components/KContent.vue +2 -2
  15. package/core/client/components/KDialog.vue +4 -7
  16. package/core/client/components/KStamp.vue +3 -9
  17. package/core/client/components/KStore.vue +2 -4
  18. package/core/client/components/KTab.vue +95 -0
  19. package/core/client/components/action/KAction.vue +15 -2
  20. package/core/client/components/action/KBugReportAction.vue +4 -2
  21. package/core/client/components/action/KToggleFullscreenAction.vue +25 -0
  22. package/core/client/components/app/KSettings.vue +17 -13
  23. package/core/client/components/chart/KDataTable.vue +6 -9
  24. package/core/client/components/chart/KTimeSeriesChart.vue +62 -49
  25. package/core/client/components/collection/KBoard.vue +22 -33
  26. package/core/client/components/collection/KCard.vue +71 -56
  27. package/core/client/components/collection/KCardSection.vue +20 -10
  28. package/core/client/components/collection/KDescriptionCardSection.vue +47 -0
  29. package/core/client/components/collection/KGrid.vue +234 -54
  30. package/core/client/components/collection/KScrollDown.vue +97 -0
  31. package/core/client/components/collection/KScrollToTop.vue +93 -0
  32. package/core/client/components/collection/KTable.vue +87 -33
  33. package/core/client/components/collection/KTimeLine.vue +406 -0
  34. package/core/client/components/collection/index.js +1 -5
  35. package/core/client/components/document/KDocument.vue +20 -55
  36. package/core/client/components/document/KHtml.vue +17 -7
  37. package/core/client/components/document/KImage.vue +78 -0
  38. package/core/client/components/document/KMarkdown.vue +12 -16
  39. package/core/client/components/document/KPdf.vue +69 -0
  40. package/core/client/components/form/KFileField.vue +2 -2
  41. package/core/client/components/form/KSelectField.vue +2 -1
  42. package/core/client/components/form/KUnitField.vue +3 -1
  43. package/core/client/components/layout/KFab.vue +9 -10
  44. package/core/client/components/layout/KLayout.vue +104 -6
  45. package/core/client/components/layout/KOpener.vue +14 -19
  46. package/core/client/components/layout/KPage.vue +195 -105
  47. package/core/client/components/layout/KWindow.vue +54 -32
  48. package/core/client/components/layout/index.js +0 -2
  49. package/core/client/components/media/KRibbon.vue +95 -0
  50. package/core/client/components/menu/KMenu.vue +4 -4
  51. package/core/client/components/team/KGroupsActivity.vue +25 -27
  52. package/core/client/components/team/KMembersActivity.vue +21 -23
  53. package/core/client/components/team/KOrganisationsActivity.vue +20 -22
  54. package/core/client/components/team/KTagsActivity.vue +21 -23
  55. package/core/client/components/time/KAbsoluteTimeRange.vue +70 -170
  56. package/core/client/composables/activity.js +14 -12
  57. package/core/client/composables/collection.js +3 -1
  58. package/core/client/composables/counter.js +51 -0
  59. package/core/client/composables/index.js +3 -0
  60. package/core/client/composables/layout.js +13 -2
  61. package/core/client/composables/messages.js +15 -0
  62. package/core/client/composables/pwa.js +1 -1
  63. package/core/client/composables/schema.js +6 -6
  64. package/core/client/composables/screen.js +23 -0
  65. package/core/client/directives/index.js +1 -0
  66. package/core/client/directives/v-hover.js +23 -0
  67. package/core/client/document.js +61 -0
  68. package/core/client/exporter.js +1 -1
  69. package/core/client/filter.js +0 -1
  70. package/core/client/guards.js +1 -1
  71. package/core/client/i18n/core_en.json +14 -8
  72. package/core/client/i18n/core_fr.json +15 -9
  73. package/core/client/index.js +9 -3
  74. package/core/client/layout.js +129 -29
  75. package/core/client/local-storage.js +1 -1
  76. package/core/client/mixins/index.js +0 -1
  77. package/core/client/mixins/mixin.base-activity.js +23 -13
  78. package/core/client/mixins/mixin.base-item.js +6 -3
  79. package/core/client/services/index.js +4 -1
  80. package/core/client/services/local-settings.service.js +4 -0
  81. package/core/client/storage.js +1 -1
  82. package/core/client/store.js +1 -1
  83. package/core/client/template-context.js +17 -0
  84. package/core/client/units.js +49 -27
  85. package/core/client/utils/index.js +3 -2
  86. package/core/client/utils/utils.actions.js +4 -0
  87. package/core/client/utils/utils.colors.js +155 -2
  88. package/core/client/utils/utils.items.js +26 -0
  89. package/core/client/utils/utils.math.js +3 -0
  90. package/core/client/utils/utils.platform.js +3 -1
  91. package/core/client/utils/utils.screen.js +82 -0
  92. package/core/client/utils/utils.time.js +0 -1
  93. package/core/common/schemas/settings.update.json +12 -0
  94. package/coverage/base.css +224 -0
  95. package/coverage/block-navigation.js +87 -0
  96. package/coverage/core/api/application.js.html +1870 -0
  97. package/coverage/core/api/authentication.js.html +742 -0
  98. package/coverage/core/api/db.js.html +793 -0
  99. package/coverage/core/api/hooks/hooks.authentication.js.html +313 -0
  100. package/coverage/core/api/hooks/hooks.authorisations.js.html +1243 -0
  101. package/coverage/core/api/hooks/hooks.groups.js.html +229 -0
  102. package/coverage/core/api/hooks/hooks.logger.js.html +163 -0
  103. package/coverage/core/api/hooks/hooks.model.js.html +955 -0
  104. package/coverage/core/api/hooks/hooks.organisations.js.html +541 -0
  105. package/coverage/core/api/hooks/hooks.push.js.html +253 -0
  106. package/coverage/core/api/hooks/hooks.query.js.html +862 -0
  107. package/coverage/core/api/hooks/hooks.schemas.js.html +298 -0
  108. package/coverage/core/api/hooks/hooks.service.js.html +319 -0
  109. package/coverage/core/api/hooks/hooks.storage.js.html +193 -0
  110. package/coverage/core/api/hooks/hooks.users.js.html +868 -0
  111. package/coverage/core/api/hooks/index.html +296 -0
  112. package/coverage/core/api/hooks/index.js.html +121 -0
  113. package/coverage/core/api/index.html +191 -0
  114. package/coverage/core/api/index.js.html +148 -0
  115. package/coverage/core/api/marshall.js.html +448 -0
  116. package/coverage/core/api/models/groups.model.mongodb.js.html +109 -0
  117. package/coverage/core/api/models/index.html +176 -0
  118. package/coverage/core/api/models/messages.model.mongodb.js.html +121 -0
  119. package/coverage/core/api/models/organisations.model.mongodb.js.html +94 -0
  120. package/coverage/core/api/models/tags.model.mongodb.js.html +115 -0
  121. package/coverage/core/api/models/users.model.mongodb.js.html +115 -0
  122. package/coverage/core/api/services/account/account.hooks.js.html +208 -0
  123. package/coverage/core/api/services/account/account.service.js.html +436 -0
  124. package/coverage/core/api/services/account/index.html +131 -0
  125. package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +184 -0
  126. package/coverage/core/api/services/authorisations/authorisations.service.js.html +529 -0
  127. package/coverage/core/api/services/authorisations/index.html +131 -0
  128. package/coverage/core/api/services/databases/databases.hooks.js.html +193 -0
  129. package/coverage/core/api/services/databases/databases.service.js.html +100 -0
  130. package/coverage/core/api/services/databases/index.html +131 -0
  131. package/coverage/core/api/services/groups/groups.hooks.js.html +178 -0
  132. package/coverage/core/api/services/groups/index.html +116 -0
  133. package/coverage/core/api/services/import-export/import-export.hooks.js.html +184 -0
  134. package/coverage/core/api/services/import-export/import-export.service.js.html +118 -0
  135. package/coverage/core/api/services/import-export/index.html +131 -0
  136. package/coverage/core/api/services/index.html +116 -0
  137. package/coverage/core/api/services/index.js.html +556 -0
  138. package/coverage/core/api/services/mailer/index.html +131 -0
  139. package/coverage/core/api/services/mailer/mailer.hooks.js.html +190 -0
  140. package/coverage/core/api/services/mailer/mailer.service.js.html +118 -0
  141. package/coverage/core/api/services/messages/index.html +116 -0
  142. package/coverage/core/api/services/messages/messages.hooks.js.html +199 -0
  143. package/coverage/core/api/services/organisations/index.html +131 -0
  144. package/coverage/core/api/services/organisations/organisations.hooks.js.html +178 -0
  145. package/coverage/core/api/services/organisations/organisations.service.js.html +343 -0
  146. package/coverage/core/api/services/push/index.html +131 -0
  147. package/coverage/core/api/services/push/push.hooks.js.html +190 -0
  148. package/coverage/core/api/services/push/push.service.js.html +121 -0
  149. package/coverage/core/api/services/storage/index.html +131 -0
  150. package/coverage/core/api/services/storage/storage.hooks.js.html +190 -0
  151. package/coverage/core/api/services/storage/storage.service.js.html +172 -0
  152. package/coverage/core/api/services/tags/index.html +116 -0
  153. package/coverage/core/api/services/tags/tags.hooks.js.html +178 -0
  154. package/coverage/core/api/services/users/index.html +116 -0
  155. package/coverage/core/api/services/users/users.hooks.js.html +307 -0
  156. package/coverage/core/api/utils.js.html +118 -0
  157. package/coverage/core/common/errors.js.html +88 -0
  158. package/coverage/core/common/index.html +176 -0
  159. package/coverage/core/common/index.js.html +115 -0
  160. package/coverage/core/common/permissions.js.html +1048 -0
  161. package/coverage/core/common/schema.js.html +190 -0
  162. package/coverage/core/common/utils.js.html +220 -0
  163. package/coverage/favicon.png +0 -0
  164. package/coverage/index.html +506 -0
  165. package/coverage/lcov-report/base.css +224 -0
  166. package/coverage/lcov-report/block-navigation.js +87 -0
  167. package/coverage/lcov-report/core/api/application.js.html +1870 -0
  168. package/coverage/lcov-report/core/api/authentication.js.html +742 -0
  169. package/coverage/lcov-report/core/api/db.js.html +793 -0
  170. package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +313 -0
  171. package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +1243 -0
  172. package/coverage/lcov-report/core/api/hooks/hooks.groups.js.html +229 -0
  173. package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +163 -0
  174. package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +955 -0
  175. package/coverage/lcov-report/core/api/hooks/hooks.organisations.js.html +541 -0
  176. package/coverage/lcov-report/core/api/hooks/hooks.push.js.html +253 -0
  177. package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +862 -0
  178. package/coverage/lcov-report/core/api/hooks/hooks.schemas.js.html +298 -0
  179. package/coverage/lcov-report/core/api/hooks/hooks.service.js.html +319 -0
  180. package/coverage/lcov-report/core/api/hooks/hooks.storage.js.html +193 -0
  181. package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +868 -0
  182. package/coverage/lcov-report/core/api/hooks/index.html +296 -0
  183. package/coverage/lcov-report/core/api/hooks/index.js.html +121 -0
  184. package/coverage/lcov-report/core/api/index.html +191 -0
  185. package/coverage/lcov-report/core/api/index.js.html +148 -0
  186. package/coverage/lcov-report/core/api/marshall.js.html +448 -0
  187. package/coverage/lcov-report/core/api/models/groups.model.mongodb.js.html +109 -0
  188. package/coverage/lcov-report/core/api/models/index.html +176 -0
  189. package/coverage/lcov-report/core/api/models/messages.model.mongodb.js.html +121 -0
  190. package/coverage/lcov-report/core/api/models/organisations.model.mongodb.js.html +94 -0
  191. package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +115 -0
  192. package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +115 -0
  193. package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +208 -0
  194. package/coverage/lcov-report/core/api/services/account/account.service.js.html +436 -0
  195. package/coverage/lcov-report/core/api/services/account/index.html +131 -0
  196. package/coverage/lcov-report/core/api/services/authorisations/authorisations.hooks.js.html +184 -0
  197. package/coverage/lcov-report/core/api/services/authorisations/authorisations.service.js.html +529 -0
  198. package/coverage/lcov-report/core/api/services/authorisations/index.html +131 -0
  199. package/coverage/lcov-report/core/api/services/databases/databases.hooks.js.html +193 -0
  200. package/coverage/lcov-report/core/api/services/databases/databases.service.js.html +100 -0
  201. package/coverage/lcov-report/core/api/services/databases/index.html +131 -0
  202. package/coverage/lcov-report/core/api/services/groups/groups.hooks.js.html +178 -0
  203. package/coverage/lcov-report/core/api/services/groups/index.html +116 -0
  204. package/coverage/lcov-report/core/api/services/import-export/import-export.hooks.js.html +184 -0
  205. package/coverage/lcov-report/core/api/services/import-export/import-export.service.js.html +118 -0
  206. package/coverage/lcov-report/core/api/services/import-export/index.html +131 -0
  207. package/coverage/lcov-report/core/api/services/index.html +116 -0
  208. package/coverage/lcov-report/core/api/services/index.js.html +556 -0
  209. package/coverage/lcov-report/core/api/services/mailer/index.html +131 -0
  210. package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +190 -0
  211. package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +118 -0
  212. package/coverage/lcov-report/core/api/services/messages/index.html +116 -0
  213. package/coverage/lcov-report/core/api/services/messages/messages.hooks.js.html +199 -0
  214. package/coverage/lcov-report/core/api/services/organisations/index.html +131 -0
  215. package/coverage/lcov-report/core/api/services/organisations/organisations.hooks.js.html +178 -0
  216. package/coverage/lcov-report/core/api/services/organisations/organisations.service.js.html +343 -0
  217. package/coverage/lcov-report/core/api/services/push/index.html +131 -0
  218. package/coverage/lcov-report/core/api/services/push/push.hooks.js.html +190 -0
  219. package/coverage/lcov-report/core/api/services/push/push.service.js.html +121 -0
  220. package/coverage/lcov-report/core/api/services/storage/index.html +131 -0
  221. package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +190 -0
  222. package/coverage/lcov-report/core/api/services/storage/storage.service.js.html +172 -0
  223. package/coverage/lcov-report/core/api/services/tags/index.html +116 -0
  224. package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +178 -0
  225. package/coverage/lcov-report/core/api/services/users/index.html +116 -0
  226. package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +307 -0
  227. package/coverage/lcov-report/core/api/utils.js.html +118 -0
  228. package/coverage/lcov-report/core/common/errors.js.html +88 -0
  229. package/coverage/lcov-report/core/common/index.html +176 -0
  230. package/coverage/lcov-report/core/common/index.js.html +115 -0
  231. package/coverage/lcov-report/core/common/permissions.js.html +1048 -0
  232. package/coverage/lcov-report/core/common/schema.js.html +190 -0
  233. package/coverage/lcov-report/core/common/utils.js.html +220 -0
  234. package/coverage/lcov-report/favicon.png +0 -0
  235. package/coverage/lcov-report/index.html +506 -0
  236. package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +457 -0
  237. package/coverage/lcov-report/map/api/hooks/hooks.features.js.html +397 -0
  238. package/coverage/lcov-report/map/api/hooks/hooks.query.js.html +1309 -0
  239. package/coverage/lcov-report/map/api/hooks/index.html +161 -0
  240. package/coverage/lcov-report/map/api/hooks/index.js.html +94 -0
  241. package/coverage/lcov-report/map/api/index.html +131 -0
  242. package/coverage/lcov-report/map/api/index.js.html +139 -0
  243. package/coverage/lcov-report/map/api/marshall.js.html +178 -0
  244. package/coverage/lcov-report/map/api/models/alerts.model.mongodb.js.html +106 -0
  245. package/coverage/lcov-report/map/api/models/catalog.model.mongodb.js.html +127 -0
  246. package/coverage/lcov-report/map/api/models/features.model.mongodb.js.html +196 -0
  247. package/coverage/lcov-report/map/api/models/index.html +161 -0
  248. package/coverage/lcov-report/map/api/models/projects.model.mongodb.js.html +109 -0
  249. package/coverage/lcov-report/map/api/services/alerts/alerts.hooks.js.html +274 -0
  250. package/coverage/lcov-report/map/api/services/alerts/alerts.service.js.html +610 -0
  251. package/coverage/lcov-report/map/api/services/alerts/index.html +131 -0
  252. package/coverage/lcov-report/map/api/services/catalog/catalog.hooks.js.html +310 -0
  253. package/coverage/lcov-report/map/api/services/catalog/index.html +116 -0
  254. package/coverage/lcov-report/map/api/services/daptiles/daptiles.service.js.html +1510 -0
  255. package/coverage/lcov-report/map/api/services/daptiles/index.html +116 -0
  256. package/coverage/lcov-report/map/api/services/features/features.hooks.js.html +241 -0
  257. package/coverage/lcov-report/map/api/services/features/features.service.js.html +241 -0
  258. package/coverage/lcov-report/map/api/services/features/index.html +131 -0
  259. package/coverage/lcov-report/map/api/services/index.html +116 -0
  260. package/coverage/lcov-report/map/api/services/index.js.html +817 -0
  261. package/coverage/lcov-report/map/api/services/projects/index.html +116 -0
  262. package/coverage/lcov-report/map/api/services/projects/projects.hooks.js.html +439 -0
  263. package/coverage/lcov-report/map/common/dynamic-grid-source.js.html +466 -0
  264. package/coverage/lcov-report/map/common/errors.js.html +94 -0
  265. package/coverage/lcov-report/map/common/geotiff-grid-source.js.html +541 -0
  266. package/coverage/lcov-report/map/common/grid.js.html +1612 -0
  267. package/coverage/lcov-report/map/common/index.html +371 -0
  268. package/coverage/lcov-report/map/common/index.js.html +172 -0
  269. package/coverage/lcov-report/map/common/meteo-model-grid-source.js.html +556 -0
  270. package/coverage/lcov-report/map/common/moment-utils.js.html +157 -0
  271. package/coverage/lcov-report/map/common/opendap-grid-source.js.html +868 -0
  272. package/coverage/lcov-report/map/common/opendap-utils.js.html +826 -0
  273. package/coverage/lcov-report/map/common/permissions.js.html +124 -0
  274. package/coverage/lcov-report/map/common/time-based-grid-source.js.html +418 -0
  275. package/coverage/lcov-report/map/common/tms-utils.js.html +274 -0
  276. package/coverage/lcov-report/map/common/wcs-grid-source.js.html +364 -0
  277. package/coverage/lcov-report/map/common/wcs-utils.js.html +586 -0
  278. package/coverage/lcov-report/map/common/weacast-grid-source.js.html +1033 -0
  279. package/coverage/lcov-report/map/common/wfs-utils.js.html +574 -0
  280. package/coverage/lcov-report/map/common/wms-utils.js.html +451 -0
  281. package/coverage/lcov-report/map/common/wmts-utils.js.html +547 -0
  282. package/coverage/lcov-report/prettify.css +1 -0
  283. package/coverage/lcov-report/prettify.js +2 -0
  284. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  285. package/coverage/lcov-report/sorter.js +196 -0
  286. package/coverage/lcov.info +11245 -0
  287. package/coverage/map/api/hooks/hooks.catalog.js.html +457 -0
  288. package/coverage/map/api/hooks/hooks.features.js.html +397 -0
  289. package/coverage/map/api/hooks/hooks.query.js.html +1309 -0
  290. package/coverage/map/api/hooks/index.html +161 -0
  291. package/coverage/map/api/hooks/index.js.html +94 -0
  292. package/coverage/map/api/index.html +131 -0
  293. package/coverage/map/api/index.js.html +139 -0
  294. package/coverage/map/api/marshall.js.html +178 -0
  295. package/coverage/map/api/models/alerts.model.mongodb.js.html +106 -0
  296. package/coverage/map/api/models/catalog.model.mongodb.js.html +127 -0
  297. package/coverage/map/api/models/features.model.mongodb.js.html +196 -0
  298. package/coverage/map/api/models/index.html +161 -0
  299. package/coverage/map/api/models/projects.model.mongodb.js.html +109 -0
  300. package/coverage/map/api/services/alerts/alerts.hooks.js.html +274 -0
  301. package/coverage/map/api/services/alerts/alerts.service.js.html +610 -0
  302. package/coverage/map/api/services/alerts/index.html +131 -0
  303. package/coverage/map/api/services/catalog/catalog.hooks.js.html +310 -0
  304. package/coverage/map/api/services/catalog/index.html +116 -0
  305. package/coverage/map/api/services/daptiles/daptiles.service.js.html +1510 -0
  306. package/coverage/map/api/services/daptiles/index.html +116 -0
  307. package/coverage/map/api/services/features/features.hooks.js.html +241 -0
  308. package/coverage/map/api/services/features/features.service.js.html +241 -0
  309. package/coverage/map/api/services/features/index.html +131 -0
  310. package/coverage/map/api/services/index.html +116 -0
  311. package/coverage/map/api/services/index.js.html +817 -0
  312. package/coverage/map/api/services/projects/index.html +116 -0
  313. package/coverage/map/api/services/projects/projects.hooks.js.html +439 -0
  314. package/coverage/map/common/dynamic-grid-source.js.html +466 -0
  315. package/coverage/map/common/errors.js.html +94 -0
  316. package/coverage/map/common/geotiff-grid-source.js.html +541 -0
  317. package/coverage/map/common/grid.js.html +1612 -0
  318. package/coverage/map/common/index.html +371 -0
  319. package/coverage/map/common/index.js.html +172 -0
  320. package/coverage/map/common/meteo-model-grid-source.js.html +556 -0
  321. package/coverage/map/common/moment-utils.js.html +157 -0
  322. package/coverage/map/common/opendap-grid-source.js.html +868 -0
  323. package/coverage/map/common/opendap-utils.js.html +826 -0
  324. package/coverage/map/common/permissions.js.html +124 -0
  325. package/coverage/map/common/time-based-grid-source.js.html +418 -0
  326. package/coverage/map/common/tms-utils.js.html +274 -0
  327. package/coverage/map/common/wcs-grid-source.js.html +364 -0
  328. package/coverage/map/common/wcs-utils.js.html +586 -0
  329. package/coverage/map/common/weacast-grid-source.js.html +1033 -0
  330. package/coverage/map/common/wfs-utils.js.html +574 -0
  331. package/coverage/map/common/wms-utils.js.html +451 -0
  332. package/coverage/map/common/wmts-utils.js.html +547 -0
  333. package/coverage/prettify.css +1 -0
  334. package/coverage/prettify.js +2 -0
  335. package/coverage/sort-arrow-sprite.png +0 -0
  336. package/coverage/sorter.js +196 -0
  337. package/coverage/tmp/coverage-280506-1731704745613-0.json +1 -0
  338. package/coverage/tmp/coverage-280518-1731704745599-0.json +1 -0
  339. package/coverage/tmp/coverage-280529-1731704745588-0.json +1 -0
  340. package/coverage/tmp/coverage-280541-1731704745574-0.json +1 -0
  341. package/coverage/tmp/coverage-280548-1731704745545-0.json +1 -0
  342. package/extras/css/core.variables.scss +32 -8
  343. package/extras/icons/attribution.png +0 -0
  344. package/map/api/services/catalog/catalog.hooks.js +5 -7
  345. package/map/api/services/features/features.hooks.js +1 -1
  346. package/map/client/cesium/utils/utils.style.js +11 -2
  347. package/map/client/components/KAttribution.vue +108 -0
  348. package/map/client/components/KPositionIndicator.vue +11 -18
  349. package/map/client/components/KProjectMenu.vue +4 -4
  350. package/map/client/components/catalog/KCategoryItem.vue +74 -0
  351. package/map/client/components/catalog/KLayerCategories.vue +24 -12
  352. package/map/client/components/catalog/KLayersPanel.vue +139 -116
  353. package/map/client/components/catalog/KProjectSelector.vue +29 -17
  354. package/map/client/components/catalog/KProjectsPanel.vue +19 -35
  355. package/map/client/components/catalog/KViewSelector.vue +37 -25
  356. package/map/client/components/catalog/KViewsPanel.vue +19 -35
  357. package/map/client/components/form/KLocationField.vue +1 -2
  358. package/map/client/components/legend/KLegend.vue +34 -34
  359. package/map/client/components/location/KLocationCardSection.vue +18 -22
  360. package/map/client/components/location/KLocationMap.vue +36 -38
  361. package/map/client/components/location/KLocationTimeLineCard.vue +147 -0
  362. package/map/client/components/location/KLocationTip.vue +12 -2
  363. package/map/client/components/widget/KInformationBox.vue +0 -4
  364. package/map/client/components/widget/KStackableTimeSeries.vue +8 -1
  365. package/map/client/components/widget/KTimeSeries.vue +1 -1
  366. package/map/client/composables/highlight.js +29 -31
  367. package/map/client/composables/probe.js +7 -3
  368. package/map/client/composables/weather.js +71 -31
  369. package/map/client/i18n/map_en.json +3 -0
  370. package/map/client/i18n/map_fr.json +3 -0
  371. package/map/client/init.js +4 -3
  372. package/map/client/leaflet/ShapeMarker.js +1 -1
  373. package/map/client/leaflet/utils/utils.events.js +1 -1
  374. package/map/client/leaflet/utils/utils.style.js +20 -8
  375. package/map/client/mixins/globe/mixin.base-globe.js +111 -13
  376. package/map/client/mixins/globe/mixin.file-layers.js +10 -10
  377. package/map/client/mixins/globe/mixin.geojson-layers.js +90 -15
  378. package/map/client/mixins/globe/mixin.style.js +2 -0
  379. package/map/client/mixins/index.js +0 -1
  380. package/map/client/mixins/map/index.js +1 -0
  381. package/map/client/mixins/map/mixin.base-map.js +21 -2
  382. package/map/client/mixins/map/mixin.canvas-layers.js +7 -2
  383. package/map/client/mixins/map/mixin.edit-layers.js +12 -4
  384. package/map/client/mixins/map/mixin.file-layers.js +3 -0
  385. package/map/client/mixins/map/mixin.geojson-layers.js +90 -5
  386. package/map/client/mixins/map/mixin.pmtiles-layers.js +106 -0
  387. package/map/client/mixins/mixin.activity.js +8 -3
  388. package/map/client/mixins/mixin.feature-service.js +73 -32
  389. package/map/client/mixins/mixin.levels.js +1 -0
  390. package/map/client/mixins/mixin.weacast.js +10 -87
  391. package/map/client/utils/index.js +1 -0
  392. package/map/client/utils/utils.capture.js +1 -1
  393. package/map/client/utils/utils.catalog.js +7 -7
  394. package/map/client/utils/utils.features.js +59 -1
  395. package/map/client/utils/utils.layers.js +8 -0
  396. package/map/client/utils/utils.time-series.js +121 -0
  397. package/map/client/utils/utils.weacast.js +102 -0
  398. package/package.json +6 -6
  399. package/scripts/init_runner.sh +2 -2
  400. package/scripts/kash/CHANGELOG.md +12 -0
  401. package/scripts/kash/README.md +2 -0
  402. package/scripts/kash/kash.sh +34 -32
  403. package/scripts/run_tests.sh +2 -2
  404. package/scripts/setup_workspace.sh +24 -6
  405. package/test/api/core/hooks.test.js +6 -3
  406. package/test/api/core/test-log-2023-12-19.log +7 -0
  407. package/test/api/core/test-log-2024-01-04.log +14 -0
  408. package/test/api/core/test-log-2024-05-14.log +6 -0
  409. package/test/api/core/{test-log-2024-04-23.log → test-log-2024-06-06.log} +3 -3
  410. package/test/api/core/test-log-2024-06-26.log +25 -0
  411. package/test/api/core/test-log-2024-06-28.log +2 -0
  412. package/test/api/core/test-log-2024-07-09.log +0 -0
  413. package/test/api/core/test-log-2024-08-13.log +69 -0
  414. package/test/api/core/test-log-2024-10-28.log +53 -0
  415. package/test/api/core/test-log-2024-11-05.log +30 -0
  416. package/test/api/core/test-log-2024-11-15.log +23 -0
  417. package/test/api/map/alerts.test.js +3 -1
  418. package/test/api/map/config/layers.json +3 -1
  419. package/test/api/map/index.test.js +18 -1
  420. package/test/api/map/test-log-2023-11-24.log +121 -0
  421. package/test/api/map/test-log-2023-12-12.log +29 -0
  422. package/test/api/map/test-log-2023-12-13.log +5 -0
  423. package/test/api/map/test-log-2024-01-04.log +2 -0
  424. package/test/api/map/test-log-2024-01-11.log +1 -0
  425. package/test/api/map/test-log-2024-01-25.log +19 -0
  426. package/test/api/map/test-log-2024-06-06.log +39 -0
  427. package/test/api/map/test-log-2024-08-13.log +13 -0
  428. package/test/api/map/test-log-2024-08-20.log +55 -0
  429. package/test/api/map/test-log-2024-09-09.log +92 -0
  430. package/test/api/map/test-log-2024-10-28.log +11 -0
  431. package/test/client/core/utils.js +13 -0
  432. package/test/client/map/api.js +34 -0
  433. package/test/client/map/catalog.js +6 -2
  434. package/test/client/map/index.js +1 -0
  435. package/test/client/map/utils.js +4 -2
  436. package/core/client/components/collection/KList.vue +0 -135
  437. package/core/client/components/layout/KPageSticky.vue +0 -53
  438. package/core/client/mixins/mixin.base-collection.js +0 -162
  439. package/core/client/utils/utils.data.js +0 -22
  440. package/map/client/mixins/mixin.catalog-panel.js +0 -26
  441. package/test/api/core/test-log-2024-04-22.log +0 -84
@@ -35,13 +35,13 @@ export function useProbe (name, options = {}) {
35
35
  return activity && activity.isCursor('probe-cursor')
36
36
  }
37
37
  function hasProbedLayer () {
38
- return isProbing() && get('item') && get('item').layer
38
+ return get('item') && get('item').layer
39
39
  }
40
40
  function getProbedLayer () {
41
41
  return get('item').layer
42
42
  }
43
43
  function hasProbedLocation () {
44
- return isProbing() && get('item') && get('item').location
44
+ return get('item') && get('item').location
45
45
  }
46
46
  function getProbedLocation () {
47
47
  return get('item').location
@@ -68,7 +68,11 @@ export function useProbe (name, options = {}) {
68
68
  let lastClickedPosition
69
69
  function onClicked (layer, event) {
70
70
  if (!isProbing()) {
71
- if (get('item')) clearProbe()
71
+ if (get('item')) {
72
+ const feature = _.get(event, 'target.feature')
73
+ // If not clicking directly on the map we don't cancel last probe, eg feature selection
74
+ if (!feature) clearProbe()
75
+ }
72
76
  return
73
77
  }
74
78
  // FIXME: For some layers, eg based on path, we get a first click with the layer as target
@@ -3,6 +3,7 @@ import L from 'leaflet'
3
3
  import moment from 'moment'
4
4
  import { unref, watch } from 'vue'
5
5
  import { Time } from '../../../core/client/time.js'
6
+ import { i18n } from '../../../core/client/i18n.js'
6
7
  import { Units } from '../../../core/client/units.js'
7
8
  import * as composables from '../../../core/client/composables/index.js'
8
9
  import { getNearestTime } from '../utils.js'
@@ -24,35 +25,68 @@ export function useWeather (options = {}) {
24
25
  // data
25
26
 
26
27
  // functions
27
- function getProbedLocationForecastFields () {
28
- return {
28
+ function getProbedLocationForecastFields (variables) {
29
+ const fields = {
29
30
  // Only wind/temperature can be available at different levels now
30
- windDirection: (activity.forecastLevel ? `properties.windDirection-${activity.forecastLevel}` : 'properties.windDirection'),
31
- windSpeed: (activity.forecastLevel ? `properties.windSpeed-${activity.forecastLevel}` : 'properties.windSpeed'),
32
- temperature: (activity.forecastLevel ? `properties.temperature-${activity.forecastLevel}` : 'properties.temperature'),
33
- gust: 'properties.gust',
34
- precipitations: 'properties.precipitations',
35
- humidity: 'properties.humidity',
36
- time: 'forecastTime',
37
- name: 'properties.name'
31
+ windDirection: {
32
+ property: (activity.forecastLevel ? `properties.windDirection-${activity.forecastLevel}` : 'properties.windDirection')
33
+ },
34
+ windSpeed: {
35
+ property: (activity.forecastLevel ? `properties.windSpeed-${activity.forecastLevel}` : 'properties.windSpeed')
36
+ },
37
+ temperature: {
38
+ property: (activity.forecastLevel ? `properties.temperature-${activity.forecastLevel}` : 'properties.temperature')
39
+ },
40
+ gust: {
41
+ property: 'properties.gust',
42
+ label: 'max'
43
+ },
44
+ precipitations: {
45
+ property: 'properties.precipitations'
46
+ },
47
+ humidity: {
48
+ property: 'properties.humidity'
49
+ },
50
+ time: {
51
+ property: 'forecastTime'
52
+ },
53
+ name: {
54
+ property: 'properties.name'
55
+ }
56
+ }
57
+ // Any given variables to extract labels from ?
58
+ if (variables && variables.length > 0) {
59
+ _.forOwn(fields, (value, key) => {
60
+ // Take care that weather fields are prefixed by 'properties.' because they target feature
61
+ const variable = _.find(variables, { name: `${value.property.replace('properties.', '')}` })
62
+ if (variable) value.label = variable.label
63
+ })
38
64
  }
65
+ return fields
39
66
  }
40
67
  function isWeatherProbe (feature) {
41
68
  const { windDirection, windSpeed } = getProbedLocationForecastFields()
42
- return (_.has(feature, windDirection) &&
43
- _.has(feature, windSpeed))
69
+ return (_.has(feature, windDirection.property) &&
70
+ _.has(feature, windSpeed.property))
44
71
  }
45
72
  function getForecastAsHtml (feature, fields = {}) {
46
73
  const defaults = getProbedLocationForecastFields()
74
+ // Retrieve target labels
75
+ const windDirectionLabel = _.get(fields, 'windDirection.label', defaults.windDirection.label)
76
+ const windSpeedLabel = _.get(fields, 'windSpeed.label', defaults.windSpeed.label)
77
+ const gustLabel = _.get(fields, 'gust.label', defaults.gust.label)
78
+ const temperatureLabel = _.get(fields, 'temperature.label', defaults.temperature.label)
79
+ const precipitationsLabel = _.get(fields, 'precipitations.label', defaults.precipitations.label)
80
+ const humidityLabel = _.get(fields, 'humidity.label', defaults.humidity.label)
47
81
  // Retrieve target fields on feature
48
- const windDirectionField = _.get(fields, 'windDirection', defaults.windDirection)
49
- const windSpeedField = _.get(fields, 'windSpeed', defaults.windSpeed)
50
- const gustField = _.get(fields, 'gust', defaults.gust)
51
- const temperatureField = _.get(fields, 'temperature', defaults.temperature)
52
- const precipitationsField = _.get(fields, 'precipitations', defaults.precipitations)
53
- const humidityField = _.get(fields, 'humidity', defaults.humidity)
54
- const timeField = _.get(fields, 'time', defaults.time)
55
- const nameField = _.get(fields, 'name', defaults.name)
82
+ const windDirectionField = _.get(fields, 'windDirection.property', defaults.windDirection.property)
83
+ const windSpeedField = _.get(fields, 'windSpeed.property', defaults.windSpeed.property)
84
+ const gustField = _.get(fields, 'gust.property', defaults.gust.property)
85
+ const temperatureField = _.get(fields, 'temperature.property', defaults.temperature.property)
86
+ const precipitationsField = _.get(fields, 'precipitations.property', defaults.precipitations.property)
87
+ const humidityField = _.get(fields, 'humidity.property', defaults.humidity.property)
88
+ const timeField = _.get(fields, 'time.property', defaults.time.property)
89
+ const nameField = _.get(fields, 'name.property', defaults.name.property)
56
90
  // Then get values for fields
57
91
  const windDirection = _.get(feature, `${windDirectionField}`)
58
92
  const windSpeed = _.get(feature, `${windSpeedField}`)
@@ -83,36 +117,42 @@ export function useWeather (options = {}) {
83
117
  }
84
118
  let html = ''
85
119
  if (!_.isNil(windSpeed) && _.isFinite(windSpeed)) {
120
+ if (windSpeedLabel) html += `${i18n.tie(windSpeedLabel)}: `
86
121
  html += Units.format(windSpeed, 'm/s')
87
122
  // Add related time if any
88
123
  if (!uniqTime) html += getTimeAsHtml(_.get(time, windSpeedField.replace('properties.', '')))
89
124
  html += '</br>'
90
125
  }
91
126
  if (!_.isNil(gust) && _.isFinite(gust)) {
92
- html += `max ${Units.format(gust, 'm/s')}`
127
+ if (gustLabel) html += `${i18n.tie(gustLabel)}: `
128
+ html += Units.format(gust, 'm/s')
93
129
  // Add related time if any
94
130
  if (!uniqTime) html += getTimeAsHtml(_.get(time, gustField.replace('properties.', '')))
95
131
  html += '</br>'
96
132
  }
97
133
  if (!_.isNil(windDirection) && _.isFinite(windDirection)) {
134
+ if (windDirectionLabel) html += `${i18n.tie(windDirectionLabel)}: `
98
135
  html += Units.format(windDirection, 'deg')
99
136
  // Add related time if any
100
137
  if (!uniqTime) html += getTimeAsHtml(_.get(time, windDirectionField.replace('properties.', '')))
101
138
  html += '</br>'
102
139
  }
103
140
  if (!_.isNil(precipitations) && _.isFinite(precipitations)) {
141
+ if (precipitationsLabel) html += `${i18n.tie(precipitationsLabel)}: `
104
142
  html += Units.format(precipitations, 'mm/h')
105
143
  // Add related time if any
106
144
  if (!uniqTime) html += getTimeAsHtml(_.get(time, precipitationsField.replace('properties.', '')))
107
145
  html += '</br>'
108
146
  }
109
147
  if (!_.isNil(humidity) && _.isFinite(humidity)) {
148
+ if (humidityLabel) html += `${i18n.tie(humidityLabel)}: `
110
149
  html += `${humidity.toFixed(0)} %`
111
150
  // Add related time if any
112
151
  if (!uniqTime) html += getTimeAsHtml(_.get(time, humidityField.replace('properties.', '')))
113
152
  html += '</br>'
114
153
  }
115
154
  if (!_.isNil(temperature) && _.isFinite(temperature)) {
155
+ if (temperatureLabel) html += `${i18n.tie(temperatureLabel)}: `
116
156
  html += Units.format(temperature, 'degC')
117
157
  // Add related time if any
118
158
  if (!uniqTime) html += getTimeAsHtml(_.get(time, temperatureField.replace('properties.', '')))
@@ -124,7 +164,7 @@ export function useWeather (options = {}) {
124
164
  if (!_.isNil(name)) html = `<b><u>${name}</u></b></br>` + html
125
165
  // If we get a signle time for all field add it at the end
126
166
  if (uniqTime) {
127
- html += getTimeAsHtml(time)
167
+ html += getTimeAsHtml(time).trim().replace('(', '').replace(')', '')
128
168
  }
129
169
  }
130
170
  return html
@@ -160,8 +200,8 @@ export function useWeather (options = {}) {
160
200
  function getWindBarbOptions (feature, fields = {}) {
161
201
  const defaults = getProbedLocationForecastFields()
162
202
  // Retrieve target fields on feature
163
- let windDirection = _.get(fields, 'windDirection', defaults.windDirection)
164
- let windSpeed = _.get(fields, 'windSpeed', defaults.windSpeed)
203
+ let windDirection = _.get(fields, 'windDirection.property', defaults.windDirection.property)
204
+ let windSpeed = _.get(fields, 'windSpeed.property', defaults.windSpeed.property)
165
205
  // TODO: colorize according to temperature scale if ?
166
206
  // let temperature = _.get(fields, 'temperature', 'properties.temperature')
167
207
  // Then get values for fields
@@ -185,17 +225,17 @@ export function useWeather (options = {}) {
185
225
  forceDir: true
186
226
  }
187
227
  }
188
- function createWindBarbIcon (feature) {
189
- const options = getWindBarbOptions(feature)
190
- return (options ? new L.WindBarb.Icon(getWindBarbOptions(feature)) : null)
228
+ function createWindBarbIcon (feature, fields = {}) {
229
+ const options = getWindBarbOptions(feature, fields)
230
+ return (options ? new L.WindBarb.Icon(options) : null)
191
231
  }
192
- function getProbedLocationForecastTooltip (feature, layer, options) {
193
- const html = getForecastAsHtml(feature)
232
+ function getProbedLocationForecastTooltip (feature, layer, options, fields = {}) {
233
+ const html = getForecastAsHtml(feature, fields)
194
234
  return (html ? L.tooltip({ permanent: false }, layer).setContent(`<b>${html}</b>`) : null)
195
235
  }
196
- function getProbedLocationForecastMarker (feature, latlng, options) {
236
+ function getProbedLocationForecastMarker (feature, latlng, options, fields = {}) {
197
237
  // Use wind barbs on probed features
198
- const icon = createWindBarbIcon(feature)
238
+ const icon = createWindBarbIcon(feature, fields)
199
239
  return (icon ? L.marker(latlng, { icon }) : null)
200
240
  }
201
241
 
@@ -233,6 +233,9 @@
233
233
  "TIMELINE_INTERVAL": "Real-time data refresh update interval",
234
234
  "TIMESERIES_SETTINGS": "Timeseries parameters",
235
235
  "TIMESERIES_SPAN": "Timeseries span (in hours)",
236
+ "TIMESERIES_GROUP_BY": "Timeseries grouping",
237
+ "TIMESERIES_GROUP_BY_VARIABLE": "Broup by variable",
238
+ "TIMESERIES_GROUP_BY_FEATURE": "Group by geographical feature",
236
239
  "CAPTURE_RESOLUTION_FIELD_LABEL": "Resolution setting",
237
240
  "CAPTURE_HEADER_FIELD_LABEL": "Title setting",
238
241
  "CAPTURE_FOOTER_FIELD_LABEL": "Footer setting",
@@ -233,6 +233,9 @@
233
233
  "TIMELINE_INTERVAL": "Fréquence de rafraichissement des données en temps-réel",
234
234
  "TIMESERIES_SETTINGS": "Paramètrage des séries temporelles",
235
235
  "TIMESERIES_SPAN": "Intervalle des séries temporelles, en heures",
236
+ "TIMESERIES_GROUP_BY": "Regroupement des séries temporelles",
237
+ "TIMESERIES_GROUP_BY_VARIABLE": "Regroupement par variable",
238
+ "TIMESERIES_GROUP_BY_FEATURE": "Regroupement par élément géographique",
236
239
  "CAPTURE_RESOLUTION_FIELD_LABEL": "Paramétrez la résolution",
237
240
  "CAPTURE_HEADER_FIELD_LABEL": "Paramétrez le titre",
238
241
  "CAPTURE_FOOTER_FIELD_LABEL": "Paramétrez le pied de page",
@@ -33,7 +33,7 @@ export function setupApi (configuration) {
33
33
  export default async function init () {
34
34
  const api = this
35
35
 
36
- logger.debug('[KDK] initializing map module')
36
+ logger.debug('[KDK] Initializing map module')
37
37
 
38
38
  // Declare the built-in services, others are optional
39
39
  api.declareService('geocoder')
@@ -83,12 +83,13 @@ export default async function init () {
83
83
  }))
84
84
  // Default timeseries parameters
85
85
  Store.set('timeseries', reactive({
86
- span: 1440 // 24H
86
+ span: 1440, // 24H
87
+ groupBy: 'feature'
87
88
  }))
88
89
 
89
90
  // Register the readers
90
91
  _.forEach(_.get(config, 'readers.map', []), entry => {
91
- logger.debug(`[KDK] registering mime types [${entry.mimeTypes}] to reader ${entry.reader}`)
92
+ logger.debug(`[KDK] Registering mime types [${entry.mimeTypes}] to reader ${entry.reader}`)
92
93
  Reader.register(entry.mimeTypes, readers[entry.reader])
93
94
  })
94
95
 
@@ -10,7 +10,7 @@ export const ShapeMarker = L.Marker.extend({
10
10
  // Forward extra options for different purposes, i.e. clustering, panes, ...
11
11
  const markerOptions = _.get(options, 'options', {})
12
12
  // We allow to specify panes directly at root level
13
- Object.assign(markerOptions, _.pick(options, ['pane', 'shadowPane']))
13
+ Object.assign(markerOptions, _.pick(options, ['pane', 'shadowPane', 'interactive', 'draggable']))
14
14
  if (options.icon instanceof L.Icon) { // We allow to directly provide the icon
15
15
  L.Marker.prototype.initialize.call(this, latlng, {
16
16
  icon: options.icon,
@@ -28,7 +28,7 @@ export const LeafletEvents = {
28
28
  Map: ['baselayerchange', 'overlayadd', 'overlayremove', 'layeradd', 'layerremove', 'zoomlevelschange',
29
29
  'resize', 'unload', 'viewreset', 'load',
30
30
  'zoomstart', 'boxzoomstart', 'boxselectionstart', 'movestart',
31
- 'zoom', 'move',
31
+ 'zoom', 'move', 'rotate',
32
32
  'zoomend', 'boxzoomend', 'boxselectionend', 'moveend',
33
33
  'click', 'dblclick', 'mousedown', 'mouseup', 'mouseover', 'mouseout', 'mousemove', 'contextmenu',
34
34
  'keypress', 'preclick', 'moveend', 'zoomanim', 'fullscreenchange'],
@@ -3,7 +3,7 @@ import logger from 'loglevel'
3
3
  import chroma from 'chroma-js'
4
4
  import moment from 'moment'
5
5
  import L from 'leaflet'
6
- import { Time, Units, utils as kdkCoreUtils } from '../../../../core/client/index.js'
6
+ import { Time, Units, TemplateContext, utils as kdkCoreUtils } from '../../../../core/client/index.js'
7
7
  import { getFeatureStyleType } from '../../utils/utils.features.js'
8
8
  import { convertStyle, convertSimpleStyleToPointStyle, convertSimpleStyleToLineStyle, convertSimpleStyleToPolygonStyle,
9
9
  PointStyleTemplateMappings, LineStyleTemplateMappings, PolygonStyleTemplateMappings } from '../../utils/utils.style.js'
@@ -151,7 +151,7 @@ function processStyle (style, feature, options, mappings) {
151
151
  const leafletOptions = options.leaflet || options
152
152
  // We allow to template style properties according to feature,
153
153
  // because it can be slow you have to specify a subset of properties
154
- const context = { properties: feature.properties, feature, chroma, moment, Units, Time }
154
+ const context = Object.assign({ properties: feature.properties, feature, chroma, moment, Units, Time }, TemplateContext.get())
155
155
  if (leafletOptions.template) {
156
156
  // Create the map of variables
157
157
  if (options.variables) context.variables = _.reduce(options.variables,
@@ -160,10 +160,22 @@ function processStyle (style, feature, options, mappings) {
160
160
  _.set(style, _.get(mappings, _.kebabCase(entry.property), entry.property), entry.compiler(context))
161
161
  })
162
162
  }
163
- // We manage panes for z-index, so we need to forward it to marker options (only if not already defined)
163
+
164
164
  const type = getFeatureStyleType(feature)
165
- if (leafletOptions.pane && !_.has(style, `${type}.pane`)) _.set(style, `${type}.pane`, leafletOptions.pane)
166
- if (leafletOptions.shadowPane && !_.has(style, `${type}.shadowPane`)) _.set(style, `${type}.shadowPane`, leafletOptions.shadowPane)
165
+
166
+ // visibility attribute can be used to hide individual features
167
+ // visibility is true by default but can also be a string when it's
168
+ // a result of a lodash steing template evaluation
169
+ let visibility = _.get(style, 'style.visibility', true)
170
+ if (typeof visibility === 'string') visibility = visibility === 'true'
171
+ // The 'kdk-hidden-features' pane is created when the leaflet map is initialized
172
+ if (!visibility) _.set(style, `style.${type}.pane`, 'kdk-hidden-features')
173
+
174
+ // We manage panes for z-index, so we need to forward it to marker options (only if not already defined)
175
+ if (leafletOptions.pane && !_.has(style, `style.${type}.pane`)) _.set(style, `style.${type}.pane`, leafletOptions.pane)
176
+ if (leafletOptions.shadowPane && !_.has(style, `style.${type}.shadowPane`)) _.set(style, `style.${type}.shadowPane`, leafletOptions.shadowPane)
177
+ // Similarly forward interactive option from layer if any
178
+ if (_.has(leafletOptions, 'interactive') && !_.has(style, `style.${type}.interactive`)) _.set(style, `style.${type}.interactive`, leafletOptions.interactive)
167
179
  return style
168
180
  }
169
181
 
@@ -171,7 +183,7 @@ export function getDefaultPointStyle (feature, options, engine, engineStylePath
171
183
  const engineStyle = _.get(engine, engineStylePath, {})
172
184
  const layerStyle = options ? _.get(options.leaflet || options, 'layerPointStyle') : {}
173
185
  const featureStyle = feature.style ? _.get(feature, 'style', {}) : convertSimpleStyleToPointStyle(feature.properties)
174
- const style = Object.assign({}, engineStyle, layerStyle, featureStyle)
186
+ const style = _.merge({}, engineStyle, layerStyle, featureStyle)
175
187
  processStyle({ style: { point: style } }, feature, options, PointStyleTemplateMappings)
176
188
  return style
177
189
  }
@@ -180,7 +192,7 @@ export function getDefaultLineStyle (feature, options, engine, engineStylePath =
180
192
  const engineStyle = _.get(engine, engineStylePath, {})
181
193
  const layerStyle = options ? _.get(options.leaflet || options, 'layerLineStyle') : {}
182
194
  const featureStyle = feature.style ? _.get(feature, 'style', {}) : convertSimpleStyleToLineStyle(feature.properties)
183
- const style = Object.assign({}, engineStyle, layerStyle, featureStyle)
195
+ const style = _.merge({}, engineStyle, layerStyle, featureStyle)
184
196
  processStyle({ style: { line: style } }, feature, options, LineStyleTemplateMappings)
185
197
  return convertLineStyleToLeafletPath(style)
186
198
  }
@@ -189,7 +201,7 @@ export function getDefaultPolygonStyle (feature, options, engine, engineStylePat
189
201
  const engineStyle = _.get(engine, engineStylePath, {})
190
202
  const layerStyle = options ? _.get(options.leaflet || options, 'layerPolygonStyle') : {}
191
203
  const featureStyle = feature.style ? _.get(feature, 'style', {}) : convertSimpleStyleToPolygonStyle(feature.properties)
192
- const style = Object.assign({}, engineStyle, layerStyle, featureStyle)
204
+ const style = _.merge({}, engineStyle, layerStyle, featureStyle)
193
205
  processStyle({ style: { polygon: style } }, feature, options, PolygonStyleTemplateMappings)
194
206
  return convertPolygonStyleToLeafletPath(style)
195
207
  }
@@ -5,7 +5,7 @@ import Emitter from 'tiny-emitter'
5
5
  import { getCssVar } from 'quasar'
6
6
  import { Ion, Viewer, Color, viewerCesiumInspectorMixin, Rectangle, ScreenSpaceEventType, ScreenSpaceEventHandler, buildModuleUrl,
7
7
  Cesium3DTileset, ImageryLayer, Cartesian3, PinBuilder, BoundingSphere, Ellipsoid, Cartographic, Entity, EntityCollection,
8
- exportKml, VerticalOrigin, Math as CesiumMath } from 'cesium'
8
+ exportKml, VerticalOrigin, Transforms, Quaternion, HeadingPitchRoll, Matrix3, Matrix4, DebugCameraPrimitive, DebugModelMatrixPrimitive, Math as CesiumMath } from 'cesium'
9
9
  import 'cesium/Source/Widgets/widgets.css'
10
10
  import { Geolocation } from '../../geolocation.js'
11
11
  import { Cesium, convertCesiumHandlerEvent, isTerrainLayer, convertEntitiesToGeoJson, createCesiumObject } from '../../utils.globe.js'
@@ -30,7 +30,7 @@ export const baseGlobe = {
30
30
  refreshGlobe () {
31
31
  },
32
32
  setupGlobe (domEl, token, options) {
33
- const viewerOptions = options ||
33
+ this.viewerOptions = options ||
34
34
  // For activities
35
35
  _.get(this, 'activityOptions.engine.viewer', {
36
36
  sceneMode: 3, // SceneMode.COLUMBUS_VIEW = 1, SceneMode.SCENE3D = 3,
@@ -50,21 +50,22 @@ export const baseGlobe = {
50
50
  // If we don't need ion
51
51
  else Ion.defaultAccessToken = ''
52
52
  // Initialize the globe
53
- Object.assign(viewerOptions, {
53
+ Object.assign(this.viewerOptions, {
54
54
  imageryProviderViewModels: [],
55
55
  terrainProviderViewModels: []
56
56
  })
57
- this.viewer = new Viewer(domEl, viewerOptions)
58
- const backgroundColor = _.get(viewerOptions, 'backgroundColor')
57
+ this.viewer = new Viewer(domEl, this.viewerOptions)
58
+ const backgroundColor = _.get(this.viewerOptions, 'backgroundColor')
59
59
  this.viewer.scene.backgroundColor = (backgroundColor ? createCesiumObject('Color', ...backgroundColor) : Color.BLACK)
60
60
  if (this.viewer.scene.globe) {
61
- const baseColor = _.get(viewerOptions, 'baseColor')
61
+ const baseColor = _.get(this.viewerOptions, 'baseColor')
62
62
  this.viewer.scene.globe.baseColor = (baseColor ? createCesiumObject('Color', ...baseColor) : Color.BLACK)
63
- const undergroundColor = _.get(viewerOptions, 'undergroundColor')
63
+ const undergroundColor = _.get(this.viewerOptions, 'undergroundColor')
64
64
  this.viewer.scene.globe.undergroundColor = (undergroundColor ? createCesiumObject('Color', ...undergroundColor) : Color.BLACK)
65
65
  }
66
66
  // Debug mode ?
67
- if (viewerOptions.debug) this.viewer.extend(viewerCesiumInspectorMixin)
67
+ //this.viewerOptions.debug = true
68
+ if (this.viewerOptions.debug) this.viewer.extend(viewerCesiumInspectorMixin)
68
69
  // Cesium always create a default provider when a globe is used
69
70
  if (this.viewer.scene.imageryLayers) this.viewer.scene.imageryLayers.removeAll()
70
71
  // Add defaults handler
@@ -229,7 +230,7 @@ export const baseGlobe = {
229
230
  this.viewer.dataSources.add(cesiumLayer)
230
231
  }
231
232
  layer.isVisible = true
232
- this.onLayerShown('layer-shown', layer, cesiumLayer)
233
+ this.onLayerShown(layer, cesiumLayer)
233
234
  },
234
235
  onLayerShown (layer, cesiumLayer) {
235
236
  this.$emit('layer-shown', layer, cesiumLayer)
@@ -351,17 +352,71 @@ export const baseGlobe = {
351
352
  center (longitude, latitude, altitude, heading = 0, pitch = -90, roll = 0, options = {}) {
352
353
  const center = this.viewer.camera.positionCartographic
353
354
  const duration = _.get(options, 'duration', 0)
355
+ // This is the "base" frame, position with orientation in east north up frame at position
356
+ const destination = Cartesian3.fromDegrees(longitude, latitude, altitude || center.height)
357
+ const orientation = new HeadingPitchRoll(
358
+ CesiumMath.toRadians(heading),
359
+ CesiumMath.toRadians(pitch),
360
+ CesiumMath.toRadians(roll))
361
+ // An offset can be provided relative to the base frame as an additional translation/rotation
362
+ // Typically the base frame can be set to "follow" a vehicle with its GPS position + heading.
363
+ // Then an offset can be used to take driver's position into account relative to the GPS,
364
+ // and simulate the moving head of the driver with an additional rotation
365
+ const destinationOffset = new Cartesian3(
366
+ _.get(options, 'offset.x', 0),
367
+ _.get(options, 'offset.y', 0),
368
+ _.get(options, 'offset.z', 0))
369
+ const orientationOffset = new HeadingPitchRoll(
370
+ CesiumMath.toRadians(_.get(options, 'offset.heading', 0)),
371
+ CesiumMath.toRadians(_.get(options, 'offset.pitch', 0)),
372
+ CesiumMath.toRadians(_.get(options, 'offset.roll', 0)))
354
373
  const target = {
355
- destination: Cartesian3.fromDegrees(longitude, latitude, altitude || center.height),
374
+ destination,
356
375
  orientation: {
357
- heading: CesiumMath.toRadians(heading),
358
- pitch: CesiumMath.toRadians(pitch),
359
- roll: CesiumMath.toRadians(roll)
376
+ heading: orientation.heading,
377
+ pitch: orientation.pitch,
378
+ roll: orientation.roll
360
379
  },
361
380
  duration
362
381
  }
363
382
  if (duration) this.viewer.camera.flyTo(target)
364
383
  else this.viewer.camera.setView(target)
384
+ this.viewer.camera.move(this.viewer.camera.right, destinationOffset.x)
385
+ this.viewer.camera.move(this.viewer.camera.direction, destinationOffset.y)
386
+ this.viewer.camera.move(this.viewer.camera.up, destinationOffset.z)
387
+ this.viewer.camera.look(this.viewer.camera.up, orientationOffset.heading)
388
+ this.viewer.camera.look(this.viewer.camera.direction, orientationOffset.pitch)
389
+ this.viewer.camera.look(this.viewer.camera.right, orientationOffset.roll)
390
+ if (this.viewerOptions.debug) {
391
+ const baseQuaternion = Transforms.headingPitchRollQuaternion(destination, orientation, Ellipsoid.WGS84, Transforms.eastNorthUpToFixedFrame)
392
+ const cameraQuaternion = Transforms.headingPitchRollQuaternion(this.viewer.camera.positionWC,
393
+ new HeadingPitchRoll(this.viewer.camera.heading, this.viewer.camera.pitch, this.viewer.camera.roll), Ellipsoid.WGS84, Transforms.eastNorthUpToFixedFrame)
394
+ if (this.baseFrameDebug) {
395
+ this.baseFrameDebug.modelMatrix = Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(baseQuaternion), destination)
396
+ this.finalFrameDebug.modelMatrix = Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(cameraQuaternion), this.viewer.camera.positionWC)
397
+ } else {
398
+ this.baseFrameDebug = new DebugModelMatrixPrimitive({
399
+ modelMatrix : Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(baseQuaternion), destination),
400
+ length : 25,
401
+ width : 5
402
+ })
403
+ this.viewer.scene.primitives.add(this.baseFrameDebug)
404
+ this.finalFrameDebug = new DebugModelMatrixPrimitive({
405
+ modelMatrix : Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(cameraQuaternion), this.viewer.camera.positionWC),
406
+ length : 25,
407
+ width : 5
408
+ })
409
+ this.viewer.scene.primitives.add(this.finalFrameDebug)
410
+ }
411
+ // As we don't want to continue tracking the camera after we need to recreate one each time
412
+ if (this.cameraDebug) this.viewer.scene.primitives.remove(this.cameraDebug)
413
+ this.cameraDebug = new DebugCameraPrimitive({
414
+ camera : this.viewer.camera,
415
+ color : Cesium.Color.YELLOW,
416
+ updateOnChange: false
417
+ })
418
+ this.viewer.scene.primitives.add(this.cameraDebug)
419
+ }
365
420
  },
366
421
  getCenter () {
367
422
  const center = this.viewer.camera.positionCartographic
@@ -379,6 +434,49 @@ export const baseGlobe = {
379
434
  const east = CesiumMath.toDegrees(bounds.east)
380
435
  return [[south, west], [north, east]]
381
436
  },
437
+ onEntityTracked (time) {
438
+ if (this.viewerOptions.debug) {
439
+ if (this.trackedFrameDebug) {
440
+ this.trackedFrameDebug.modelMatrix = this.viewer.trackedEntity.computeModelMatrix(time)
441
+ } else {
442
+ this.trackedFrameDebug = new DebugModelMatrixPrimitive({
443
+ modelMatrix : this.viewer.trackedEntity.computeModelMatrix(time),
444
+ length : 25,
445
+ width : 5
446
+ })
447
+ this.viewer.scene.primitives.add(this.trackedFrameDebug)
448
+ }
449
+ }
450
+ },
451
+ trackEntity (entityId, options = {}) {
452
+ // Check for entities directly added to the viewer
453
+ this.viewer.entities.values.forEach(entity => {
454
+ if (entityId === entity.id) {
455
+ // Make the camera track this entity
456
+ this.viewer.trackedEntity = entity
457
+ }
458
+ })
459
+ // Check for external data sources
460
+ for (let i = 0; i < this.viewer.dataSources.length; i++) {
461
+ const source = this.viewer.dataSources.get(i)
462
+ source.entities.values.forEach(entity => {
463
+ if (entityId === entity.id) {
464
+ // Make the camera track this entity
465
+ this.viewer.trackedEntity = entity
466
+ }
467
+ })
468
+ }
469
+ if (this.viewer.trackedEntity) {
470
+ this.viewer.clock.onTick.addEventListener(this.onEntityTracked)
471
+ }
472
+ },
473
+ untrackEntity () {
474
+ if (this.viewer.trackedEntity) {
475
+ if (this.trackedFrameDebug) this.viewer.scene.primitives.remove(this.trackedFrameDebug)
476
+ this.viewer.clock.onTick.removeEventListener(this.onEntityTracked)
477
+ }
478
+ this.viewer.trackedEntity = null
479
+ },
382
480
  async showUserLocation () {
383
481
  if (Geolocation.hasLocation()) {
384
482
  const longitude = Geolocation.getLongitude()
@@ -1,18 +1,16 @@
1
1
  import _ from 'lodash'
2
- import { viewerDragDropMixin } from 'cesium'
3
2
  import logger from 'loglevel'
3
+ import { viewerDragDropMixin } from 'cesium'
4
4
 
5
5
  export const fileLayers = {
6
6
  mounted () {
7
7
  this.$engineEvents.on('globe-ready', () => {
8
- this.viewer.extend(viewerDragDropMixin,
9
- // For activities
10
- _.get(this, 'activityOptions.engine.fileLayers', {
11
- clearOnDrop: false,
12
- flyToOnDrop: true,
13
- clampToGround: true
14
- })
15
- )
8
+ const fileLayersOptions = _.defaults(_.get(this, 'activityOptions.engine.fileLayers', {}), {
9
+ clearOnDrop: false,
10
+ flyToOnDrop: true,
11
+ clampToGround: true
12
+ })
13
+ this.viewer.extend(viewerDragDropMixin, fileLayersOptions)
16
14
  this.viewer.dropError.addEventListener((viewerArg, source, error) => {
17
15
  logger.error(error)
18
16
  })
@@ -21,6 +19,7 @@ export const fileLayers = {
21
19
  // Check if source has not been dropped, otherwise add it as layer
22
20
  if (source.notFromDrop) return
23
21
  if (!source.name) source.name = this.$t('mixins.fileLayers.IMPORTED_DATA_NAME')
22
+ logger.debug('[KDK] processing dropped file: ', source.name)
24
23
  // Create an empty layer used as a container
25
24
  this.addLayer({
26
25
  name: source.name,
@@ -30,7 +29,8 @@ export const fileLayers = {
30
29
  cesium: {
31
30
  type: 'geoJson',
32
31
  isVisible: true,
33
- cluster: { pixelRange: 50 },
32
+ cluster: _.get(fileLayersOptions, 'cluster', { pixelRange: 50 }),
33
+ entityStyle: _.get(fileLayersOptions, 'entityStyle'),
34
34
  source: source.name // Set the data source name instead of URL in this case
35
35
  }
36
36
  })