@kalisio/kdk 1.4.2 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (410) hide show
  1. package/.nyc_output/02a7a308-a8d7-4cc6-8e61-6066a0055a96.json +1 -0
  2. package/.nyc_output/1900d596-5e87-433a-8fd6-fb7f7ded35ec.json +1 -0
  3. package/.nyc_output/{2e74ca23-8cf0-4161-9536-f71c2a1a74bb.json → 27401f21-8ccf-42fa-8230-4232189d86b3.json} +0 -0
  4. package/.nyc_output/{81d21e46-766a-46bc-b1b7-143ca577347a.json → 52278ef5-c337-4724-97be-e2e4416847c5.json} +0 -0
  5. package/.nyc_output/{aaf3ebbb-f895-4d7b-9255-bc5dee832570.json → 5dd49b8a-4c84-42f9-a3d5-712247a84775.json} +0 -0
  6. package/.nyc_output/{dbeb2602-0ac2-4e66-978b-0d29548359ca.json → 612b4859-9645-45c1-a41e-1fae420518c4.json} +0 -0
  7. package/.nyc_output/{e47d1e4c-2fff-4dcb-908f-d3081162547c.json → bab87fe9-d99a-4759-99e6-3fc4622eeca0.json} +0 -0
  8. package/.nyc_output/processinfo/02a7a308-a8d7-4cc6-8e61-6066a0055a96.json +1 -0
  9. package/.nyc_output/processinfo/1900d596-5e87-433a-8fd6-fb7f7ded35ec.json +1 -0
  10. package/.nyc_output/processinfo/27401f21-8ccf-42fa-8230-4232189d86b3.json +1 -0
  11. package/.nyc_output/processinfo/52278ef5-c337-4724-97be-e2e4416847c5.json +1 -0
  12. package/.nyc_output/processinfo/5dd49b8a-4c84-42f9-a3d5-712247a84775.json +1 -0
  13. package/.nyc_output/processinfo/612b4859-9645-45c1-a41e-1fae420518c4.json +1 -0
  14. package/.nyc_output/processinfo/bab87fe9-d99a-4759-99e6-3fc4622eeca0.json +1 -0
  15. package/.nyc_output/processinfo/index.json +1 -1
  16. package/CHANGELOG.md +69 -10
  17. package/coverage/core/api/application.js.html +500 -422
  18. package/coverage/core/api/authentication.js.html +119 -119
  19. package/coverage/core/api/db.js.html +172 -172
  20. package/coverage/core/api/hooks/hooks.account.js.html +45 -45
  21. package/coverage/core/api/hooks/hooks.authentication.js.html +71 -71
  22. package/coverage/core/api/hooks/hooks.authorisations.js.html +368 -353
  23. package/coverage/core/api/hooks/hooks.devices.js.html +49 -49
  24. package/coverage/core/api/hooks/hooks.groups.js.html +37 -37
  25. package/coverage/core/api/hooks/hooks.logger.js.html +27 -27
  26. package/coverage/core/api/hooks/hooks.model.js.html +269 -269
  27. package/coverage/core/api/hooks/hooks.organisations.js.html +190 -190
  28. package/coverage/core/api/hooks/hooks.pusher.js.html +114 -114
  29. package/coverage/core/api/hooks/hooks.query.js.html +277 -211
  30. package/coverage/core/api/hooks/hooks.service.js.html +82 -82
  31. package/coverage/core/api/hooks/hooks.storage.js.html +121 -121
  32. package/coverage/core/api/hooks/hooks.tags.js.html +232 -232
  33. package/coverage/core/api/hooks/hooks.users.js.html +263 -263
  34. package/coverage/core/api/hooks/index.html +172 -172
  35. package/coverage/core/api/hooks/index.js.html +24 -24
  36. package/coverage/core/api/index.html +76 -76
  37. package/coverage/core/api/index.js.html +30 -30
  38. package/coverage/core/api/marshall.js.html +57 -57
  39. package/coverage/core/api/models/groups.model.mongodb.js.html +20 -20
  40. package/coverage/core/api/models/index.html +50 -50
  41. package/coverage/core/api/models/organisations.model.mongodb.js.html +12 -12
  42. package/coverage/core/api/models/tags.model.mongodb.js.html +22 -22
  43. package/coverage/core/api/models/users.model.mongodb.js.html +20 -20
  44. package/coverage/core/api/oauth2-handler.js.html +18 -18
  45. package/coverage/core/api/oauth2-verifier.js.html +38 -38
  46. package/coverage/core/api/services/account/account.hooks.js.html +16 -16
  47. package/coverage/core/api/services/account/account.service.js.html +104 -104
  48. package/coverage/core/api/services/account/index.html +32 -32
  49. package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +9 -9
  50. package/coverage/core/api/services/authorisations/authorisations.service.js.html +156 -132
  51. package/coverage/core/api/services/authorisations/index.html +28 -28
  52. package/coverage/core/api/services/databases/databases.hooks.js.html +9 -9
  53. package/coverage/core/api/services/databases/databases.service.js.html +12 -12
  54. package/coverage/core/api/services/databases/index.html +24 -24
  55. package/coverage/core/api/services/devices/devices.hooks.js.html +9 -9
  56. package/coverage/core/api/services/devices/devices.service.js.html +121 -121
  57. package/coverage/core/api/services/devices/index.html +28 -28
  58. package/coverage/core/api/services/groups/groups.hooks.js.html +9 -9
  59. package/coverage/core/api/services/groups/index.html +13 -13
  60. package/coverage/core/api/services/index.html +21 -21
  61. package/coverage/core/api/services/index.js.html +118 -118
  62. package/coverage/core/api/services/mailer/index.html +24 -24
  63. package/coverage/core/api/services/mailer/mailer.hooks.js.html +9 -9
  64. package/coverage/core/api/services/mailer/mailer.service.js.html +19 -19
  65. package/coverage/core/api/services/organisations/index.html +24 -24
  66. package/coverage/core/api/services/organisations/organisations.hooks.js.html +8 -8
  67. package/coverage/core/api/services/organisations/organisations.service.js.html +67 -67
  68. package/coverage/core/api/services/pusher/index.html +34 -34
  69. package/coverage/core/api/services/pusher/pusher.channels.js.html +8 -8
  70. package/coverage/core/api/services/pusher/pusher.hooks.js.html +10 -10
  71. package/coverage/core/api/services/pusher/pusher.service.js.html +414 -414
  72. package/coverage/core/api/services/storage/index.html +21 -21
  73. package/coverage/core/api/services/storage/storage.hooks.js.html +35 -35
  74. package/coverage/core/api/services/tags/index.html +21 -21
  75. package/coverage/core/api/services/tags/tags.hooks.js.html +25 -25
  76. package/coverage/core/api/services/users/index.html +21 -21
  77. package/coverage/core/api/services/users/users.hooks.js.html +33 -33
  78. package/coverage/core/common/errors.js.html +1 -1
  79. package/coverage/core/common/index.html +42 -27
  80. package/coverage/core/common/index.js.html +16 -16
  81. package/coverage/core/common/permissions.js.html +320 -290
  82. package/coverage/index.html +181 -181
  83. package/coverage/lcov-report/core/api/application.js.html +500 -422
  84. package/coverage/lcov-report/core/api/authentication.js.html +119 -119
  85. package/coverage/lcov-report/core/api/db.js.html +172 -172
  86. package/coverage/lcov-report/core/api/hooks/hooks.account.js.html +45 -45
  87. package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +71 -71
  88. package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +368 -353
  89. package/coverage/lcov-report/core/api/hooks/hooks.devices.js.html +49 -49
  90. package/coverage/lcov-report/core/api/hooks/hooks.groups.js.html +37 -37
  91. package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +27 -27
  92. package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +269 -269
  93. package/coverage/lcov-report/core/api/hooks/hooks.organisations.js.html +190 -190
  94. package/coverage/lcov-report/core/api/hooks/hooks.pusher.js.html +114 -114
  95. package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +277 -211
  96. package/coverage/lcov-report/core/api/hooks/hooks.service.js.html +82 -82
  97. package/coverage/lcov-report/core/api/hooks/hooks.storage.js.html +121 -121
  98. package/coverage/lcov-report/core/api/hooks/hooks.tags.js.html +232 -232
  99. package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +263 -263
  100. package/coverage/lcov-report/core/api/hooks/index.html +172 -172
  101. package/coverage/lcov-report/core/api/hooks/index.js.html +24 -24
  102. package/coverage/lcov-report/core/api/index.html +76 -76
  103. package/coverage/lcov-report/core/api/index.js.html +30 -30
  104. package/coverage/lcov-report/core/api/marshall.js.html +57 -57
  105. package/coverage/lcov-report/core/api/models/groups.model.mongodb.js.html +20 -20
  106. package/coverage/lcov-report/core/api/models/index.html +50 -50
  107. package/coverage/lcov-report/core/api/models/organisations.model.mongodb.js.html +12 -12
  108. package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +22 -22
  109. package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +20 -20
  110. package/coverage/lcov-report/core/api/oauth2-handler.js.html +18 -18
  111. package/coverage/lcov-report/core/api/oauth2-verifier.js.html +38 -38
  112. package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +16 -16
  113. package/coverage/lcov-report/core/api/services/account/account.service.js.html +104 -104
  114. package/coverage/lcov-report/core/api/services/account/index.html +32 -32
  115. package/coverage/lcov-report/core/api/services/authorisations/authorisations.hooks.js.html +9 -9
  116. package/coverage/lcov-report/core/api/services/authorisations/authorisations.service.js.html +156 -132
  117. package/coverage/lcov-report/core/api/services/authorisations/index.html +28 -28
  118. package/coverage/lcov-report/core/api/services/databases/databases.hooks.js.html +9 -9
  119. package/coverage/lcov-report/core/api/services/databases/databases.service.js.html +12 -12
  120. package/coverage/lcov-report/core/api/services/databases/index.html +24 -24
  121. package/coverage/lcov-report/core/api/services/devices/devices.hooks.js.html +9 -9
  122. package/coverage/lcov-report/core/api/services/devices/devices.service.js.html +121 -121
  123. package/coverage/lcov-report/core/api/services/devices/index.html +28 -28
  124. package/coverage/lcov-report/core/api/services/groups/groups.hooks.js.html +9 -9
  125. package/coverage/lcov-report/core/api/services/groups/index.html +13 -13
  126. package/coverage/lcov-report/core/api/services/index.html +21 -21
  127. package/coverage/lcov-report/core/api/services/index.js.html +118 -118
  128. package/coverage/lcov-report/core/api/services/mailer/index.html +24 -24
  129. package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +9 -9
  130. package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +19 -19
  131. package/coverage/lcov-report/core/api/services/organisations/index.html +24 -24
  132. package/coverage/lcov-report/core/api/services/organisations/organisations.hooks.js.html +8 -8
  133. package/coverage/lcov-report/core/api/services/organisations/organisations.service.js.html +67 -67
  134. package/coverage/lcov-report/core/api/services/pusher/index.html +34 -34
  135. package/coverage/lcov-report/core/api/services/pusher/pusher.channels.js.html +8 -8
  136. package/coverage/lcov-report/core/api/services/pusher/pusher.hooks.js.html +10 -10
  137. package/coverage/lcov-report/core/api/services/pusher/pusher.service.js.html +414 -414
  138. package/coverage/lcov-report/core/api/services/storage/index.html +21 -21
  139. package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +35 -35
  140. package/coverage/lcov-report/core/api/services/tags/index.html +21 -21
  141. package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +25 -25
  142. package/coverage/lcov-report/core/api/services/users/index.html +21 -21
  143. package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +33 -33
  144. package/coverage/lcov-report/core/common/errors.js.html +1 -1
  145. package/coverage/lcov-report/core/common/index.html +42 -27
  146. package/coverage/lcov-report/core/common/index.js.html +16 -16
  147. package/coverage/lcov-report/core/common/permissions.js.html +320 -290
  148. package/coverage/lcov-report/index.html +181 -181
  149. package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +1 -1
  150. package/coverage/lcov-report/map/api/hooks/hooks.query.js.html +25 -7
  151. package/coverage/lcov-report/map/api/hooks/index.html +7 -7
  152. package/coverage/lcov-report/map/api/hooks/index.js.html +1 -1
  153. package/coverage/lcov-report/map/api/index.html +1 -1
  154. package/coverage/lcov-report/map/api/index.js.html +1 -1
  155. package/coverage/lcov-report/map/api/marshall.js.html +1 -1
  156. package/coverage/lcov-report/map/api/models/alerts.model.mongodb.js.html +1 -1
  157. package/coverage/lcov-report/map/api/models/catalog.model.mongodb.js.html +1 -1
  158. package/coverage/lcov-report/map/api/models/features.model.mongodb.js.html +14 -5
  159. package/coverage/lcov-report/map/api/models/index.html +7 -7
  160. package/coverage/lcov-report/map/api/services/alerts/alerts.hooks.js.html +1 -1
  161. package/coverage/lcov-report/map/api/services/alerts/alerts.service.js.html +1 -1
  162. package/coverage/lcov-report/map/api/services/alerts/index.html +1 -1
  163. package/coverage/lcov-report/map/api/services/catalog/catalog.hooks.js.html +1 -1
  164. package/coverage/lcov-report/map/api/services/catalog/index.html +1 -1
  165. package/coverage/lcov-report/map/api/services/daptiles/daptiles.service.js.html +1 -1
  166. package/coverage/lcov-report/map/api/services/daptiles/index.html +1 -1
  167. package/coverage/lcov-report/map/api/services/features/features.hooks.js.html +1 -1
  168. package/coverage/lcov-report/map/api/services/features/index.html +1 -1
  169. package/coverage/lcov-report/map/api/services/geocoder/geocoder.hooks.js.html +1 -1
  170. package/coverage/lcov-report/map/api/services/geocoder/geocoder.service.js.html +1 -1
  171. package/coverage/lcov-report/map/api/services/geocoder/index.html +1 -1
  172. package/coverage/lcov-report/map/api/services/index.html +1 -1
  173. package/coverage/lcov-report/map/api/services/index.js.html +1 -1
  174. package/coverage/lcov-report/map/common/dynamic-grid-source.js.html +1 -1
  175. package/coverage/lcov-report/map/common/errors.js.html +1 -1
  176. package/coverage/lcov-report/map/common/geotiff-grid-source.js.html +1 -1
  177. package/coverage/lcov-report/map/common/grid.js.html +1 -1
  178. package/coverage/lcov-report/map/common/index.html +1 -1
  179. package/coverage/lcov-report/map/common/index.js.html +1 -1
  180. package/coverage/lcov-report/map/common/meteo-model-grid-source.js.html +1 -1
  181. package/coverage/lcov-report/map/common/moment-utils.js.html +1 -1
  182. package/coverage/lcov-report/map/common/opendap-grid-source.js.html +1 -1
  183. package/coverage/lcov-report/map/common/opendap-utils.js.html +1 -1
  184. package/coverage/lcov-report/map/common/permissions.js.html +1 -1
  185. package/coverage/lcov-report/map/common/time-based-grid-source.js.html +1 -1
  186. package/coverage/lcov-report/map/common/tms-utils.js.html +1 -1
  187. package/coverage/lcov-report/map/common/wcs-grid-source.js.html +1 -1
  188. package/coverage/lcov-report/map/common/wcs-utils.js.html +1 -1
  189. package/coverage/lcov-report/map/common/weacast-grid-source.js.html +1 -1
  190. package/coverage/lcov-report/map/common/wfs-utils.js.html +1 -1
  191. package/coverage/lcov-report/map/common/wms-utils.js.html +1 -1
  192. package/coverage/lcov-report/map/common/wmts-utils.js.html +1 -1
  193. package/coverage/lcov.info +3683 -3825
  194. package/coverage/map/api/hooks/hooks.catalog.js.html +1 -1
  195. package/coverage/map/api/hooks/hooks.query.js.html +25 -7
  196. package/coverage/map/api/hooks/index.html +7 -7
  197. package/coverage/map/api/hooks/index.js.html +1 -1
  198. package/coverage/map/api/index.html +1 -1
  199. package/coverage/map/api/index.js.html +1 -1
  200. package/coverage/map/api/marshall.js.html +1 -1
  201. package/coverage/map/api/models/alerts.model.mongodb.js.html +1 -1
  202. package/coverage/map/api/models/catalog.model.mongodb.js.html +1 -1
  203. package/coverage/map/api/models/features.model.mongodb.js.html +14 -5
  204. package/coverage/map/api/models/index.html +7 -7
  205. package/coverage/map/api/services/alerts/alerts.hooks.js.html +1 -1
  206. package/coverage/map/api/services/alerts/alerts.service.js.html +1 -1
  207. package/coverage/map/api/services/alerts/index.html +1 -1
  208. package/coverage/map/api/services/catalog/catalog.hooks.js.html +1 -1
  209. package/coverage/map/api/services/catalog/index.html +1 -1
  210. package/coverage/map/api/services/daptiles/daptiles.service.js.html +1 -1
  211. package/coverage/map/api/services/daptiles/index.html +1 -1
  212. package/coverage/map/api/services/features/features.hooks.js.html +1 -1
  213. package/coverage/map/api/services/features/index.html +1 -1
  214. package/coverage/map/api/services/geocoder/geocoder.hooks.js.html +1 -1
  215. package/coverage/map/api/services/geocoder/geocoder.service.js.html +1 -1
  216. package/coverage/map/api/services/geocoder/index.html +1 -1
  217. package/coverage/map/api/services/index.html +1 -1
  218. package/coverage/map/api/services/index.js.html +1 -1
  219. package/coverage/map/common/dynamic-grid-source.js.html +1 -1
  220. package/coverage/map/common/errors.js.html +1 -1
  221. package/coverage/map/common/geotiff-grid-source.js.html +1 -1
  222. package/coverage/map/common/grid.js.html +1 -1
  223. package/coverage/map/common/index.html +1 -1
  224. package/coverage/map/common/index.js.html +1 -1
  225. package/coverage/map/common/meteo-model-grid-source.js.html +1 -1
  226. package/coverage/map/common/moment-utils.js.html +1 -1
  227. package/coverage/map/common/opendap-grid-source.js.html +1 -1
  228. package/coverage/map/common/opendap-utils.js.html +1 -1
  229. package/coverage/map/common/permissions.js.html +1 -1
  230. package/coverage/map/common/time-based-grid-source.js.html +1 -1
  231. package/coverage/map/common/tms-utils.js.html +1 -1
  232. package/coverage/map/common/wcs-grid-source.js.html +1 -1
  233. package/coverage/map/common/wcs-utils.js.html +1 -1
  234. package/coverage/map/common/weacast-grid-source.js.html +1 -1
  235. package/coverage/map/common/wfs-utils.js.html +1 -1
  236. package/coverage/map/common/wms-utils.js.html +1 -1
  237. package/coverage/map/common/wmts-utils.js.html +1 -1
  238. package/extras/tours/map/navigation-bar.js +49 -1
  239. package/lib/core/api/application.js +35 -9
  240. package/lib/core/api/application.js.map +1 -1
  241. package/lib/core/api/hooks/hooks.authorisations.js +8 -1
  242. package/lib/core/api/hooks/hooks.authorisations.js.map +1 -1
  243. package/lib/core/api/hooks/hooks.query.js +135 -100
  244. package/lib/core/api/hooks/hooks.query.js.map +1 -1
  245. package/lib/core/api/services/authorisations/authorisations.service.js +13 -1
  246. package/lib/core/api/services/authorisations/authorisations.service.js.map +1 -1
  247. package/lib/core/api/services/pusher/pusher.service.js +40 -16
  248. package/lib/core/api/services/pusher/pusher.service.js.map +1 -1
  249. package/lib/core/client/components/collection/KColumn.vue +29 -28
  250. package/lib/core/client/components/collection/KFilter.vue +97 -72
  251. package/lib/core/client/components/editor/KModalEditor.vue +3 -4
  252. package/lib/core/client/components/editor/KSettingsEditor.vue +6 -2
  253. package/lib/core/client/components/form/KFileField.vue +14 -36
  254. package/lib/core/client/components/form/KRoleField.vue +5 -2
  255. package/lib/core/client/components/form/KTextField.vue +12 -2
  256. package/lib/core/client/components/form/KUnitField.vue +57 -0
  257. package/lib/core/client/components/form/KUrlField.vue +1 -1
  258. package/lib/core/client/components/frame/KAction.vue +1 -2
  259. package/lib/core/client/components/frame/KModal.vue +66 -20
  260. package/lib/core/client/components/frame/KScrollArea.vue +65 -0
  261. package/lib/core/client/components/frame/index.js +6 -1
  262. package/lib/core/client/components/frame/index.js.map +1 -1
  263. package/lib/core/client/components/input/KColorChooser.vue +3 -5
  264. package/lib/core/client/components/input/KIconChooser.vue +38 -40
  265. package/lib/core/client/components/input/KOptionsChooser.vue +2 -2
  266. package/lib/core/client/components/layout/KAbout.vue +47 -49
  267. package/lib/core/client/components/team/KAddMember.vue +1 -1
  268. package/lib/core/client/components/team/KChangeRole.vue +11 -14
  269. package/lib/core/client/components/team/KGroupCard.vue +12 -5
  270. package/lib/core/client/components/team/KGroupsActivity.vue +1 -1
  271. package/lib/core/client/components/team/KJoinGroup.vue +22 -22
  272. package/lib/core/client/components/team/KMemberCard.vue +19 -4
  273. package/lib/core/client/components/viewer/KModalViewer.vue +10 -9
  274. package/lib/core/client/i18n/core_en.json +72 -8
  275. package/lib/core/client/i18n/core_fr.json +66 -8
  276. package/lib/core/client/index.js +31 -0
  277. package/lib/core/client/index.js.map +1 -1
  278. package/lib/core/client/layout.js +8 -1
  279. package/lib/core/client/layout.js.map +1 -1
  280. package/lib/core/client/mixins/mixin.base-widget.js +5 -3
  281. package/lib/core/client/mixins/mixin.base-widget.js.map +1 -1
  282. package/lib/core/client/reader.js +85 -0
  283. package/lib/core/client/reader.js.map +1 -0
  284. package/lib/core/client/readers/index.js +30 -0
  285. package/lib/core/client/readers/index.js.map +1 -0
  286. package/lib/core/client/readers/reader.csv.js +54 -0
  287. package/lib/core/client/readers/reader.csv.js.map +1 -0
  288. package/lib/core/client/readers/reader.json.js +49 -0
  289. package/lib/core/client/readers/reader.json.js.map +1 -0
  290. package/lib/core/client/services/index.js +14 -3
  291. package/lib/core/client/services/index.js.map +1 -1
  292. package/lib/core/client/services/local-settings.service.js +6 -4
  293. package/lib/core/client/services/local-settings.service.js.map +1 -1
  294. package/lib/core/client/time.js +4 -3
  295. package/lib/core/client/time.js.map +1 -1
  296. package/lib/core/client/units.js +195 -0
  297. package/lib/core/client/units.js.map +1 -0
  298. package/lib/core/common/permissions.js +44 -34
  299. package/lib/core/common/permissions.js.map +1 -1
  300. package/lib/core/common/schemas/settings.update.json +72 -0
  301. package/lib/map/api/hooks/hooks.query.js +7 -2
  302. package/lib/map/api/hooks/hooks.query.js.map +1 -1
  303. package/lib/map/api/models/features.model.mongodb.js +3 -0
  304. package/lib/map/api/models/features.model.mongodb.js.map +1 -1
  305. package/lib/map/client/components/KCaptureToolbar.vue +151 -0
  306. package/lib/map/client/components/KColorLegend.vue +16 -4
  307. package/lib/map/client/components/KFeaturesChart.vue +10 -11
  308. package/lib/map/client/components/KFeaturesFilter.vue +40 -39
  309. package/lib/map/client/components/KFeaturesTable.vue +15 -16
  310. package/lib/map/client/components/KLayerEditionToolbar.vue +19 -11
  311. package/lib/map/client/components/KLayerStyleEditor.vue +3 -2
  312. package/lib/map/client/components/KLayerStyleForm.vue +38 -27
  313. package/lib/map/client/components/KMeasureTool.vue +337 -0
  314. package/lib/map/client/components/KTimeline.vue +5 -9
  315. package/lib/map/client/components/catalog/KAddLayer.vue +3 -2
  316. package/lib/map/client/components/catalog/KCatalog.vue +26 -7
  317. package/lib/map/client/components/catalog/KImportLayer.vue +8 -35
  318. package/lib/map/client/components/catalog/KLayerCategories.vue +3 -2
  319. package/lib/map/client/components/catalog/KLayersSelector.vue +8 -6
  320. package/lib/map/client/components/catalog/KWeatherLayersSelector.vue +1 -1
  321. package/lib/map/client/components/widget/KInformationBox.vue +8 -17
  322. package/lib/map/client/components/widget/KMapillaryViewer.vue +5 -1
  323. package/lib/map/client/components/widget/KTimeSeries.vue +92 -9
  324. package/lib/map/client/i18n/map_en.json +51 -20
  325. package/lib/map/client/i18n/map_fr.json +51 -20
  326. package/lib/map/client/init.js +7 -1
  327. package/lib/map/client/init.js.map +1 -1
  328. package/lib/map/client/leaflet/MaskLayer.js +9 -0
  329. package/lib/map/client/leaflet/MaskLayer.js.map +1 -1
  330. package/lib/map/client/mixins/globe/mixin.base-globe.js +3 -5
  331. package/lib/map/client/mixins/globe/mixin.base-globe.js.map +1 -1
  332. package/lib/map/client/mixins/globe/mixin.geojson-layers.js +16 -21
  333. package/lib/map/client/mixins/globe/mixin.geojson-layers.js.map +1 -1
  334. package/lib/map/client/mixins/globe/mixin.popup.js +7 -1
  335. package/lib/map/client/mixins/globe/mixin.popup.js.map +1 -1
  336. package/lib/map/client/mixins/globe/mixin.tooltip.js +7 -1
  337. package/lib/map/client/mixins/globe/mixin.tooltip.js.map +1 -1
  338. package/lib/map/client/mixins/map/mixin.base-map.js +54 -9
  339. package/lib/map/client/mixins/map/mixin.base-map.js.map +1 -1
  340. package/lib/map/client/mixins/map/mixin.canvas-layers.js +2 -0
  341. package/lib/map/client/mixins/map/mixin.canvas-layers.js.map +1 -1
  342. package/lib/map/client/mixins/map/mixin.file-layers.js +51 -97
  343. package/lib/map/client/mixins/map/mixin.file-layers.js.map +1 -1
  344. package/lib/map/client/mixins/map/mixin.geojson-layers.js +43 -11
  345. package/lib/map/client/mixins/map/mixin.geojson-layers.js.map +1 -1
  346. package/lib/map/client/mixins/map/mixin.popup.js +7 -1
  347. package/lib/map/client/mixins/map/mixin.popup.js.map +1 -1
  348. package/lib/map/client/mixins/map/mixin.style.js +1 -1
  349. package/lib/map/client/mixins/map/mixin.style.js.map +1 -1
  350. package/lib/map/client/mixins/map/mixin.tooltip.js +7 -1
  351. package/lib/map/client/mixins/map/mixin.tooltip.js.map +1 -1
  352. package/lib/map/client/mixins/mixin.activity.js +2 -0
  353. package/lib/map/client/mixins/mixin.activity.js.map +1 -1
  354. package/lib/map/client/mixins/mixin.context.js +26 -3
  355. package/lib/map/client/mixins/mixin.context.js.map +1 -1
  356. package/lib/map/client/mixins/mixin.feature-service.js +3 -3
  357. package/lib/map/client/mixins/mixin.feature-service.js.map +1 -1
  358. package/lib/map/client/mixins/mixin.infobox.js +4 -0
  359. package/lib/map/client/mixins/mixin.infobox.js.map +1 -1
  360. package/lib/map/client/mixins/mixin.weacast.js +7 -5
  361. package/lib/map/client/mixins/mixin.weacast.js.map +1 -1
  362. package/lib/map/client/readers/index.js +54 -0
  363. package/lib/map/client/readers/index.js.map +1 -0
  364. package/lib/map/client/readers/reader.geojson.js +87 -0
  365. package/lib/map/client/readers/reader.geojson.js.map +1 -0
  366. package/lib/map/client/readers/reader.gpx.js +52 -0
  367. package/lib/map/client/readers/reader.gpx.js.map +1 -0
  368. package/lib/map/client/readers/reader.kml.js +52 -0
  369. package/lib/map/client/readers/reader.kml.js.map +1 -0
  370. package/lib/map/client/readers/reader.shp.js +116 -0
  371. package/lib/map/client/readers/reader.shp.js.map +1 -0
  372. package/lib/map/client/utils.js +0 -7
  373. package/lib/map/client/utils.js.map +1 -1
  374. package/lib/test/client/core/account.js +1 -1
  375. package/lib/test/client/core/account.js.map +1 -1
  376. package/lib/test/client/core/runner.js +1 -2
  377. package/lib/test/client/core/runner.js.map +1 -1
  378. package/lib/test/client/core/screens.js +1 -1
  379. package/lib/test/client/core/screens.js.map +1 -1
  380. package/lib/test/client/core/utils.js +2 -2
  381. package/lib/test/client/core/utils.js.map +1 -1
  382. package/lib/test/client/map/catalog.js +50 -49
  383. package/lib/test/client/map/catalog.js.map +1 -1
  384. package/package.json +3 -3
  385. package/.nyc_output/2c5b7c8e-81db-4d2c-a7a4-02dc640d301f.json +0 -1
  386. package/.nyc_output/a762cb58-70dc-4d39-ab69-928635affa98.json +0 -1
  387. package/.nyc_output/processinfo/2c5b7c8e-81db-4d2c-a7a4-02dc640d301f.json +0 -1
  388. package/.nyc_output/processinfo/2e74ca23-8cf0-4161-9536-f71c2a1a74bb.json +0 -1
  389. package/.nyc_output/processinfo/81d21e46-766a-46bc-b1b7-143ca577347a.json +0 -1
  390. package/.nyc_output/processinfo/a762cb58-70dc-4d39-ab69-928635affa98.json +0 -1
  391. package/.nyc_output/processinfo/aaf3ebbb-f895-4d7b-9255-bc5dee832570.json +0 -1
  392. package/.nyc_output/processinfo/dbeb2602-0ac2-4e66-978b-0d29548359ca.json +0 -1
  393. package/.nyc_output/processinfo/e47d1e4c-2fff-4dcb-908f-d3081162547c.json +0 -1
  394. package/extras/testcafe/Dockerfile +0 -48
  395. package/extras/testcafe/docker-entrypoint.sh +0 -27
  396. package/extras/testcafe/page-models/core/account.js +0 -75
  397. package/extras/testcafe/page-models/core/base-collection.js +0 -41
  398. package/extras/testcafe/page-models/core/base-page.js +0 -25
  399. package/extras/testcafe/page-models/core/groups.js +0 -36
  400. package/extras/testcafe/page-models/core/index.js +0 -140
  401. package/extras/testcafe/page-models/core/layout.js +0 -145
  402. package/extras/testcafe/page-models/core/members.js +0 -98
  403. package/extras/testcafe/page-models/core/organisations.js +0 -76
  404. package/extras/testcafe/page-models/core/screens.js +0 -99
  405. package/extras/testcafe/page-models/core/tags.js +0 -21
  406. package/extras/testcafe/page-models/map/add-layer.js +0 -51
  407. package/extras/testcafe/page-models/map/catalog.js +0 -132
  408. package/extras/testcafe/page-models/map/index.js +0 -36
  409. package/extras/testcafe/page-models/map/map-activity.js +0 -42
  410. package/extras/testcafe/page-models/map/timeline.js +0 -67
@@ -84,6 +84,23 @@
84
84
  ]
85
85
  }
86
86
  },
87
+ "timelineInterval": {
88
+ "type": "number",
89
+ "group": "schemas.TIMELINE_SETTINGS",
90
+ "field": {
91
+ "component": "form/KSelectField",
92
+ "label": "schemas.TIMELINE_INTERVAL",
93
+ "options": [
94
+ { "label": "10s", "value": 10 },
95
+ { "label": "30s", "value": 30 },
96
+ { "label": "1m", "value": 60, "selected": true },
97
+ { "label": "5m", "value": 300 },
98
+ { "label": "10m", "value": 600 },
99
+ { "label": "15m", "value": 900 },
100
+ { "label": "30m", "value": 1800 }
101
+ ]
102
+ }
103
+ },
87
104
  "timeseriesSpan": {
88
105
  "type": "number",
89
106
  "group": "schemas.TIMESERIES_SETTINGS",
@@ -125,6 +142,61 @@
125
142
  "label": "schemas.LOCATION_FORMAT_LABEL",
126
143
  "helper": "schemas.LOCATION_FORMAT_HELPER"
127
144
  }
145
+ },
146
+ "defaultLength": {
147
+ "type": "string",
148
+ "group": "schemas.UNITS_SETTINGS",
149
+ "field": {
150
+ "component": "form/KUnitField",
151
+ "label": "schemas.LENGTH_FIELD_LABEL",
152
+ "quantity": "length"
153
+ }
154
+ },
155
+ "defaultArea": {
156
+ "type": "string",
157
+ "group": "schemas.UNITS_SETTINGS",
158
+ "field": {
159
+ "component": "form/KUnitField",
160
+ "label": "schemas.AREA_FIELD_LABEL",
161
+ "quantity": "area"
162
+ }
163
+ },
164
+ "defaultVelocity": {
165
+ "type": "string",
166
+ "group": "schemas.UNITS_SETTINGS",
167
+ "field": {
168
+ "component": "form/KUnitField",
169
+ "label": "schemas.VELOCITY_FIELD_LABEL",
170
+ "quantity": "velocity"
171
+ }
172
+ },
173
+ "defaultTemperature": {
174
+ "type": "string",
175
+ "group": "schemas.UNITS_SETTINGS",
176
+ "field": {
177
+ "component": "form/KUnitField",
178
+ "label": "schemas.TEMPERATURE_FIELD_LABEL",
179
+ "quantity": "temperature"
180
+ }
181
+ },
182
+ "defaultAngle": {
183
+ "type": "string",
184
+ "group": "schemas.UNITS_SETTINGS",
185
+ "field": {
186
+ "component": "form/KUnitField",
187
+ "label": "schemas.ANGLE_FIELD_LABEL",
188
+ "quantity": "angle"
189
+ }
190
+ },
191
+ "defaultPrecision": {
192
+ "type": "number",
193
+ "group": "schemas.UNITS_SETTINGS",
194
+ "field": {
195
+ "component": "form/KNumberField",
196
+ "label": "schemas.PRECISION_FIELD_LABEL",
197
+ "min": 0,
198
+ "max": 5
199
+ }
128
200
  }
129
201
  },
130
202
  "required": [
@@ -38,6 +38,7 @@ let aggregateFeaturesQuery = exports.aggregateFeaturesQuery = (() => {
38
38
  } else {
39
39
  Object.assign(groupBy, {
40
40
  time: { $push: '$time' }, // Keep track of all times
41
+ runTime: { $push: '$runTime' }, // Keep track of all run times
41
42
  type: { $last: '$type' }, // type is assumed similar for all results, keep last
42
43
  properties: { $last: '$properties' // non-aggregated properties are assumed similar for all results, keep last
43
44
  } });
@@ -73,8 +74,8 @@ let aggregateFeaturesQuery = exports.aggregateFeaturesQuery = (() => {
73
74
  }
74
75
  // Find matching features only
75
76
  pipeline.push({ $match: Object.assign({ [prefix + element]: { $exists: true } }, match) });
76
- // Ensure they are ordered by increasing time by default
77
- pipeline.push({ $sort: query.$sort || { time: 1 } });
77
+ // Ensure they are ordered by increasing time by default and most recent forecast first
78
+ pipeline.push({ $sort: Object.assign({ time: 1, runTime: -1 }, query.$sort) });
78
79
  // Keep track of all feature values
79
80
  if (singleTime) {
80
81
  pipeline.push({ $group: groupBy });
@@ -93,6 +94,7 @@ let aggregateFeaturesQuery = exports.aggregateFeaturesQuery = (() => {
93
94
  // Rearrange data so that we get ordered arrays indexed by element
94
95
  elementResults.forEach(function (result) {
95
96
  result.time = { [element]: result.time };
97
+ if (result.runTime) result.runTime = { [element]: result.runTime };
96
98
  if (!singleTime && !isGeometry) {
97
99
  // Set back the element values as properties because we aggregated in an accumulator
98
100
  // to avoid conflict with non-aggregated feature properties
@@ -114,6 +116,9 @@ let aggregateFeaturesQuery = exports.aggregateFeaturesQuery = (() => {
114
116
  // Merge with previous matching feature if any
115
117
  if (previousResult) {
116
118
  Object.assign(previousResult.time, result.time);
119
+ if (result.runTime) {
120
+ if (previousResult.runTime) Object.assign(previousResult.runTime, result.runTime);else previousResult.runTime = { [element]: result.runTime };
121
+ }
117
122
  _lodash2.default.set(previousResult, prefix + element, _lodash2.default.get(result, prefix + element));
118
123
  } else {
119
124
  aggregatedResults.push(result);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../map/api/hooks/hooks.query.js"],"names":["hook","query","params","service","$aggregate","collection","Model","featureId","options","featureIdType","ids","$groupBy","reduce","object","id","Object","assign","groupBy","_id","keys","_","singleTime","toNumber","$limit","map","key","feature","$first","time","$push","type","$last","properties","includes","geometry","match","omit","aggregateOptions","has","set","get","hint","aggregatedResults","Promise","all","element","isGeometry","prefix","pipeline","$geoNear","push","$match","$exists","$sort","$group","$replaceRoot","newRoot","debug","forEach","forOwn","stage","value","elementResults","aggregate","toArray","length","result","unset","resultKeys","pick","previousResult","find","aggregatedResultKeys","aggregatedResult","isEqual","aggregateFeaturesQuery","marshallGeometryQuery","marshallSpatialQuery","asGeoJson","isNil","centerLon","longitude","centerLat","latitude","distance","near","coordinates","maxDistance","distanceField","spherical","$geoWithin","$centerSphere","south","north","west","east","geometryQuery","$geoIntersects","$geometry","geoJson","force","$distinct","$aggregation","longitudeProperty","latitudeProperty","altitudeProperty","geometryProperty","results","dataPath","isPaginated","data","pagination","filter","item","Array","isArray","geometries","mapping","from","to","delete","features"],"mappings":"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","file":"hooks.query.js","sourcesContent":["import _ from 'lodash'\r\nimport { marshallGeometry } from '../marshall'\r\nimport makeDebug from 'debug'\r\n\r\nconst debug = makeDebug('kdk:map:query:hooks')\r\n\r\nexport function marshallGeometryQuery (hook) {\r\n const query = hook.params.query\r\n if (_.isNil(query)) return\r\n const geometry = query.geometry\r\n if (_.isNil(geometry)) return\r\n marshallGeometry(geometry)\r\n}\r\n\r\nexport function marshallSpatialQuery (hook) {\r\n const query = hook.params.query\r\n if (query) {\r\n if (!_.isNil(query.geometry)) marshallGeometry(query.geometry)\r\n // Shortcut for proximity query\r\n if ((!_.isNil(query.centerLon) || !_.isNil(query.longitude)) &&\r\n (!_.isNil(query.centerLat) || !_.isNil(query.latitude)) && !_.isNil(query.distance)) {\r\n const longitude = (_.isNil(query.centerLon) ? _.toNumber(query.longitude) : _.toNumber(query.centerLon))\r\n const latitude = (_.isNil(query.centerLat) ? _.toNumber(query.latitude) : _.toNumber(query.centerLat))\r\n const distance = _.toNumber(query.distance)\r\n // Transform to MongoDB spatial request\r\n delete query.centerLon\r\n delete query.longitude\r\n delete query.centerLat\r\n delete query.latitude\r\n delete query.distance\r\n // Aggregation requires a specific operator\r\n if (query.$aggregate) {\r\n query.$geoNear = {\r\n near: { type: 'Point', coordinates: [longitude, latitude] },\r\n maxDistance: distance,\r\n distanceField: 'distance',\r\n spherical: true\r\n }\r\n } else {\r\n /* We switched from $near to $geoWithin due to https://github.com/kalisio/kdk/issues/345\r\n query.geometry = {\r\n $near: {\r\n $geometry: {\r\n type: 'Point',\r\n coordinates: [longitude, latitude]\r\n },\r\n $maxDistance: distance\r\n }\r\n }\r\n */\r\n query.geometry = {\r\n $geoWithin: {\r\n $centerSphere: [[longitude, latitude], distance / 6378137.0] // Earth radius as in radians\r\n }\r\n }\r\n }\r\n }\r\n // Shortcut for bbox query\r\n if (!_.isNil(query.south) && !_.isNil(query.north) && !_.isNil(query.west) && !_.isNil(query.east)) {\r\n const south = _.toNumber(query.south)\r\n const north = _.toNumber(query.north)\r\n const west = _.toNumber(query.west)\r\n const east = _.toNumber(query.east)\r\n // Transform to MongoDB spatial request\r\n delete query.south\r\n delete query.north\r\n delete query.west\r\n delete query.east\r\n const geometryQuery = {\r\n $geoIntersects: {\r\n $geometry: {\r\n type: 'Polygon',\r\n coordinates: [ // BBox as a polygon\r\n [[west, south], [east, south], [east, north], [west, north], [west, south]] // Closing point\r\n ]\r\n }\r\n }\r\n }\r\n query.geometry = geometryQuery\r\n }\r\n // Shortcut for location query\r\n if (!_.isNil(query.longitude) && !_.isNil(query.latitude)) {\r\n const longitude = _.toNumber(query.longitude)\r\n const latitude = _.toNumber(query.latitude)\r\n // Transform to MongoDB spatial request\r\n delete query.longitude\r\n delete query.latitude\r\n const geometryQuery = {\r\n $geoIntersects: {\r\n $geometry: {\r\n type: 'Point',\r\n coordinates: [longitude, latitude]\r\n }\r\n }\r\n }\r\n query.geometry = geometryQuery\r\n }\r\n if (query.geoJson) {\r\n delete query.geoJson\r\n hook.params.asGeoJson = true\r\n }\r\n }\r\n}\r\n\r\nexport function asGeoJson (options = {}) {\r\n return function (hook) {\r\n const params = hook.params\r\n const query = params.query\r\n if (!options.force && !params.asGeoJson) return\r\n if (query.$distinct || query.$aggregation) return // Not applicable in this case\r\n const longitudeProperty = (options.longitudeProperty || 'longitude')\r\n const latitudeProperty = (options.latitudeProperty || 'latitude')\r\n const altitudeProperty = (options.altitudeProperty || 'altitude')\r\n const geometryProperty = (options.geometryProperty || 'geometry')\r\n let results = _.get(hook, options.dataPath || 'result')\r\n // Already as GeoJson ?\r\n if (results.type === 'FeatureCollection') return\r\n const isPaginated = !_.isNil(results.data)\r\n const pagination = (isPaginated ? _.pick(results, ['total', 'skip', 'limit']) : {})\r\n results = (isPaginated ? results.data : results)\r\n results = results\r\n .filter(item => {\r\n // Check if item is not already in GeoJson feature format and we can convert if required\r\n return (_.has(item, longitudeProperty) && _.has(item, latitudeProperty)) ||\r\n // When performing feature aggregation on geometries the result can be an array\r\n Array.isArray(_.get(item, geometryProperty)) ||\r\n // Check for a geometry property (previously provided or already transformed item)\r\n (_.has(item, geometryProperty + '.type') && _.has(item, geometryProperty + '.coordinates'))\r\n })\r\n .map(item => {\r\n let coordinates\r\n // Keep track of coordinates before picking properties\r\n if (_.has(item, longitudeProperty) && _.has(item, latitudeProperty)) {\r\n coordinates = [_.get(item, longitudeProperty), _.get(item, latitudeProperty)]\r\n if (_.has(item, altitudeProperty)) {\r\n coordinates.push(_.get(item, altitudeProperty))\r\n }\r\n }\r\n if (options.pick) {\r\n item = _.pick(item, options.pick)\r\n }\r\n if (options.omit) {\r\n item = _.omit(item, options.omit)\r\n }\r\n // Item locations are already in GeoJson format\r\n if (_.has(item, geometryProperty + '.type') && _.has(item, geometryProperty + '.coordinates')) {\r\n return Object.assign({\r\n type: 'Feature',\r\n geometry: _.get(item, geometryProperty),\r\n properties: {}\r\n }, _.omit(item, [geometryProperty]))\r\n } else if (Array.isArray(_.get(item, geometryProperty))) {\r\n return Object.assign({\r\n type: 'Feature',\r\n geometry: { type: 'GeometryCollection', geometries: _.get(item, geometryProperty) },\r\n properties: {}\r\n }, _.omit(item, [geometryProperty]))\r\n } else if (coordinates) {\r\n // Item locations are not already in GeoJson feature format so we need to convert\r\n return Object.assign({\r\n type: 'Feature',\r\n geometry: { type: 'Point', coordinates },\r\n properties: {}\r\n }, _.omit(item, [longitudeProperty, latitudeProperty]))\r\n }\r\n })\r\n // Move some data to properties ?\r\n if (options.properties) {\r\n results.forEach(item => {\r\n options.properties.forEach(mapping => {\r\n if (mapping.from) _.set(item, `properties.${mapping.to || mapping.from}`, _.get(item, `${mapping.from}`))\r\n if (mapping.delete) _.unset(item, `${mapping.from}`)\r\n })\r\n })\r\n }\r\n // Copy pagination information if any so that client can use it anyway\r\n if (_.get(options, 'asFeatureCollection', true)) {\r\n _.set(hook, options.dataPath || 'result', Object.assign({\r\n type: 'FeatureCollection',\r\n features: results\r\n }, pagination)) // If no pagination this merged object will be empty\r\n } else if (isPaginated) {\r\n _.set(hook, options.dataPath || 'result', Object.assign({\r\n data: results\r\n }, pagination))\r\n } else {\r\n _.set(hook, options.dataPath || 'result', results)\r\n }\r\n }\r\n}\r\n\r\nexport async function aggregateFeaturesQuery (hook) {\r\n const query = hook.params.query\r\n const service = hook.service\r\n if (!query) return\r\n // Perform aggregation\r\n if (query.$aggregate) {\r\n const collection = service.Model\r\n const featureId = (service.options ? service.options.featureId : '')\r\n const featureIdType = (service.options ? service.options.featureIdType : 'string')\r\n const ids = typeof query.$groupBy === 'string' // Group by matching ID(s), ie single ID or array of field to create a compound ID\r\n ? { [query.$groupBy]: '$properties.' + query.$groupBy }\r\n // Aggregated in an accumulator to avoid conflict with feature properties\r\n : query.$groupBy.reduce((object, id) => Object.assign(object, { [id]: '$properties.' + id }), {})\r\n const groupBy = { _id: ids }\r\n let keys = _.keys(ids)\r\n // Do we only keep first or last available time ?\r\n const singleTime = (_.toNumber(query.$limit) === 1)\r\n if (singleTime) {\r\n // When single time no aggregation is performed at all so we only have raw features\r\n keys = keys.map(key => 'properties.' + key)\r\n // In this case no need to aggregate on each element we simply keep the first feature\r\n // BUG: according to https://jira.mongodb.org/browse/SERVER-9507 MongoDB is not yet\r\n // able to optimize this kind of operations to avoid full index scan\r\n // For now we should restrict it to short time range\r\n Object.assign(groupBy, { feature: { $first: '$$ROOT' } })\r\n } else {\r\n Object.assign(groupBy, {\r\n time: { $push: '$time' }, // Keep track of all times\r\n type: { $last: '$type' }, // type is assumed similar for all results, keep last\r\n properties: { $last: '$properties' } // non-aggregated properties are assumed similar for all results, keep last\r\n })\r\n // Check if we aggregate geometry or simply properties\r\n if (!query.$aggregate.includes('geometry')) {\r\n Object.assign(groupBy, {\r\n geometry: { $last: '$geometry' } // geometry is assumed similar for all results, keep last\r\n })\r\n }\r\n }\r\n // The query contains the match stage except options relevent to the aggregation pipeline\r\n const match = _.omit(query, ['$groupBy', '$aggregate', '$geoNear', '$sort', '$limit', '$skip'])\r\n const aggregateOptions = {}\r\n // Check for any required type conversion (eg HTTP requests)\r\n if (featureId && _.has(match, 'properties.' + featureId)) {\r\n if (featureIdType === 'number') _.set(match, 'properties.' + featureId, _.toNumber(_.get(match, 'properties.' + featureId)))\r\n // Check if we could provide a hint to the aggregation when targeting feature ID\r\n // Indeed, in that case, we define the appropriate index\r\n aggregateOptions.hint = { ['properties.' + featureId]: 1 }\r\n }\r\n // Ensure we do not mix results with/without relevant element values\r\n // by separately querying each element then merging\r\n let aggregatedResults\r\n await Promise.all(query.$aggregate.map(async element => {\r\n const isGeometry = (element === 'geometry')\r\n // Geometry is a root property while others are feature properties\r\n const prefix = (isGeometry ? '' : 'properties.')\r\n const pipeline = []\r\n // Check for geometry stage\r\n if (query.$geoNear) {\r\n pipeline.push({ $geoNear: query.$geoNear })\r\n }\r\n // Find matching features only\r\n pipeline.push({ $match: Object.assign({ [prefix + element]: { $exists: true } }, match) })\r\n // Ensure they are ordered by increasing time by default\r\n pipeline.push({ $sort: query.$sort || { time: 1 } })\r\n // Keep track of all feature values\r\n if (singleTime) {\r\n pipeline.push({ $group: groupBy })\r\n pipeline.push({ $replaceRoot: { newRoot: '$feature' } })\r\n } else {\r\n pipeline.push({ $group: Object.assign({ [element]: { $push: '$' + prefix + element } }, groupBy) })\r\n }\r\n debug(`Aggregating ${element} element for features`)\r\n pipeline.forEach(stage => {\r\n _.forOwn(stage, (value, key) => debug('Stage', key, value))\r\n })\r\n const elementResults = await collection.aggregate(pipeline, aggregateOptions).toArray()\r\n debug(`Generated ${elementResults.length} feature(s) for ${element} element`, elementResults)\r\n // Rearrange data so that we get ordered arrays indexed by element\r\n elementResults.forEach(result => {\r\n result.time = { [element]: result.time }\r\n if (!singleTime && !isGeometry) {\r\n // Set back the element values as properties because we aggregated in an accumulator\r\n // to avoid conflict with non-aggregated feature properties\r\n _.set(result, prefix + element, _.get(result, element))\r\n // Delete accumulator\r\n _.unset(result, element)\r\n }\r\n })\r\n // Now merge with previous element results\r\n if (!aggregatedResults) {\r\n aggregatedResults = elementResults\r\n } else {\r\n elementResults.forEach(result => {\r\n const resultKeys = _.pick(result, keys)\r\n const previousResult = aggregatedResults.find(aggregatedResult => {\r\n const aggregatedResultKeys = _.pick(aggregatedResult, keys)\r\n return _.isEqual(aggregatedResultKeys, resultKeys)\r\n })\r\n // Merge with previous matching feature if any\r\n if (previousResult) {\r\n Object.assign(previousResult.time, result.time)\r\n _.set(previousResult, prefix + element, _.get(result, prefix + element))\r\n } else {\r\n aggregatedResults.push(result)\r\n }\r\n })\r\n }\r\n }))\r\n delete query.$groupBy\r\n delete query.$aggregate\r\n delete query.$geoNear\r\n // Set result to avoid service DB call\r\n hook.result = aggregatedResults\r\n }\r\n return hook\r\n}\r\n"]}
1
+ {"version":3,"sources":["../../../../map/api/hooks/hooks.query.js"],"names":["hook","query","params","service","$aggregate","collection","Model","featureId","options","featureIdType","ids","$groupBy","reduce","object","id","Object","assign","groupBy","_id","keys","_","singleTime","toNumber","$limit","map","key","feature","$first","time","$push","runTime","type","$last","properties","includes","geometry","match","omit","aggregateOptions","has","set","get","hint","aggregatedResults","Promise","all","element","isGeometry","prefix","pipeline","$geoNear","push","$match","$exists","$sort","$group","$replaceRoot","newRoot","debug","forEach","forOwn","stage","value","elementResults","aggregate","toArray","length","result","unset","resultKeys","pick","previousResult","find","aggregatedResultKeys","aggregatedResult","isEqual","aggregateFeaturesQuery","marshallGeometryQuery","marshallSpatialQuery","asGeoJson","isNil","centerLon","longitude","centerLat","latitude","distance","near","coordinates","maxDistance","distanceField","spherical","$geoWithin","$centerSphere","south","north","west","east","geometryQuery","$geoIntersects","$geometry","geoJson","force","$distinct","$aggregation","longitudeProperty","latitudeProperty","altitudeProperty","geometryProperty","results","dataPath","isPaginated","data","pagination","filter","item","Array","isArray","geometries","mapping","from","to","delete","features"],"mappings":"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","file":"hooks.query.js","sourcesContent":["import _ from 'lodash'\r\nimport { marshallGeometry } from '../marshall'\r\nimport makeDebug from 'debug'\r\n\r\nconst debug = makeDebug('kdk:map:query:hooks')\r\n\r\nexport function marshallGeometryQuery (hook) {\r\n const query = hook.params.query\r\n if (_.isNil(query)) return\r\n const geometry = query.geometry\r\n if (_.isNil(geometry)) return\r\n marshallGeometry(geometry)\r\n}\r\n\r\nexport function marshallSpatialQuery (hook) {\r\n const query = hook.params.query\r\n if (query) {\r\n if (!_.isNil(query.geometry)) marshallGeometry(query.geometry)\r\n // Shortcut for proximity query\r\n if ((!_.isNil(query.centerLon) || !_.isNil(query.longitude)) &&\r\n (!_.isNil(query.centerLat) || !_.isNil(query.latitude)) && !_.isNil(query.distance)) {\r\n const longitude = (_.isNil(query.centerLon) ? _.toNumber(query.longitude) : _.toNumber(query.centerLon))\r\n const latitude = (_.isNil(query.centerLat) ? _.toNumber(query.latitude) : _.toNumber(query.centerLat))\r\n const distance = _.toNumber(query.distance)\r\n // Transform to MongoDB spatial request\r\n delete query.centerLon\r\n delete query.longitude\r\n delete query.centerLat\r\n delete query.latitude\r\n delete query.distance\r\n // Aggregation requires a specific operator\r\n if (query.$aggregate) {\r\n query.$geoNear = {\r\n near: { type: 'Point', coordinates: [longitude, latitude] },\r\n maxDistance: distance,\r\n distanceField: 'distance',\r\n spherical: true\r\n }\r\n } else {\r\n /* We switched from $near to $geoWithin due to https://github.com/kalisio/kdk/issues/345\r\n query.geometry = {\r\n $near: {\r\n $geometry: {\r\n type: 'Point',\r\n coordinates: [longitude, latitude]\r\n },\r\n $maxDistance: distance\r\n }\r\n }\r\n */\r\n query.geometry = {\r\n $geoWithin: {\r\n $centerSphere: [[longitude, latitude], distance / 6378137.0] // Earth radius as in radians\r\n }\r\n }\r\n }\r\n }\r\n // Shortcut for bbox query\r\n if (!_.isNil(query.south) && !_.isNil(query.north) && !_.isNil(query.west) && !_.isNil(query.east)) {\r\n const south = _.toNumber(query.south)\r\n const north = _.toNumber(query.north)\r\n const west = _.toNumber(query.west)\r\n const east = _.toNumber(query.east)\r\n // Transform to MongoDB spatial request\r\n delete query.south\r\n delete query.north\r\n delete query.west\r\n delete query.east\r\n const geometryQuery = {\r\n $geoIntersects: {\r\n $geometry: {\r\n type: 'Polygon',\r\n coordinates: [ // BBox as a polygon\r\n [[west, south], [east, south], [east, north], [west, north], [west, south]] // Closing point\r\n ]\r\n }\r\n }\r\n }\r\n query.geometry = geometryQuery\r\n }\r\n // Shortcut for location query\r\n if (!_.isNil(query.longitude) && !_.isNil(query.latitude)) {\r\n const longitude = _.toNumber(query.longitude)\r\n const latitude = _.toNumber(query.latitude)\r\n // Transform to MongoDB spatial request\r\n delete query.longitude\r\n delete query.latitude\r\n const geometryQuery = {\r\n $geoIntersects: {\r\n $geometry: {\r\n type: 'Point',\r\n coordinates: [longitude, latitude]\r\n }\r\n }\r\n }\r\n query.geometry = geometryQuery\r\n }\r\n if (query.geoJson) {\r\n delete query.geoJson\r\n hook.params.asGeoJson = true\r\n }\r\n }\r\n}\r\n\r\nexport function asGeoJson (options = {}) {\r\n return function (hook) {\r\n const params = hook.params\r\n const query = params.query\r\n if (!options.force && !params.asGeoJson) return\r\n if (query.$distinct || query.$aggregation) return // Not applicable in this case\r\n const longitudeProperty = (options.longitudeProperty || 'longitude')\r\n const latitudeProperty = (options.latitudeProperty || 'latitude')\r\n const altitudeProperty = (options.altitudeProperty || 'altitude')\r\n const geometryProperty = (options.geometryProperty || 'geometry')\r\n let results = _.get(hook, options.dataPath || 'result')\r\n // Already as GeoJson ?\r\n if (results.type === 'FeatureCollection') return\r\n const isPaginated = !_.isNil(results.data)\r\n const pagination = (isPaginated ? _.pick(results, ['total', 'skip', 'limit']) : {})\r\n results = (isPaginated ? results.data : results)\r\n results = results\r\n .filter(item => {\r\n // Check if item is not already in GeoJson feature format and we can convert if required\r\n return (_.has(item, longitudeProperty) && _.has(item, latitudeProperty)) ||\r\n // When performing feature aggregation on geometries the result can be an array\r\n Array.isArray(_.get(item, geometryProperty)) ||\r\n // Check for a geometry property (previously provided or already transformed item)\r\n (_.has(item, geometryProperty + '.type') && _.has(item, geometryProperty + '.coordinates'))\r\n })\r\n .map(item => {\r\n let coordinates\r\n // Keep track of coordinates before picking properties\r\n if (_.has(item, longitudeProperty) && _.has(item, latitudeProperty)) {\r\n coordinates = [_.get(item, longitudeProperty), _.get(item, latitudeProperty)]\r\n if (_.has(item, altitudeProperty)) {\r\n coordinates.push(_.get(item, altitudeProperty))\r\n }\r\n }\r\n if (options.pick) {\r\n item = _.pick(item, options.pick)\r\n }\r\n if (options.omit) {\r\n item = _.omit(item, options.omit)\r\n }\r\n // Item locations are already in GeoJson format\r\n if (_.has(item, geometryProperty + '.type') && _.has(item, geometryProperty + '.coordinates')) {\r\n return Object.assign({\r\n type: 'Feature',\r\n geometry: _.get(item, geometryProperty),\r\n properties: {}\r\n }, _.omit(item, [geometryProperty]))\r\n } else if (Array.isArray(_.get(item, geometryProperty))) {\r\n return Object.assign({\r\n type: 'Feature',\r\n geometry: { type: 'GeometryCollection', geometries: _.get(item, geometryProperty) },\r\n properties: {}\r\n }, _.omit(item, [geometryProperty]))\r\n } else if (coordinates) {\r\n // Item locations are not already in GeoJson feature format so we need to convert\r\n return Object.assign({\r\n type: 'Feature',\r\n geometry: { type: 'Point', coordinates },\r\n properties: {}\r\n }, _.omit(item, [longitudeProperty, latitudeProperty]))\r\n }\r\n })\r\n // Move some data to properties ?\r\n if (options.properties) {\r\n results.forEach(item => {\r\n options.properties.forEach(mapping => {\r\n if (mapping.from) _.set(item, `properties.${mapping.to || mapping.from}`, _.get(item, `${mapping.from}`))\r\n if (mapping.delete) _.unset(item, `${mapping.from}`)\r\n })\r\n })\r\n }\r\n // Copy pagination information if any so that client can use it anyway\r\n if (_.get(options, 'asFeatureCollection', true)) {\r\n _.set(hook, options.dataPath || 'result', Object.assign({\r\n type: 'FeatureCollection',\r\n features: results\r\n }, pagination)) // If no pagination this merged object will be empty\r\n } else if (isPaginated) {\r\n _.set(hook, options.dataPath || 'result', Object.assign({\r\n data: results\r\n }, pagination))\r\n } else {\r\n _.set(hook, options.dataPath || 'result', results)\r\n }\r\n }\r\n}\r\n\r\nexport async function aggregateFeaturesQuery (hook) {\r\n const query = hook.params.query\r\n const service = hook.service\r\n if (!query) return\r\n // Perform aggregation\r\n if (query.$aggregate) {\r\n const collection = service.Model\r\n const featureId = (service.options ? service.options.featureId : '')\r\n const featureIdType = (service.options ? service.options.featureIdType : 'string')\r\n const ids = typeof query.$groupBy === 'string' // Group by matching ID(s), ie single ID or array of field to create a compound ID\r\n ? { [query.$groupBy]: '$properties.' + query.$groupBy }\r\n // Aggregated in an accumulator to avoid conflict with feature properties\r\n : query.$groupBy.reduce((object, id) => Object.assign(object, { [id]: '$properties.' + id }), {})\r\n const groupBy = { _id: ids }\r\n let keys = _.keys(ids)\r\n // Do we only keep first or last available time ?\r\n const singleTime = (_.toNumber(query.$limit) === 1)\r\n if (singleTime) {\r\n // When single time no aggregation is performed at all so we only have raw features\r\n keys = keys.map(key => 'properties.' + key)\r\n // In this case no need to aggregate on each element we simply keep the first feature\r\n // BUG: according to https://jira.mongodb.org/browse/SERVER-9507 MongoDB is not yet\r\n // able to optimize this kind of operations to avoid full index scan\r\n // For now we should restrict it to short time range\r\n Object.assign(groupBy, { feature: { $first: '$$ROOT' } })\r\n } else {\r\n Object.assign(groupBy, {\r\n time: { $push: '$time' }, // Keep track of all times\r\n runTime: { $push: '$runTime' }, // Keep track of all run times\r\n type: { $last: '$type' }, // type is assumed similar for all results, keep last\r\n properties: { $last: '$properties' } // non-aggregated properties are assumed similar for all results, keep last\r\n })\r\n // Check if we aggregate geometry or simply properties\r\n if (!query.$aggregate.includes('geometry')) {\r\n Object.assign(groupBy, {\r\n geometry: { $last: '$geometry' } // geometry is assumed similar for all results, keep last\r\n })\r\n }\r\n }\r\n // The query contains the match stage except options relevent to the aggregation pipeline\r\n const match = _.omit(query, ['$groupBy', '$aggregate', '$geoNear', '$sort', '$limit', '$skip'])\r\n const aggregateOptions = {}\r\n // Check for any required type conversion (eg HTTP requests)\r\n if (featureId && _.has(match, 'properties.' + featureId)) {\r\n if (featureIdType === 'number') _.set(match, 'properties.' + featureId, _.toNumber(_.get(match, 'properties.' + featureId)))\r\n // Check if we could provide a hint to the aggregation when targeting feature ID\r\n // Indeed, in that case, we define the appropriate index\r\n aggregateOptions.hint = { ['properties.' + featureId]: 1 }\r\n }\r\n // Ensure we do not mix results with/without relevant element values\r\n // by separately querying each element then merging\r\n let aggregatedResults\r\n await Promise.all(query.$aggregate.map(async element => {\r\n const isGeometry = (element === 'geometry')\r\n // Geometry is a root property while others are feature properties\r\n const prefix = (isGeometry ? '' : 'properties.')\r\n const pipeline = []\r\n // Check for geometry stage\r\n if (query.$geoNear) {\r\n pipeline.push({ $geoNear: query.$geoNear })\r\n }\r\n // Find matching features only\r\n pipeline.push({ $match: Object.assign({ [prefix + element]: { $exists: true } }, match) })\r\n // Ensure they are ordered by increasing time by default and most recent forecast first\r\n pipeline.push({ $sort: Object.assign({ time: 1, runTime: -1 }, query.$sort) })\r\n // Keep track of all feature values\r\n if (singleTime) {\r\n pipeline.push({ $group: groupBy })\r\n pipeline.push({ $replaceRoot: { newRoot: '$feature' } })\r\n } else {\r\n pipeline.push({ $group: Object.assign({ [element]: { $push: '$' + prefix + element } }, groupBy) })\r\n }\r\n debug(`Aggregating ${element} element for features`)\r\n pipeline.forEach(stage => {\r\n _.forOwn(stage, (value, key) => debug('Stage', key, value))\r\n })\r\n const elementResults = await collection.aggregate(pipeline, aggregateOptions).toArray()\r\n debug(`Generated ${elementResults.length} feature(s) for ${element} element`, elementResults)\r\n // Rearrange data so that we get ordered arrays indexed by element\r\n elementResults.forEach(result => {\r\n result.time = { [element]: result.time }\r\n if (result.runTime) result.runTime = { [element]: result.runTime }\r\n if (!singleTime && !isGeometry) {\r\n // Set back the element values as properties because we aggregated in an accumulator\r\n // to avoid conflict with non-aggregated feature properties\r\n _.set(result, prefix + element, _.get(result, element))\r\n // Delete accumulator\r\n _.unset(result, element)\r\n }\r\n })\r\n // Now merge with previous element results\r\n if (!aggregatedResults) {\r\n aggregatedResults = elementResults\r\n } else {\r\n elementResults.forEach(result => {\r\n const resultKeys = _.pick(result, keys)\r\n const previousResult = aggregatedResults.find(aggregatedResult => {\r\n const aggregatedResultKeys = _.pick(aggregatedResult, keys)\r\n return _.isEqual(aggregatedResultKeys, resultKeys)\r\n })\r\n // Merge with previous matching feature if any\r\n if (previousResult) {\r\n Object.assign(previousResult.time, result.time)\r\n if (result.runTime) {\r\n if (previousResult.runTime) Object.assign(previousResult.runTime, result.runTime)\r\n else previousResult.runTime = { [element]: result.runTime }\r\n }\r\n _.set(previousResult, prefix + element, _.get(result, prefix + element))\r\n } else {\r\n aggregatedResults.push(result)\r\n }\r\n })\r\n }\r\n }))\r\n delete query.$groupBy\r\n delete query.$aggregate\r\n delete query.$geoNear\r\n // Set result to avoid service DB call\r\n hook.result = aggregatedResults\r\n }\r\n return hook\r\n}\r\n"]}
@@ -8,5 +8,8 @@ module.exports = function (app, options) {
8
8
  if (options.featureId) {
9
9
  options.Model.createIndex({ ['properties.' + options.featureId]: 1 });
10
10
  }
11
+ if (options.expireAfter || options.ttl) {
12
+ options.Model.createIndex({ time: 1 }, { expireAfterSeconds: options.expireAfter || options.ttl });
13
+ }
11
14
  };
12
15
  //# sourceMappingURL=features.model.mongodb.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../map/api/models/features.model.mongodb.js"],"names":["module","exports","app","options","db","Model","collection","createIndex","geometry","layer","featureId"],"mappings":";;AAAAA,OAAOC,OAAP,GAAiB,UAAUC,GAAV,EAAeC,OAAf,EAAwB;AACvC,QAAMC,KAAKD,QAAQC,EAAR,IAAcF,IAAIE,EAA7B;AACAD,UAAQE,KAAR,GAAgBD,GAAGE,UAAH,CAAcH,QAAQG,UAAtB,CAAhB;AACAH,UAAQE,KAAR,CAAcE,WAAd,CAA0B,EAAEC,UAAU,UAAZ,EAA1B;AACAL,UAAQE,KAAR,CAAcE,WAAd,CAA0B,EAAEE,OAAO,CAAT,EAA1B;AACA,MAAIN,QAAQO,SAAZ,EAAuB;AACrBP,YAAQE,KAAR,CAAcE,WAAd,CAA0B,EAAE,CAAC,gBAAgBJ,QAAQO,SAAzB,GAAqC,CAAvC,EAA1B;AACD;AACF,CARD","file":"features.model.mongodb.js","sourcesContent":["module.exports = function (app, options) {\r\n const db = options.db || app.db\r\n options.Model = db.collection(options.collection)\r\n options.Model.createIndex({ geometry: '2dsphere' })\r\n options.Model.createIndex({ layer: 1 })\r\n if (options.featureId) {\r\n options.Model.createIndex({ ['properties.' + options.featureId]: 1 })\r\n }\r\n}\r\n"]}
1
+ {"version":3,"sources":["../../../../map/api/models/features.model.mongodb.js"],"names":["module","exports","app","options","db","Model","collection","createIndex","geometry","layer","featureId","expireAfter","ttl","time","expireAfterSeconds"],"mappings":";;AAAAA,OAAOC,OAAP,GAAiB,UAAUC,GAAV,EAAeC,OAAf,EAAwB;AACvC,QAAMC,KAAKD,QAAQC,EAAR,IAAcF,IAAIE,EAA7B;AACAD,UAAQE,KAAR,GAAgBD,GAAGE,UAAH,CAAcH,QAAQG,UAAtB,CAAhB;AACAH,UAAQE,KAAR,CAAcE,WAAd,CAA0B,EAAEC,UAAU,UAAZ,EAA1B;AACAL,UAAQE,KAAR,CAAcE,WAAd,CAA0B,EAAEE,OAAO,CAAT,EAA1B;AACA,MAAIN,QAAQO,SAAZ,EAAuB;AACrBP,YAAQE,KAAR,CAAcE,WAAd,CAA0B,EAAE,CAAC,gBAAgBJ,QAAQO,SAAzB,GAAqC,CAAvC,EAA1B;AACD;AACD,MAAIP,QAAQQ,WAAR,IAAuBR,QAAQS,GAAnC,EAAwC;AACtCT,YAAQE,KAAR,CAAcE,WAAd,CAA0B,EAAEM,MAAM,CAAR,EAA1B,EAAuC,EAAEC,oBAAoBX,QAAQQ,WAAR,IAAuBR,QAAQS,GAArD,EAAvC;AACD;AACF,CAXD","file":"features.model.mongodb.js","sourcesContent":["module.exports = function (app, options) {\r\n const db = options.db || app.db\r\n options.Model = db.collection(options.collection)\r\n options.Model.createIndex({ geometry: '2dsphere' })\r\n options.Model.createIndex({ layer: 1 })\r\n if (options.featureId) {\r\n options.Model.createIndex({ ['properties.' + options.featureId]: 1 })\r\n }\r\n if (options.expireAfter || options.ttl) {\r\n options.Model.createIndex({ time: 1 }, { expireAfterSeconds: options.expireAfter || options.ttl })\r\n }\r\n}\r\n"]}
@@ -0,0 +1,151 @@
1
+ <template>
2
+ <div class="q-pl-sm q-pr-xs row justify-center items-center no-wrap q-gutter-x-xs">
3
+ <q-select
4
+ v-model="resolution"
5
+ :options="getResolutions()"
6
+ dense
7
+ borderless>
8
+ <template v-slot:option="scope">
9
+ <q-item v-bind="scope.itemProps" v-on="scope.itemEvents">
10
+ <q-item-section>
11
+ <q-item-label v-html="scope.opt.label" />
12
+ </q-item-section>
13
+ <q-item-section side>
14
+ <q-item-label caption>{{ scope.opt.description }}</q-item-label>
15
+ </q-item-section>
16
+ </q-item>
17
+ </template>
18
+ </q-select>
19
+ <q-input
20
+ v-model.number="width"
21
+ type="number"
22
+ min="256" max="4000"
23
+ mask="(#)###"
24
+ borderless
25
+ dense
26
+ input-class="text-center"
27
+ style="max-width: 54px" />
28
+ <span>x</span>
29
+ <q-input
30
+ v-model.number="height"
31
+ type="number"
32
+ min="256" max="4000"
33
+ mask="(#)###"
34
+ borderless
35
+ dense
36
+ input-class="text-center"
37
+ style="max-width: 54px" />
38
+ <k-action
39
+ id="capture-button"
40
+ icon="las la-camera"
41
+ tooltip="KCaptureToolbar.CAPTURE_ACTION"
42
+ :handler="() => this.capture()" />
43
+ </div>
44
+ </template>
45
+
46
+ <script>
47
+ import _ from 'lodash'
48
+ import { Events, Time } from '../../../core/client'
49
+ import { exportFile } from 'quasar'
50
+
51
+ export default {
52
+ name: 'k-capture-toolbar',
53
+ inject: ['kActivity'],
54
+ data () {
55
+ return {
56
+ width: 1280,
57
+ height: 720,
58
+ resolution: undefined
59
+ }
60
+ },
61
+ watch: {
62
+ resolution: {
63
+ immediate: true,
64
+ handler (value) {
65
+ if (!value) this.resolution = this.getResolutions()[1]
66
+ else {
67
+ const size = _.split(this.resolution.value, 'x')
68
+ this.width = size[0]
69
+ this.height = size[1]
70
+ }
71
+ }
72
+ },
73
+ width: {
74
+ handler (value) {
75
+ if (value < 256) this.width = 256
76
+ if (value > 4000) this.width = 4000
77
+ }
78
+ },
79
+ height: {
80
+ handler (value) {
81
+ if (value < 256) this.height = 256
82
+ if (value > 4000) this.height = 4000
83
+ }
84
+ }
85
+ },
86
+ methods: {
87
+ getResolutions () {
88
+ return [
89
+ { label: this.$t('KCaptureToolbar.SD_LABEL'), description: this.$t('KCaptureToolbar.SD_DESCRIPTION'), value: '640x480' },
90
+ { label: this.$t('KCaptureToolbar.HD_LABEL'), description: this.$t('KCaptureToolbar.HD_DESCRIPTION'), value: '1280x720' },
91
+ { label: this.$t('KCaptureToolbar.FHD_LABEL'), description: this.$t('KCaptureToolbar.FHD_DESCRIPTION'), value: '1920x1080' },
92
+ { label: this.$t('KCaptureToolbar.QHD_LABEL'), description: this.$t('KCaptureToolbar.QHD_DESCRIPTION'), value: '2560x1440' },
93
+ { label: this.$t('KCaptureToolbar.2K_LABEL'), description: this.$t('KCaptureToolbar.2K_DESCRIPTION'), value: '2048x1080' },
94
+ { label: this.$t('KCaptureToolbar.4K_LABEL'), description: this.$t('KCaptureToolbar.4K_DESCRIPTION'), value: '3840x2160' }
95
+ ]
96
+ },
97
+ async capture () {
98
+ // Retrieve the layers
99
+ const layers = this.kActivity.getContextParameters('layers').layers
100
+ // Retrieve the extension
101
+ const bbox = this.kActivity.getContextParameters('view')
102
+ // Setup the request url options
103
+ const endpoint = this.$store.get('capabilities.api.gateway') + '/capture'
104
+ const options = {
105
+ method: 'POST',
106
+ mode: 'cors',
107
+ body: JSON.stringify({
108
+ activity: this.kActivity.is3D() ? 'globe' : 'map',
109
+ layers,
110
+ bbox: [bbox.west, bbox.south, bbox.east, bbox.north],
111
+ size: { width: +this.width, height: +this.height },
112
+ time: Time.getCurrentTime().toISOString()
113
+ }),
114
+ headers: {
115
+ 'Content-Type': 'application/json'
116
+ }
117
+ }
118
+ // Add the Authorization header if jwt is defined
119
+ const jwt = this.$api.get('storage').getItem(this.$config('gatewayJwt'))
120
+ if (jwt) options.headers.Authorization = 'Bearer ' + jwt
121
+ // Perform the request
122
+ let dismiss = null
123
+ try {
124
+ dismiss = this.$q.notify({
125
+ group: 'capture',
126
+ icon: 'las la-hourglass-half',
127
+ message: this.$t('KCaptureToolbar.CAPTURING_VIEW'),
128
+ color: 'primary',
129
+ timeout: 0,
130
+ spinner: true
131
+ })
132
+ const response = await fetch(endpoint, options)
133
+ dismiss()
134
+ if (response.ok) {
135
+ const arrayBuffer = await response.arrayBuffer()
136
+ exportFile('capture.png', new Uint8Array(arrayBuffer))
137
+ } else {
138
+ Events.$emit('error', { message: this.$t('errors.' + response.status) })
139
+ }
140
+ } catch (error) {
141
+ // Network error
142
+ dismiss()
143
+ Events.$emit('error', { message: this.$t('errors.NETWORK_ERROR') })
144
+ }
145
+ }
146
+ },
147
+ beforeCreate () {
148
+ this.$options.components['k-action'] = this.$load('frame/KAction')
149
+ }
150
+ }
151
+ </script>
@@ -6,7 +6,7 @@
6
6
  <span class="k-unit-box bg-accent text-white text-caption"
7
7
  :style="colorUnitStyle"
8
8
  >
9
- {{unit}}
9
+ {{unitSymbol}}
10
10
  <q-tooltip anchor="top middle" self="bottom middle" :offset="[10, 20]" v-if="hint">{{hint}}</q-tooltip>
11
11
  </span>
12
12
 
@@ -28,7 +28,7 @@
28
28
 
29
29
  <script>
30
30
  import _ from 'lodash'
31
- import math from 'mathjs'
31
+ import { Units } from '../../../core/client/units'
32
32
  import { buildColorMap } from '../utils'
33
33
 
34
34
  const COLOR_STEPS = 10
@@ -47,6 +47,7 @@ export default {
47
47
  return {
48
48
  visible: false,
49
49
  unit: null,
50
+ unitSymbol: '',
50
51
  hint: null,
51
52
  colorMap: null,
52
53
  colors: null,
@@ -142,6 +143,8 @@ export default {
142
143
  return engineLayer.colorMap || buildColorMap(this.getColorMapDefinition(layer))
143
144
  },
144
145
  getColorLegendUnits (layer) {
146
+ // Can be provided at layer level or variable level,
147
+ // FIXME: in case of multiple variables we assume a similar unit
145
148
  return _.get(layer, 'units', _.get(layer, 'variables[0].units'))
146
149
  },
147
150
  async onColorLegendShowLayer (layer, engineLayer) {
@@ -172,6 +175,7 @@ export default {
172
175
  setColorLegend (visible, unit, hint, colorMap, colors, values, unitValues, showGradient) {
173
176
  this.visible = visible
174
177
  this.unit = unit
178
+ this.unitSymbol = (unit ? Units.getUnitSymbol(unit) : '')
175
179
  this.hint = hint
176
180
  this.colorMap = colorMap
177
181
  this.colors = colors
@@ -193,7 +197,15 @@ export default {
193
197
  const colorMap = this.getColorMap(this.legendLayer, this.legendEngineLayer)
194
198
  const scale = _.get(this.getColorMapDefinition(this.legendLayer), 'scale')
195
199
  const units = this.getColorLegendUnits(this.legendLayer)
196
- const unit = !units || units.length === 0 ? null : units[0]
200
+ let unit = null
201
+ // If we have multiple units available try to select the default one
202
+ if (units && units.length > 0) {
203
+ // Falback to base unit
204
+ const baseUnit = units[0]
205
+ // Get default unit for this quantity instead if available
206
+ const defaultUnit = Units.getDefaultUnit(baseUnit)
207
+ unit = (units.includes(defaultUnit) ? defaultUnit : baseUnit)
208
+ }
197
209
  const hint = this.getColorLegendHint(units, unit, this.legendLayer.name || this.legendLayer.label)
198
210
  const [showGradient, colors, values, unitValues] =
199
211
  this.getColorLegendValues(colorMap, scale, units, unit, COLOR_STEPS)
@@ -242,7 +254,7 @@ export default {
242
254
  const unitTo = unit
243
255
 
244
256
  function valueMap (value) {
245
- const unitValue = math.unit(value, unitFrom).toNumber(unitTo)
257
+ const unitValue = Units.convert(value, unitFrom, unitTo)
246
258
  return Math.round(unitValue, 0).toFixed(0)
247
259
  }
248
260
 
@@ -8,17 +8,16 @@
8
8
  :maximized="isModalMaximized"
9
9
  v-model="isModalOpened"
10
10
  @opened="$emit('opened')"
11
- @closed="$emit('closed')">
12
- <div slot="modal-content">
13
- <div class="row justify-center text-center q-ma-none q-pa-none">
14
- <div style="width: 90vw">
15
- <canvas v-show="chartData.length > 0" class="chart" ref="chart"></canvas>
16
- </div>
17
- <q-btn v-show="currentChart > 1" size="1rem" flat round color="primary"
18
- icon="las la-chevron-left" class="absolute-left" @click="onPreviousChart"/>
19
- <q-btn v-show="currentChart < nbCharts" size="1rem" flat round color="primary"
20
- icon="las la-chevron-right" class="absolute-right" @click="onNextChart" />
11
+ @closed="$emit('closed')"
12
+ >
13
+ <div class="row justify-center text-center q-ma-none q-pa-none">
14
+ <div style="width: 90vw">
15
+ <canvas v-show="chartData.length > 0" class="chart" ref="chart"></canvas>
21
16
  </div>
17
+ <q-btn v-show="currentChart > 1" size="1rem" flat round color="primary"
18
+ icon="las la-chevron-left" class="absolute-left" @click="onPreviousChart"/>
19
+ <q-btn v-show="currentChart < nbCharts" size="1rem" flat round color="primary"
20
+ icon="las la-chevron-right" class="absolute-right" @click="onNextChart" />
22
21
  </div>
23
22
  </k-modal>
24
23
  <k-modal
@@ -26,7 +25,7 @@
26
25
  ref="chartSettings"
27
26
  :title="$t('KFeaturesChart.CHART_SETTINGS_LABEL')"
28
27
  :buttons="[{ id: 'close-action', label: 'CLOSE', renderer: 'form-button', handler: () => this.$refs.chartSettings.close() }]">
29
- <div slot="modal-content">
28
+ <div>
30
29
  <q-select v-model="property" :label="$t('KFeaturesChart.PROPERTY_LABEL')"
31
30
  :options="properties" @input="refreshChart"/>
32
31
  <q-select v-model="chartType" :label="$t('KFeaturesChart.CHART_LABEL')"
@@ -6,44 +6,43 @@
6
6
  :maximized="isModalMaximized"
7
7
  v-model="isModalOpened"
8
8
  @opened="$emit('opened')"
9
- @closed="$emit('closed')">
10
- <div slot="modal-content">
11
- <q-list dense class="row items-center justify-around">
12
- <q-item v-for="filter in filters" :key="filter.key" class="col-12">
13
- <q-item-section avatar v-if="filter.operator">
14
- <q-select v-model="filter.operator" :label="filter.property" stack-label :options="getOperators(filter)" emit-value map-options/>
15
- </q-item-section>
16
- <q-item-section>
17
- <component
18
- :is="filter.componentKey"
19
- :ref="filter.key"
20
- :properties="filter.properties"
21
- :display="{ icon: false, label: false }"
22
- @field-changed="filter.onValueChanged"
23
- />
24
- </q-item-section>
25
- <q-item-section avatar>
26
- <q-btn flat color="primary" icon="las la-trash" @click="onRemoveFilter(filter)">
27
- <q-tooltip anchor="top middle" self="bottom middle" :offset="[10, 10]">
28
- {{$t('KFeaturesFilter.REMOVE_FILTER')}}
29
- </q-tooltip>
30
- </q-btn>
31
- </q-item-section>
32
- </q-item>
33
- <q-item class="col-12">
34
- <q-item-section avatar class="col-6">
35
- {{$t('KFeaturesFilter.ADD_FILTER')}}
36
- </q-item-section>
37
- <q-item-section class="col-6">
38
- <q-select v-model="property" :options="properties">
39
- <template v-slot:after>
40
- <q-btn v-if="property" round dense flat icon="las la-plus" @click="onAddFilter(property)"/>
41
- </template>
42
- </q-select>
43
- </q-item-section>
44
- </q-item>
45
- </q-list>
46
- </div>
9
+ @closed="$emit('closed')"
10
+ >
11
+ <q-list dense class="row items-center justify-around">
12
+ <q-item v-for="filter in filters" :key="filter.key" class="col-12">
13
+ <q-item-section avatar v-if="filter.operator">
14
+ <q-select v-model="filter.operator" :label="filter.property" stack-label :options="getOperators(filter)" emit-value map-options/>
15
+ </q-item-section>
16
+ <q-item-section>
17
+ <component
18
+ :is="filter.componentKey"
19
+ :ref="filter.key"
20
+ :properties="filter.properties"
21
+ :display="{ icon: false, label: false }"
22
+ @field-changed="filter.onValueChanged"
23
+ />
24
+ </q-item-section>
25
+ <q-item-section avatar>
26
+ <q-btn flat color="primary" icon="las la-trash" @click="onRemoveFilter(filter)">
27
+ <q-tooltip anchor="top middle" self="bottom middle" :offset="[10, 10]">
28
+ {{$t('KFeaturesFilter.REMOVE_FILTER')}}
29
+ </q-tooltip>
30
+ </q-btn>
31
+ </q-item-section>
32
+ </q-item>
33
+ <q-item class="col-12">
34
+ <q-item-section avatar class="col-6">
35
+ {{$t('KFeaturesFilter.ADD_FILTER')}}
36
+ </q-item-section>
37
+ <q-item-section class="col-6">
38
+ <q-select v-model="property" :options="properties">
39
+ <template v-slot:after>
40
+ <q-btn v-if="property" round dense flat icon="las la-plus" @click="onAddFilter(property)"/>
41
+ </template>
42
+ </q-select>
43
+ </q-item-section>
44
+ </q-item>
45
+ </q-list>
47
46
  </k-modal>
48
47
  </template>
49
48
 
@@ -115,8 +114,10 @@ export default {
115
114
  properties.field.multiple = true
116
115
  properties.field.chips = true
117
116
  // Get available values
118
- const values = await this.$api.getService(this.layer.service, this.contextId)
117
+ let values = await this.$api.getService(this.layer.service, this.contextId)
119
118
  .find({ query: Object.assign({ $distinct: `properties.${property}` }, _.omit(this.layer.baseQuery, this.getCurrentLayerFilters())) })
119
+ // Sort them to ease searching
120
+ values = values.sort()
120
121
  // We don't have label in that case
121
122
  properties.field.options = values.map(value => ({ value, label: (_.isNil(value) ? 'NIL' : value) }))
122
123
  }