@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
@@ -3,13 +3,16 @@ import _ from 'lodash'
3
3
  import logger from 'loglevel'
4
4
  import sift from 'sift'
5
5
  import { uid } from 'quasar'
6
- import { Time } from '../../../../core/client/time.js'
6
+ import { Time, Units } from '../../../../core.client.js'
7
7
  import { fetchGeoJson, getFeatureId, processFeatures, getFeatureStyleType, isInMemoryLayer } from '../../utils.js'
8
8
  import { convertSimpleStyleToPointStyle, convertSimpleStyleToLineStyle, convertSimpleStyleToPolygonStyle } from '../../utils/utils.style.js'
9
9
  import { convertToCesiumFromSimpleStyle, getPointSimpleStyle, getLineSimpleStyle, getPolygonSimpleStyle } from '../../cesium/utils/utils.style.js'
10
10
 
11
- function getWallEntityId (id) {
12
- return id + '-wall'
11
+ // Custom entity types that can be created from a base entity like eg a polyline
12
+ const CustomTypes = ['wall', 'corridor']
13
+ // Generate an id for a custom entity type, eg 'wall'
14
+ function getCustomEntityId (id, type) {
15
+ return `${id}-${type}`
13
16
  }
14
17
 
15
18
  function updateGeoJsonEntity(source, destination) {
@@ -44,10 +47,12 @@ export const geojsonLayers = {
44
47
  let features = (geoJson.type === 'FeatureCollection' ? geoJson.features : [geoJson])
45
48
  features.forEach(feature => {
46
49
  const id = getFeatureId(feature, options)
47
- const wallId = getWallEntityId(id)
48
- if (dataSource.entities.getById(id)) dataSource.entities.removeById(id)
49
- // Take care that in case of a wall entity we add it in addition to the original line
50
- if (dataSource.entities.getById(wallId)) dataSource.entities.removeById(wallId)
50
+ CustomTypes.forEach(type => {
51
+ const customId = getCustomEntityId(id, type)
52
+ if (dataSource.entities.getById(id)) dataSource.entities.removeById(id)
53
+ // Take care that in case of a custom entity we add it in addition to or instead the original line
54
+ if (dataSource.entities.getById(customId)) dataSource.entities.removeById(customId)
55
+ })
51
56
  })
52
57
  return
53
58
  }
@@ -66,10 +71,12 @@ export const geojsonLayers = {
66
71
  if (_.get(updateOptions, 'removeMissing', cesiumOptions.removeMissing)) {
67
72
  dataSource.entities.values.forEach(entity => {
68
73
  const id = entity.id
69
- const wallId = getWallEntityId(id)
70
- if (!loadingDataSource.entities.getById(id)) dataSource.entities.removeById(id)
71
- // Take care that in case of a wall entity we add it in addition to the original line
72
- if (dataSource.entities.getById(wallId)) dataSource.entities.removeById(wallId)
74
+ CustomTypes.forEach(type => {
75
+ const customId = getCustomEntityId(id, type)
76
+ if (!loadingDataSource.entities.getById(id)) dataSource.entities.removeById(id)
77
+ // Take care that in case of a custom entity we add it in addition to or instead the original line
78
+ if (dataSource.entities.getById(customId)) dataSource.entities.removeById(customId)
79
+ })
73
80
  })
74
81
  }
75
82
  // Process specific entities
@@ -108,7 +115,7 @@ export const geojsonLayers = {
108
115
  const { stroke, strokeWidth, fill } = this.convertFromSimpleStyleOrDefaults(properties)
109
116
  // Simply push the entity, other options like font will be set using styling options
110
117
  // This one will come in addition to the original line
111
- const wallId = getWallEntityId(entity.id)
118
+ const wallId = getCustomEntityId(entity.id, 'wall')
112
119
  entitiesToAdd.push({
113
120
  id: wallId,
114
121
  parent: entity,
@@ -124,6 +131,29 @@ export const geojsonLayers = {
124
131
  }
125
132
  })
126
133
  }
134
+ // Corridors
135
+ const corridor = _.get(properties, 'corridor')
136
+ if (corridor && entity.polyline) {
137
+ const { stroke, strokeWidth, fill } = this.convertFromSimpleStyleOrDefaults(properties)
138
+ // Simply push the entity, other options like width be set using styling options
139
+ // This one will come in replacement to the original line
140
+ const corridorId = getCustomEntityId(entity.id, 'corridor')
141
+ entitiesToAdd.push({
142
+ id: corridorId,
143
+ parent: entity,
144
+ name: entity.name ? entity.name : corridorId,
145
+ description: entity.description.getValue(0),
146
+ properties: entity.properties.getValue(0),
147
+ corridor: {
148
+ positions: entity.polyline.positions.getValue(0),
149
+ material: new ColorMaterialProperty(fill),
150
+ outlineColor: new ConstantProperty(stroke),
151
+ outlineWidth: strokeWidth,
152
+ outline: new ConstantProperty(true)
153
+ }
154
+ })
155
+ entitiesToRemove.push(entity)
156
+ }
127
157
  // Billboard with 'none' shape should be removed as Cesium creates it even if the maki icon id is unknown
128
158
  if (entity.billboard && (_.get(properties, 'marker-symbol') === 'none')) {
129
159
  entitiesToRemove.push(entity)
@@ -212,8 +242,11 @@ export const geojsonLayers = {
212
242
  // We cannot access data outside the properties object of a feature in Cesium
213
243
  // As a consequence we copy back any style information inside
214
244
  // We need to convert to simple-style spec as cesium manages this only
215
- // We also need to merge all styling properties as some entities requires eg both line/polygon style (wall polylines)
245
+ // We also need to merge all styling properties as some entities requires eg both line/polygon style (wall polylines or corridor polygons)
216
246
  const simpleStyle = Object.assign(getPointSimpleStyle(feature, options, engine), getLineSimpleStyle(feature, options, engine), getPolygonSimpleStyle(feature, options, engine))
247
+ // Manage our extended simple-style spec
248
+ const text = _.get(feature, 'style.text.label')
249
+ if (text) simpleStyle['icon-text'] = text
217
250
  if (!feature.properties) feature.properties = simpleStyle
218
251
  else Object.assign(feature.properties, simpleStyle)
219
252
  }
@@ -329,13 +362,18 @@ export const geojsonLayers = {
329
362
  this.$engineEvents.emit('layer-updated', layer, cesiumLayer, data)
330
363
  },
331
364
  onCurrentTimeChangedGeoJsonLayers (time) {
365
+ // Need to update layers that require an update at a given frequency
332
366
  const geoJsonlayers = _.values(this.layers).filter(sift({
367
+ // Possible for realtime layers only
333
368
  'cesium.type': 'geoJson',
334
369
  'cesium.realtime': true,
335
- $or: [ // Supported by template URL or time-based features
370
+ $or: [ // Supported by template URL or time-based features service
336
371
  { 'cesium.sourceTemplate': { $exists: true } },
337
372
  { service: { $exists: true } }
338
373
  ],
374
+ // Skip layers powered by realtime service events
375
+ serviceEvents: { $ne: true },
376
+ // Skip invisible layers
339
377
  isVisible: true
340
378
  }))
341
379
  geoJsonlayers.forEach(async geoJsonlayer => {
@@ -348,6 +386,41 @@ export const geojsonLayers = {
348
386
  }
349
387
  })
350
388
  },
389
+ onDefaultUnitChangedGeoJsonLayers (units) {
390
+ _.forOwn(units.default, (unit, quantity) => {
391
+ const units = _.map(Units.getUnits(quantity), 'name')
392
+ // Need to update layers with variables affected by the unit change,
393
+ // ie which style depends on it
394
+ let geoJsonlayers = _.values(this.layers).filter(sift({
395
+ 'cesium.type': 'geoJson',
396
+ 'cesium.realtime': true,
397
+ // Not sure why but this does not seem to work with sift
398
+ //'variables': { $elemMatch: { unit: { $in: units } } },
399
+ 'variables': { $exists: true },
400
+ isVisible: true,
401
+ 'cesium.style': { $exists: true },
402
+ 'cesium.template': { $exists: true }
403
+ }))
404
+ // Check for each layer if it uses the target unit and templated style uses the unit system or not
405
+ geoJsonlayers = geoJsonlayers.filter(layer => {
406
+ const unit = _.intersection(units, _.map(layer.variables, 'unit'))
407
+ if (_.isEmpty(unit)) return false
408
+ for (const template of layer.cesium.template) {
409
+ if (template.startsWith('style.')) {
410
+ const style = _.get(layer.cesium, template)
411
+ if ((typeof style === 'string') && style.includes('Units')) return true
412
+ }
413
+ }
414
+ return false
415
+ })
416
+ // Then retrieve the engine layers and update
417
+ geoJsonlayers.forEach(layer => {
418
+ // Retrieve the layer
419
+ const dataSource = this.getCesiumLayerByName(geoJsonlayer.name)
420
+ dataSource.updateGeoJson()
421
+ })
422
+ })
423
+ },
351
424
  onLayerShownGeoJsonLayers (layer, engineLayer) {
352
425
  // Check if we have cached geojson data for this layer
353
426
  const cachedGeojson = this.geojsonCache[layer.name]
@@ -371,6 +444,7 @@ export const geojsonLayers = {
371
444
  created () {
372
445
  this.registerCesiumConstructor(this.createCesiumGeoJsonLayer)
373
446
  this.$events.on('time-current-time-changed', this.onCurrentTimeChangedGeoJsonLayers)
447
+ this.$events.on('units-changed', this.onDefaultUnitChangedGeoJsonLayers)
374
448
  this.$engineEvents.on('layer-shown', this.onLayerShownGeoJsonLayers)
375
449
  this.$engineEvents.on('layer-removed', this.onLayerRemovedGeoJsonLayers)
376
450
  // Map of currently updated layers to avoid reentrance with real-time events as
@@ -380,7 +454,8 @@ export const geojsonLayers = {
380
454
  this.geojsonCache = {}
381
455
  },
382
456
  beforeUnmount () {
383
- this.$events.off('time-current-time-changed', this.onCurrentTimeChangedHeatmapLayers)
457
+ this.$events.off('time-current-time-changed', this.onCurrentTimeChangedGeoJsonLayers)
458
+ this.$events.off('units-changed', this.onDefaultUnitChangedGeoJsonLayers)
384
459
  this.$engineEvents.off('layer-shown', this.onLayerShownGeoJsonLayers)
385
460
  this.$engineEvents.off('layer-removed', this.onLayerRemovedGeoJsonLayers)
386
461
 
@@ -24,6 +24,8 @@ export const style = {
24
24
  }
25
25
  // Handle specific case of orientation
26
26
  if (style.orientation) entity.orientation = style.orientation
27
+ // Handle specific case of visibility
28
+ if (_.has(style, 'visibility')) entity.show = style.visibility
27
29
  }
28
30
  },
29
31
  applyClusterStyle (entities, cluster, options) {
@@ -1,5 +1,4 @@
1
1
  export * from './mixin.activity.js'
2
- export * from './mixin.catalog-panel.js'
3
2
  export * from './mixin.context.js'
4
3
  export * from './mixin.feature-selection.js'
5
4
  export * from './mixin.feature-service.js'
@@ -14,3 +14,4 @@ export * from './mixin.heatmap-layers.js'
14
14
  export * from './mixin.mapillary-layers.js'
15
15
  export * from './mixin.gsmap-layers.js'
16
16
  export * from './mixin.canvas-layers.js'
17
+ export * from './mixin.pmtiles-layers.js'
@@ -92,6 +92,9 @@ export const baseMap = {
92
92
  if (scale) this.setupScaleControl(scale)
93
93
  const geolocate = _.get(viewerOptions, 'geolocate', true)
94
94
  if (geolocate) this.setupGeolocateControl(geolocate)
95
+ // Add a special hidden pane, used to hide individual features
96
+ const hiddenPane = this.map.createPane('kdk-hidden-features')
97
+ hiddenPane.style.display = 'none'
95
98
  this.onMapReady()
96
99
  },
97
100
  onMapReady () {
@@ -560,11 +563,24 @@ export const baseMap = {
560
563
  },
561
564
  getBearing () {
562
565
  if (typeof this.map.getBearing !== 'function') {
563
- logger.warn(`[KDK] Map not configured to handle bearing, ignoring`)
564
566
  return 0
565
567
  }
566
568
  return this.map.getBearing()
567
569
  },
570
+ setCompassBearingTrackingEnabled (enabled) {
571
+ if (enabled) {
572
+ if (!this.map.compassBearing.enabled()) this.map.compassBearing.enable()
573
+ } else if (this.map.compassBearing.enabled()) {
574
+ this.map.compassBearing.disable()
575
+ }
576
+ },
577
+ setTouchRotateEnabled (enabled) {
578
+ if (enabled) {
579
+ if (!this.map.touchRotate.enabled()) this.map.touchRotate.enable()
580
+ } else if (this.map.touchRotate.enabled()) {
581
+ this.map.touchRotate.disable()
582
+ }
583
+ },
568
584
  getBounds () {
569
585
  this.viewBounds = this.map.getBounds()
570
586
  const south = this.viewBounds.getSouth()
@@ -650,6 +666,9 @@ export const baseMap = {
650
666
  this.$events.off('time-current-time-changed', this.onCurrentMapTimeChanged)
651
667
  },
652
668
  unmounted () {
653
- if (this.map) this.map.remove()
669
+ if (this.map) {
670
+ this.map.off()
671
+ this.map.remove()
672
+ }
654
673
  }
655
674
  }
@@ -207,8 +207,13 @@ L.KanvasLayer = (L.Layer ? L.Layer : L.Class).extend({
207
207
  }
208
208
 
209
209
  // Skip redraw when no feature hovered and we're not highlighting
210
- if (!hoveringFeatures && !this.highlighting) return
211
- this.needRedraw()
210
+ if (!hoveringFeatures && !this.highlighting) {
211
+ this._canvas.style.cursor = ''
212
+ return
213
+ } else {
214
+ this._canvas.style.cursor = 'pointer'
215
+ this.needRedraw()
216
+ }
212
217
  },
213
218
  // -------------------------------------------------------------
214
219
  getEvents: function () {
@@ -4,7 +4,8 @@ import { getType, getGeom } from '@turf/invariant'
4
4
  import { Dialog, uid } from 'quasar'
5
5
  import {
6
6
  bindLeafletEvents, unbindLeafletEvents,
7
- getDefaultPointStyle, getDefaultLineStyle, getDefaultPolygonStyle, createMarkerFromPointStyle
7
+ getDefaultPointStyle, getDefaultLineStyle, getDefaultPolygonStyle, createMarkerFromPointStyle,
8
+ convertSimpleStyleToPointStyle, convertSimpleStyleToLineStyle, convertSimpleStyleToPolygonStyle
8
9
  } from '../../utils.map.js'
9
10
 
10
11
  // Events we listen while layer is in edition mode
@@ -55,6 +56,13 @@ export const editLayers = {
55
56
  },
56
57
  getGeoJsonEditOptions (options) {
57
58
  let filteredOptions = options
59
+ // Convert and store style
60
+ const leafletOptions = options.leaflet || options
61
+ const layerStyle = {}
62
+ layerStyle.layerPointStyle = leafletOptions.style ? _.get(leafletOptions.style, 'point') : convertSimpleStyleToPointStyle(leafletOptions)
63
+ layerStyle.layerLineStyle = leafletOptions.style ? _.get(leafletOptions.style, 'line') : convertSimpleStyleToLineStyle(leafletOptions)
64
+ layerStyle.layerPolygonStyle = leafletOptions.style ? _.get(leafletOptions.style, 'polygon') : convertSimpleStyleToPolygonStyle(leafletOptions)
65
+
58
66
  if (_.has(filteredOptions, 'leaflet.tooltip') || _.has(filteredOptions, 'leaflet.popup')) {
59
67
  // Disable tooltip & popup features on edited layer
60
68
  filteredOptions = Object.assign({}, options)
@@ -72,16 +80,16 @@ export const editLayers = {
72
80
  // Use default styling when editing as dynamic styling can conflict
73
81
  style: (feature) => {
74
82
  if (['LineString', 'MultiLineString'].includes(feature.geometry.type)) {
75
- return getDefaultLineStyle(feature, null, _.get(this, 'activityOptions.engine'), 'style.edition.line')
83
+ return getDefaultLineStyle(feature, layerStyle, _.get(this, 'activityOptions.engine'), 'style.edition.line')
76
84
  }
77
85
  if (['Polygon', 'MultiPolygon'].includes(feature.geometry.type)) {
78
- return getDefaultPolygonStyle(feature, null, _.get(this, 'activityOptions.engine'), 'style.edition.polygon')
86
+ return getDefaultPolygonStyle(feature, layerStyle, _.get(this, 'activityOptions.engine'), 'style.edition.polygon')
79
87
  } else {
80
88
  logger.warn(`[KDK] the geometry of type of ${feature.geometry.type} is not supported`)
81
89
  }
82
90
  },
83
91
  pointToLayer: (feature, latlng) => {
84
- const style = getDefaultPointStyle(feature, null, _.get(this, 'activityOptions.engine'), 'style.edition.point')
92
+ const style = getDefaultPointStyle(feature, layerStyle, _.get(this, 'activityOptions.engine'), 'style.edition.point')
85
93
  style.options = { pmIgnore: false } // Allow geoman edition
86
94
  return createMarkerFromPointStyle(latlng, style)
87
95
  }
@@ -1,4 +1,5 @@
1
1
  import _ from 'lodash'
2
+ import logger from 'loglevel'
2
3
  import path from 'path-browserify'
3
4
  import { Reader } from '../../../../core/client/reader.js'
4
5
 
@@ -28,6 +29,7 @@ export const fileLayers = {
28
29
  dropFileInput.type = 'file'
29
30
  dropFileInput.style.display = 'none'
30
31
  dropFileInput.addEventListener('change', async (event) => {
32
+ logger.debug('[KDK] processing dropped files: ', event.target.files)
31
33
  await this.importFiles(event.target.files)
32
34
  })
33
35
  container.appendChild(dropFileInput)
@@ -39,6 +41,7 @@ export const fileLayers = {
39
41
  event.preventDefault()
40
42
  }, false)
41
43
  this.map._container.addEventListener('drop', async (event) => {
44
+ logger.debug('[KDK] processing dropped files: ', event.dataTransfer.files)
42
45
  event.stopPropagation()
43
46
  event.preventDefault()
44
47
  await this.importFiles(event.dataTransfer.files)
@@ -2,8 +2,9 @@ import L from 'leaflet'
2
2
  import _ from 'lodash'
3
3
  import sift from 'sift'
4
4
  import logger from 'loglevel'
5
+ import lineOffset from '@turf/line-offset'
5
6
  import 'leaflet-realtime'
6
- import { Time, utils as kdkCoreUtils } from '../../../../core.client.js'
7
+ import { Time, Units, utils as kdkCoreUtils } from '../../../../core.client.js'
7
8
  import { GradientPath } from '../../leaflet/GradientPath.js'
8
9
  import { MaskLayer } from '../../leaflet/MaskLayer.js'
9
10
  import { TiledFeatureLayer } from '../../leaflet/TiledFeatureLayer.js'
@@ -27,6 +28,31 @@ const Realtime = L.Realtime.extend({
27
28
  L.realtime = function (src, options) {
28
29
  return new Realtime(src, options)
29
30
  }
31
+ // Override default Polyline simplify function to manage offset
32
+ const simplifyPoints = L.Polyline.prototype._simplifyPoints
33
+ L.Polyline.include({
34
+ _simplifyPoints: function () {
35
+ simplifyPoints.call(this)
36
+ // Offset simplified version
37
+ if (this.options.offset) {
38
+ // We'd like to ensure a pixel constant offset when zooming
39
+ // Zoom 0 resolution is 156 543 m/pixel at equator in default map tiles,
40
+ // we take latitude into account to account for a convergence factor
41
+ const latitude = this.getBounds().getCenter().lat
42
+ const factor = 156543 / Math.pow(2, this._map.getZoom()) / Math.cos(latitude * Math.PI / 180)
43
+ const offset = Math.max(1, this.options.offset * factor)
44
+
45
+ for (let i = 0; i < this._parts.length; i++) {
46
+ let latLngs = this._parts[i].map(point => this._map.layerPointToLatLng(point))
47
+ // Ensure a large enough precision for computation (defaults to 6 in Leaflet)
48
+ const coords = L.GeoJSON.latLngsToCoords(latLngs, 0, false, 12)
49
+ const feature = lineOffset({ type: 'LineString', coordinates: coords }, offset, { units: 'meters' })
50
+ latLngs = L.GeoJSON.coordsToLatLngs(feature.geometry.coordinates, 0)
51
+ this._parts[i] = latLngs.map(latlng => this._map.latLngToLayerPoint(latlng))
52
+ }
53
+ }
54
+ }
55
+ })
30
56
 
31
57
  // Override default Leaflet GeoJson utility to manage some specific use cases
32
58
  const geometryToLayer = L.GeoJSON.geometryToLayer
@@ -55,10 +81,18 @@ L.GeoJSON.geometryToLayer = function (geojson, options) {
55
81
  if (geometry.type === 'Polygon' || geometry.type === 'MultiPolygon') {
56
82
  return new MaskLayer(geojson, options.style(geojson))
57
83
  }
84
+ }// Automate Leaflet.PolylineOffset plugin use
85
+ if (geometry && properties && properties.offset) {
86
+ if (geometry.type === 'LineString') {
87
+ options = Object.assign({ offset: properties.offset }, options)
88
+ }
58
89
  }
59
90
  // As we do so this breaks leaflet-arrowheads plugin
60
91
  const layer = geometryToLayer(geojson, options)
61
- if (options.arrowheads && (layer instanceof L.Polyline)) layer.arrowheads(options.arrowheads)
92
+ if (geometry && (options.arrowheads || (properties && properties.arrowheads))) {
93
+ if (layer instanceof L.Polyline) layer.arrowheads(options.arrowheads || properties.arrowheads)
94
+ }
95
+
62
96
  return layer
63
97
  }
64
98
 
@@ -488,13 +522,18 @@ export const geojsonLayers = {
488
522
  this.$engineEvents.emit('layer-updated', layer, leafletLayer, data)
489
523
  },
490
524
  onCurrentTimeChangedGeoJsonLayers (time) {
525
+ // Need to update layers that require an update at a given frequency
491
526
  const geoJsonlayers = _.values(this.layers).filter(sift({
527
+ // Possible for realtime layers only
492
528
  'leaflet.type': 'geoJson',
493
529
  'leaflet.realtime': true,
494
- $or: [ // Supported by template URL or time-based features
530
+ $or: [ // Supported by template URL or time-based features service
495
531
  { 'leaflet.sourceTemplate': { $exists: true } },
496
532
  { service: { $exists: true } }
497
533
  ],
534
+ // Skip layers powered by realtime service events
535
+ serviceEvents: { $ne: true },
536
+ // Skip invisible layers
498
537
  isVisible: true
499
538
  }))
500
539
  geoJsonlayers.forEach(async geoJsonlayer => {
@@ -528,6 +567,44 @@ export const geojsonLayers = {
528
567
  }
529
568
  }
530
569
  },
570
+ onDefaultUnitChangedGeoJsonLayers (units) {
571
+ _.forOwn(units.default, (unit, quantity) => {
572
+ const units = _.map(Units.getUnits(quantity), 'name')
573
+ // Need to update layers with variables affected by the unit change,
574
+ // ie which style depends on it
575
+ let geoJsonlayers = _.values(this.layers).filter(sift({
576
+ 'leaflet.type': 'geoJson',
577
+ 'leaflet.realtime': true,
578
+ // Not sure why but this does not seem to work with sift
579
+ //'variables': { $elemMatch: { unit: { $in: units } } },
580
+ 'variables': { $exists: true },
581
+ isVisible: true,
582
+ 'leaflet.style': { $exists: true },
583
+ 'leaflet.template': { $exists: true }
584
+ }))
585
+ // Check for each layer if it uses the target unit and templated style uses the unit system or not
586
+ geoJsonlayers = geoJsonlayers.filter(layer => {
587
+ const unit = _.intersection(units, _.map(layer.variables, 'unit'))
588
+ if (_.isEmpty(unit)) return false
589
+ for (const template of layer.leaflet.template) {
590
+ if (template.startsWith('style.')) {
591
+ const style = _.get(layer.leaflet, template)
592
+ if ((typeof style === 'string') && style.includes('Units')) return true
593
+ }
594
+ }
595
+ return false
596
+ })
597
+ // Then retrieve the engine layers and update
598
+ geoJsonlayers.forEach(layer => {
599
+ layer = this.getLeafletLayerByName(layer.name)
600
+ if (layer.tiledLayer) {
601
+ layer.tiledLayer.redraw()
602
+ } else {
603
+ layer.update()
604
+ }
605
+ })
606
+ })
607
+ },
531
608
  onMapZoomChangedGeoJsonLayers () {
532
609
  // Need to update layers with tooltip defining a minZoom/maxZoom
533
610
  // as we cannot do that in template because tooltip needs to be recreated/destroyed dynamically
@@ -565,7 +642,13 @@ export const geojsonLayers = {
565
642
  if (cachedGeojson) {
566
643
  if (isInMemoryLayer(layer)) {
567
644
  // Restore geojson data for in-memory layers that was hidden
568
- this.updateLayer(layer.name, cachedGeojson)
645
+ // Directly deal with the leaflet layer instead of calling updateLayer, we are just restoring data
646
+ // Handle case where there's clustering on top (cf. updateLayer)
647
+ if (typeof engineLayer.getLayers === 'function') {
648
+ const container = engineLayer
649
+ engineLayer = container.getLayers().find(layer => layer._container === container)
650
+ }
651
+ engineLayer._onNewData(false, cachedGeojson)
569
652
  } else {
570
653
  // Clear cache since layer is not in memory anymore
571
654
  delete this.geojsonCache[layer.name]
@@ -583,6 +666,7 @@ export const geojsonLayers = {
583
666
  this.registerLeafletConstructor(this.createLeafletGeoJsonLayer)
584
667
  this.$events.on('time-current-time-changed', this.onCurrentTimeChangedGeoJsonLayers)
585
668
  this.$engineEvents.on('selected-level-changed', this.onCurrentLevelChangedGeoJsonLayers)
669
+ this.$events.on('units-changed', this.onDefaultUnitChangedGeoJsonLayers)
586
670
  this.$engineEvents.on('zoomend', this.onMapZoomChangedGeoJsonLayers)
587
671
  this.$engineEvents.on('layer-shown', this.onLayerShownGeoJsonLayers)
588
672
  this.$engineEvents.on('layer-removed', this.onLayerRemovedGeoJsonLayers)
@@ -591,8 +675,9 @@ export const geojsonLayers = {
591
675
  this.geojsonCache = {}
592
676
  },
593
677
  beforeUnmount () {
594
- this.$events.off('time-current-time-changed', this.onCurrentTimeChangedHeatmapLayers)
678
+ this.$events.off('time-current-time-changed', this.onCurrentTimeChangedGeoJsonLayers)
595
679
  this.$engineEvents.off('selected-level-changed', this.onCurrentLevelChangedGeoJsonLayers)
680
+ this.$events.off('units-changed', this.onDefaultUnitChangedGeoJsonLayers)
596
681
  this.$engineEvents.off('zoomend', this.onMapZoomChangedGeoJsonLayers)
597
682
  this.$engineEvents.off('layer-shown', this.onLayerShownGeoJsonLayers)
598
683
  this.$engineEvents.off('layer-removed', this.onLayerRemovedGeoJsonLayers)
@@ -0,0 +1,106 @@
1
+ import _ from 'lodash'
2
+ import chroma from 'chroma-js'
3
+ import moment from 'moment'
4
+ import sift from 'sift'
5
+ import L from 'leaflet'
6
+ import * as protomaps from 'protomaps-leaflet'
7
+ import { mapbox_style } from '@kalisio/leaflet-pmtiles'
8
+ import { Time, Units, TemplateContext } from '../../../../core/client/index.js'
9
+
10
+ export const pmtilesLayers = {
11
+ methods: {
12
+ async createLeafletPMTilesLayer (options) {
13
+ const leafletOptions = options.leaflet || options
14
+ // Check for valid types
15
+ if (leafletOptions.type !== 'pmtiles') return
16
+ // Optimize templating by creating compilers up-front
17
+ const layerStyleTemplate = _.get(leafletOptions, 'template')
18
+ if (layerStyleTemplate) {
19
+ // We allow to template style properties according to feature, because it can be slow you have to specify a subset of properties
20
+ leafletOptions.template = layerStyleTemplate.map(property => ({
21
+ property, compiler: _.template(_.get(leafletOptions, property))
22
+ }))
23
+ }
24
+
25
+ let rules = {}
26
+ // Check for style information given as object or URL
27
+ let style = _.get(leafletOptions, 'style')
28
+ if (typeof style === 'string') {
29
+ const response = await fetch(style)
30
+ if (response.status !== 200) {
31
+ throw new Error(`Impossible to fetch style ${style}: ` + response.status)
32
+ }
33
+ style = await response.json()
34
+ const backgroundLayer = style.layers.find(layer => layer.type === 'background')
35
+ if (backgroundLayer) leafletOptions.backgroundColor = backgroundLayer.paint['fill-color']
36
+ // Convert to PMTiles plugin paint rules
37
+ rules = mapbox_style(style, {})
38
+ } else {
39
+ // Manage templating
40
+ leafletOptions.template.forEach(entry => {
41
+ // protomaps allows property functions with zomm/feature as input
42
+ const f = (zoom, feature) => {
43
+ const context = Object.assign({ properties: feature.props, feature, chroma, moment, Units, Time, level: this.selectedLevel }, TemplateContext.get())
44
+ return entry.property.endsWith('filter') ? (entry.compiler(context) === 'true'): entry.compiler(context)
45
+ }
46
+ _.set(leafletOptions, entry.property, f)
47
+ })
48
+ const styleRules = _.map(style, rule => Object.assign(_.omit(rule, ['symbolizer']), {
49
+ symbolizer: new protomaps[rule.symbolizer.type](rule.symbolizer)
50
+ })
51
+ )
52
+ const isLabelSymbolizer = (rule) => typeof rule.symbolizer.place === 'function'
53
+ const isNotLabelSymbolizer = (rule) => !isLabelSymbolizer(rule)
54
+ // Support v1.x as well as v2.x
55
+ rules.paint_rules = rules.paintRules = _.filter(styleRules, isNotLabelSymbolizer)
56
+ rules.label_rules = rules.labelRules = _.filter(styleRules, isLabelSymbolizer)
57
+ }
58
+
59
+ return this.createLeafletLayer({
60
+ ...leafletOptions,
61
+ ...rules,
62
+ //debug: true,
63
+ //levelDiff: 2
64
+ })
65
+ },
66
+ onCurrentTimeChangedPMTilesLayers (time) {
67
+ const pmtileslayers = _.values(this.layers).filter(sift({
68
+ 'leaflet.type': 'pmtiles',
69
+ // Skip invisible layers
70
+ isVisible: true
71
+ }))
72
+ pmtileslayers.forEach(async pmtileslayer => {
73
+ // Retrieve the layer
74
+ const layer = this.getLeafletLayerByName(pmtileslayer.name)
75
+ layer.redraw()
76
+ })
77
+ },
78
+ onCurrentLevelChangedPMTilesLayers (level) {
79
+ // Retrieve the layer associated to current level sélection
80
+ let layer = this.selectableLevelsLayer
81
+ if (layer) {
82
+ const type = _.get(layer, `${this.engine}.type`)
83
+ // Check if of right type
84
+ if (type === 'pmtiles') {
85
+ // Retrieve the engine layer and update
86
+ layer = this.getLeafletLayerByName(layer.name)
87
+ layer.redraw()
88
+ }
89
+ }
90
+ }
91
+ },
92
+ created () {
93
+ this.registerLeafletConstructor(this.createLeafletPMTilesLayer)
94
+ this.$events.on('time-current-time-changed', this.onCurrentTimeChangedPMTilesLayers)
95
+ this.$engineEvents.on('selected-level-changed', this.onCurrentLevelChangedPMTilesLayers)
96
+ },
97
+ beforeUnmount () {
98
+ this.$events.off('time-current-time-changed', this.onCurrentTimeChangedPMTilesLayers)
99
+ this.$engineEvents.off('selected-level-changed', this.onCurrentLevelChangedPMTilesLayers)
100
+ }
101
+ }
102
+
103
+ // Not automatically declared by leaflet plugin
104
+ L.pmtiles = function (options) {
105
+ return protomaps.leafletLayer(options)
106
+ }
@@ -317,14 +317,19 @@ export const activity = {
317
317
  // (eg style edition, etc.)
318
318
  // Here we find layer by ID as renaming could have occured from another client
319
319
  const layer = this.getLayerById(object._id)
320
+ let planetApi
321
+ if (layer && (typeof layer.getPlanetApi === 'function')) {
322
+ planetApi = layer.getPlanetApi()
323
+ }
320
324
  if (layer) {
321
325
  // Stop any running edition
322
326
  if ((typeof this.isLayerEdited === 'function') && this.isLayerEdited(layer)) await this.stopEditLayer('reject')
323
327
  await this.removeCatalogLayer(layer)
324
328
  }
325
329
  if (event !== 'removed') {
326
- // Do we need to inject a token ?
327
- await setEngineJwt([object])
330
+ // Do we need to inject a token or restore planet API ?
331
+ if (planetApi) Object.assign(object, { getPlanetApi: () => planetApi })
332
+ await setEngineJwt([object], planetApi)
328
333
  await this.addCatalogLayer(object)
329
334
  }
330
335
  break
@@ -337,7 +342,7 @@ export const activity = {
337
342
  // Merge the engine options using defaults
338
343
  const defaultOptions = _.get(config, `engines.${this.engine}`)
339
344
  if (defaultOptions) {
340
- logger.debug(`[KDK] ${this.engine} engine use defaults: ${JSON.stringify(defaultOptions, null, 2)}`)
345
+ logger.debug(`[KDK] Configuring '${this.engine}' engine with options:`, defaultOptions)
341
346
  // Take care that if we only use the default options the specific options will be undefined
342
347
  this.activityOptions.engine = _.defaultsDeep(_.get(this.activityOptions, 'engine', {}), defaultOptions)
343
348
  }