@kalisio/kdk 2.5.2 → 2.5.3

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 (275) hide show
  1. package/core/client/components/input/KShapePicker.vue +4 -4
  2. package/coverage/core/api/application.js.html +344 -344
  3. package/coverage/core/api/authentication.js.html +79 -79
  4. package/coverage/core/api/db.js.html +167 -167
  5. package/coverage/core/api/hooks/hooks.authentication.js.html +12 -12
  6. package/coverage/core/api/hooks/hooks.authorisations.js.html +166 -163
  7. package/coverage/core/api/hooks/hooks.groups.js.html +1 -1
  8. package/coverage/core/api/hooks/hooks.logger.js.html +18 -18
  9. package/coverage/core/api/hooks/hooks.model.js.html +280 -268
  10. package/coverage/core/api/hooks/hooks.organisations.js.html +1 -1
  11. package/coverage/core/api/hooks/hooks.push.js.html +12 -12
  12. package/coverage/core/api/hooks/hooks.query.js.html +92 -92
  13. package/coverage/core/api/hooks/hooks.schemas.js.html +13 -13
  14. package/coverage/core/api/hooks/hooks.service.js.html +28 -28
  15. package/coverage/core/api/hooks/hooks.storage.js.html +7 -7
  16. package/coverage/core/api/hooks/hooks.users.js.html +48 -48
  17. package/coverage/core/api/hooks/index.html +49 -49
  18. package/coverage/core/api/hooks/index.js.html +11 -11
  19. package/coverage/core/api/index.html +42 -42
  20. package/coverage/core/api/index.js.html +22 -22
  21. package/coverage/core/api/marshall.js.html +127 -127
  22. package/coverage/core/api/models/groups.model.mongodb.js.html +1 -1
  23. package/coverage/core/api/models/index.html +1 -1
  24. package/coverage/core/api/models/messages.model.mongodb.js.html +1 -1
  25. package/coverage/core/api/models/organisations.model.mongodb.js.html +1 -1
  26. package/coverage/core/api/models/tags.model.mongodb.js.html +1 -1
  27. package/coverage/core/api/models/users.model.mongodb.js.html +11 -11
  28. package/coverage/core/api/services/account/account.hooks.js.html +42 -42
  29. package/coverage/core/api/services/account/account.service.js.html +34 -34
  30. package/coverage/core/api/services/account/index.html +1 -1
  31. package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +34 -34
  32. package/coverage/core/api/services/authorisations/authorisations.service.js.html +108 -120
  33. package/coverage/core/api/services/authorisations/index.html +19 -19
  34. package/coverage/core/api/services/databases/databases.hooks.js.html +1 -1
  35. package/coverage/core/api/services/databases/databases.service.js.html +1 -1
  36. package/coverage/core/api/services/databases/index.html +1 -1
  37. package/coverage/core/api/services/groups/groups.hooks.js.html +1 -1
  38. package/coverage/core/api/services/groups/index.html +1 -1
  39. package/coverage/core/api/services/import-export/import-export.hooks.js.html +1 -1
  40. package/coverage/core/api/services/import-export/import-export.service.js.html +1 -1
  41. package/coverage/core/api/services/import-export/index.html +1 -1
  42. package/coverage/core/api/services/index.html +15 -15
  43. package/coverage/core/api/services/index.js.html +97 -85
  44. package/coverage/core/api/services/mailer/index.html +1 -1
  45. package/coverage/core/api/services/mailer/mailer.hooks.js.html +1 -1
  46. package/coverage/core/api/services/mailer/mailer.service.js.html +1 -1
  47. package/coverage/core/api/services/messages/index.html +5 -5
  48. package/coverage/core/api/services/messages/messages.hooks.js.html +11 -8
  49. package/coverage/core/api/services/organisations/index.html +1 -1
  50. package/coverage/core/api/services/organisations/organisations.hooks.js.html +1 -1
  51. package/coverage/core/api/services/organisations/organisations.service.js.html +1 -1
  52. package/coverage/core/api/services/push/index.html +1 -1
  53. package/coverage/core/api/services/push/push.hooks.js.html +1 -1
  54. package/coverage/core/api/services/push/push.service.js.html +1 -1
  55. package/coverage/core/api/services/storage/index.html +1 -1
  56. package/coverage/core/api/services/storage/storage.hooks.js.html +36 -36
  57. package/coverage/core/api/services/storage/storage.service.js.html +30 -30
  58. package/coverage/core/api/services/tags/index.html +1 -1
  59. package/coverage/core/api/services/tags/tags.hooks.js.html +1 -1
  60. package/coverage/core/api/services/users/index.html +7 -7
  61. package/coverage/core/api/services/users/users.hooks.js.html +83 -80
  62. package/coverage/core/api/services/users/users.service.js.html +4 -4
  63. package/coverage/core/api/utils.js.html +1 -1
  64. package/coverage/core/common/errors.js.html +2 -2
  65. package/coverage/core/common/index.html +30 -30
  66. package/coverage/core/common/index.js.html +11 -11
  67. package/coverage/core/common/permissions.js.html +187 -187
  68. package/coverage/core/common/schema.js.html +26 -26
  69. package/coverage/core/common/utils.js.html +61 -61
  70. package/coverage/core/common/utils.offline.js.html +6 -6
  71. package/coverage/index.html +179 -164
  72. package/coverage/lcov-report/core/api/application.js.html +344 -344
  73. package/coverage/lcov-report/core/api/authentication.js.html +79 -79
  74. package/coverage/lcov-report/core/api/db.js.html +167 -167
  75. package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +12 -12
  76. package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +166 -163
  77. package/coverage/lcov-report/core/api/hooks/hooks.groups.js.html +1 -1
  78. package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +18 -18
  79. package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +280 -268
  80. package/coverage/lcov-report/core/api/hooks/hooks.organisations.js.html +1 -1
  81. package/coverage/lcov-report/core/api/hooks/hooks.push.js.html +12 -12
  82. package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +92 -92
  83. package/coverage/lcov-report/core/api/hooks/hooks.schemas.js.html +13 -13
  84. package/coverage/lcov-report/core/api/hooks/hooks.service.js.html +28 -28
  85. package/coverage/lcov-report/core/api/hooks/hooks.storage.js.html +7 -7
  86. package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +48 -48
  87. package/coverage/lcov-report/core/api/hooks/index.html +49 -49
  88. package/coverage/lcov-report/core/api/hooks/index.js.html +11 -11
  89. package/coverage/lcov-report/core/api/index.html +42 -42
  90. package/coverage/lcov-report/core/api/index.js.html +22 -22
  91. package/coverage/lcov-report/core/api/marshall.js.html +127 -127
  92. package/coverage/lcov-report/core/api/models/groups.model.mongodb.js.html +1 -1
  93. package/coverage/lcov-report/core/api/models/index.html +1 -1
  94. package/coverage/lcov-report/core/api/models/messages.model.mongodb.js.html +1 -1
  95. package/coverage/lcov-report/core/api/models/organisations.model.mongodb.js.html +1 -1
  96. package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +1 -1
  97. package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +11 -11
  98. package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +42 -42
  99. package/coverage/lcov-report/core/api/services/account/account.service.js.html +34 -34
  100. package/coverage/lcov-report/core/api/services/account/index.html +1 -1
  101. package/coverage/lcov-report/core/api/services/authorisations/authorisations.hooks.js.html +34 -34
  102. package/coverage/lcov-report/core/api/services/authorisations/authorisations.service.js.html +108 -120
  103. package/coverage/lcov-report/core/api/services/authorisations/index.html +19 -19
  104. package/coverage/lcov-report/core/api/services/databases/databases.hooks.js.html +1 -1
  105. package/coverage/lcov-report/core/api/services/databases/databases.service.js.html +1 -1
  106. package/coverage/lcov-report/core/api/services/databases/index.html +1 -1
  107. package/coverage/lcov-report/core/api/services/groups/groups.hooks.js.html +1 -1
  108. package/coverage/lcov-report/core/api/services/groups/index.html +1 -1
  109. package/coverage/lcov-report/core/api/services/import-export/import-export.hooks.js.html +1 -1
  110. package/coverage/lcov-report/core/api/services/import-export/import-export.service.js.html +1 -1
  111. package/coverage/lcov-report/core/api/services/import-export/index.html +1 -1
  112. package/coverage/lcov-report/core/api/services/index.html +15 -15
  113. package/coverage/lcov-report/core/api/services/index.js.html +97 -85
  114. package/coverage/lcov-report/core/api/services/mailer/index.html +1 -1
  115. package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +1 -1
  116. package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +1 -1
  117. package/coverage/lcov-report/core/api/services/messages/index.html +5 -5
  118. package/coverage/lcov-report/core/api/services/messages/messages.hooks.js.html +11 -8
  119. package/coverage/lcov-report/core/api/services/organisations/index.html +1 -1
  120. package/coverage/lcov-report/core/api/services/organisations/organisations.hooks.js.html +1 -1
  121. package/coverage/lcov-report/core/api/services/organisations/organisations.service.js.html +1 -1
  122. package/coverage/lcov-report/core/api/services/push/index.html +1 -1
  123. package/coverage/lcov-report/core/api/services/push/push.hooks.js.html +1 -1
  124. package/coverage/lcov-report/core/api/services/push/push.service.js.html +1 -1
  125. package/coverage/lcov-report/core/api/services/storage/index.html +1 -1
  126. package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +36 -36
  127. package/coverage/lcov-report/core/api/services/storage/storage.service.js.html +30 -30
  128. package/coverage/lcov-report/core/api/services/tags/index.html +1 -1
  129. package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +1 -1
  130. package/coverage/lcov-report/core/api/services/users/index.html +7 -7
  131. package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +83 -80
  132. package/coverage/lcov-report/core/api/services/users/users.service.js.html +4 -4
  133. package/coverage/lcov-report/core/api/utils.js.html +1 -1
  134. package/coverage/lcov-report/core/common/errors.js.html +2 -2
  135. package/coverage/lcov-report/core/common/index.html +30 -30
  136. package/coverage/lcov-report/core/common/index.js.html +11 -11
  137. package/coverage/lcov-report/core/common/permissions.js.html +187 -187
  138. package/coverage/lcov-report/core/common/schema.js.html +26 -26
  139. package/coverage/lcov-report/core/common/utils.js.html +61 -61
  140. package/coverage/lcov-report/core/common/utils.offline.js.html +6 -6
  141. package/coverage/lcov-report/index.html +179 -164
  142. package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +348 -258
  143. package/coverage/lcov-report/map/api/hooks/hooks.features.js.html +218 -218
  144. package/coverage/lcov-report/map/api/hooks/hooks.query.js.html +795 -810
  145. package/coverage/lcov-report/map/api/hooks/index.html +54 -54
  146. package/coverage/lcov-report/map/api/hooks/index.js.html +16 -16
  147. package/coverage/lcov-report/map/api/index.html +32 -32
  148. package/coverage/lcov-report/map/api/index.js.html +46 -46
  149. package/coverage/lcov-report/map/api/marshall.js.html +72 -72
  150. package/coverage/lcov-report/map/api/models/alerts.model.mongodb.js.html +24 -24
  151. package/coverage/lcov-report/map/api/models/catalog.model.mongodb.js.html +69 -27
  152. package/coverage/lcov-report/map/api/models/features.model.mongodb.js.html +80 -80
  153. package/coverage/lcov-report/map/api/models/index.html +69 -54
  154. package/coverage/lcov-report/map/api/models/projects.model.mongodb.js.html +26 -26
  155. package/coverage/lcov-report/map/api/models/styles.model.mongodb.js.html +112 -0
  156. package/coverage/lcov-report/map/api/services/alerts/alerts.hooks.js.html +136 -136
  157. package/coverage/lcov-report/map/api/services/alerts/alerts.service.js.html +343 -343
  158. package/coverage/lcov-report/map/api/services/alerts/index.html +32 -32
  159. package/coverage/lcov-report/map/api/services/catalog/catalog.hooks.js.html +177 -162
  160. package/coverage/lcov-report/map/api/services/catalog/index.html +21 -21
  161. package/coverage/lcov-report/map/api/services/daptiles/daptiles.service.js.html +1 -1
  162. package/coverage/lcov-report/map/api/services/daptiles/index.html +1 -1
  163. package/coverage/lcov-report/map/api/services/features/features.hooks.js.html +160 -160
  164. package/coverage/lcov-report/map/api/services/features/features.service.js.html +117 -117
  165. package/coverage/lcov-report/map/api/services/features/index.html +31 -31
  166. package/coverage/lcov-report/map/api/services/index.html +21 -21
  167. package/coverage/lcov-report/map/api/services/index.js.html +404 -296
  168. package/coverage/lcov-report/map/api/services/projects/index.html +21 -21
  169. package/coverage/lcov-report/map/api/services/projects/projects.hooks.js.html +237 -237
  170. package/coverage/lcov-report/map/api/services/styles/index.html +116 -0
  171. package/coverage/lcov-report/map/api/services/styles/styles.hooks.js.html +196 -0
  172. package/coverage/lcov-report/map/common/dynamic-grid-source.js.html +68 -68
  173. package/coverage/lcov-report/map/common/errors.js.html +16 -16
  174. package/coverage/lcov-report/map/common/geotiff-grid-source.js.html +267 -267
  175. package/coverage/lcov-report/map/common/grid.js.html +554 -554
  176. package/coverage/lcov-report/map/common/index.html +158 -158
  177. package/coverage/lcov-report/map/common/index.js.html +68 -68
  178. package/coverage/lcov-report/map/common/meteo-model-grid-source.js.html +73 -73
  179. package/coverage/lcov-report/map/common/moment-utils.js.html +18 -18
  180. package/coverage/lcov-report/map/common/opendap-grid-source.js.html +484 -484
  181. package/coverage/lcov-report/map/common/opendap-utils.js.html +353 -353
  182. package/coverage/lcov-report/map/common/permissions.js.html +42 -36
  183. package/coverage/lcov-report/map/common/time-based-grid-source.js.html +59 -59
  184. package/coverage/lcov-report/map/common/tms-utils.js.html +6 -6
  185. package/coverage/lcov-report/map/common/wcs-grid-source.js.html +190 -190
  186. package/coverage/lcov-report/map/common/wcs-utils.js.html +339 -339
  187. package/coverage/lcov-report/map/common/weacast-grid-source.js.html +345 -345
  188. package/coverage/lcov-report/map/common/wfs-utils.js.html +11 -11
  189. package/coverage/lcov-report/map/common/wms-utils.js.html +8 -8
  190. package/coverage/lcov-report/map/common/wmts-utils.js.html +7 -7
  191. package/coverage/lcov.info +7022 -5894
  192. package/coverage/map/api/hooks/hooks.catalog.js.html +348 -258
  193. package/coverage/map/api/hooks/hooks.features.js.html +218 -218
  194. package/coverage/map/api/hooks/hooks.query.js.html +795 -810
  195. package/coverage/map/api/hooks/index.html +54 -54
  196. package/coverage/map/api/hooks/index.js.html +16 -16
  197. package/coverage/map/api/index.html +32 -32
  198. package/coverage/map/api/index.js.html +46 -46
  199. package/coverage/map/api/marshall.js.html +72 -72
  200. package/coverage/map/api/models/alerts.model.mongodb.js.html +24 -24
  201. package/coverage/map/api/models/catalog.model.mongodb.js.html +69 -27
  202. package/coverage/map/api/models/features.model.mongodb.js.html +80 -80
  203. package/coverage/map/api/models/index.html +69 -54
  204. package/coverage/map/api/models/projects.model.mongodb.js.html +26 -26
  205. package/coverage/map/api/models/styles.model.mongodb.js.html +112 -0
  206. package/coverage/map/api/services/alerts/alerts.hooks.js.html +136 -136
  207. package/coverage/map/api/services/alerts/alerts.service.js.html +343 -343
  208. package/coverage/map/api/services/alerts/index.html +32 -32
  209. package/coverage/map/api/services/catalog/catalog.hooks.js.html +177 -162
  210. package/coverage/map/api/services/catalog/index.html +21 -21
  211. package/coverage/map/api/services/daptiles/daptiles.service.js.html +1 -1
  212. package/coverage/map/api/services/daptiles/index.html +1 -1
  213. package/coverage/map/api/services/features/features.hooks.js.html +160 -160
  214. package/coverage/map/api/services/features/features.service.js.html +117 -117
  215. package/coverage/map/api/services/features/index.html +31 -31
  216. package/coverage/map/api/services/index.html +21 -21
  217. package/coverage/map/api/services/index.js.html +404 -296
  218. package/coverage/map/api/services/projects/index.html +21 -21
  219. package/coverage/map/api/services/projects/projects.hooks.js.html +237 -237
  220. package/coverage/map/api/services/styles/index.html +116 -0
  221. package/coverage/map/api/services/styles/styles.hooks.js.html +196 -0
  222. package/coverage/map/common/dynamic-grid-source.js.html +68 -68
  223. package/coverage/map/common/errors.js.html +16 -16
  224. package/coverage/map/common/geotiff-grid-source.js.html +267 -267
  225. package/coverage/map/common/grid.js.html +554 -554
  226. package/coverage/map/common/index.html +158 -158
  227. package/coverage/map/common/index.js.html +68 -68
  228. package/coverage/map/common/meteo-model-grid-source.js.html +73 -73
  229. package/coverage/map/common/moment-utils.js.html +18 -18
  230. package/coverage/map/common/opendap-grid-source.js.html +484 -484
  231. package/coverage/map/common/opendap-utils.js.html +353 -353
  232. package/coverage/map/common/permissions.js.html +42 -36
  233. package/coverage/map/common/time-based-grid-source.js.html +59 -59
  234. package/coverage/map/common/tms-utils.js.html +6 -6
  235. package/coverage/map/common/wcs-grid-source.js.html +190 -190
  236. package/coverage/map/common/wcs-utils.js.html +339 -339
  237. package/coverage/map/common/weacast-grid-source.js.html +345 -345
  238. package/coverage/map/common/wfs-utils.js.html +11 -11
  239. package/coverage/map/common/wms-utils.js.html +8 -8
  240. package/coverage/map/common/wmts-utils.js.html +7 -7
  241. package/coverage/tmp/coverage-151198-1753351220086-0.json +1 -0
  242. package/coverage/tmp/coverage-151210-1753351220070-0.json +1 -0
  243. package/coverage/tmp/coverage-151221-1753351129816-0.json +1 -0
  244. package/coverage/tmp/coverage-151233-1753351129803-0.json +1 -0
  245. package/coverage/tmp/coverage-151240-1753351129770-0.json +1 -0
  246. package/coverage/tmp/coverage-151307-1753351220058-0.json +1 -0
  247. package/coverage/tmp/coverage-151319-1753351220044-0.json +1 -0
  248. package/coverage/tmp/coverage-151326-1753351220010-0.json +1 -0
  249. package/map/api/services/styles/styles.hooks.js +1 -1
  250. package/map/client/components/KLayerEditor.vue +4 -0
  251. package/map/client/components/catalog/KLayerCategories.vue +2 -0
  252. package/map/client/components/stickies/KLevelSlider.vue +10 -8
  253. package/map/client/components/styles/KStyleEditor.vue +1 -1
  254. package/map/client/components/styles/KStyleManager.vue +7 -1
  255. package/map/client/composables/highlight.js +5 -1
  256. package/map/client/i18n/map_en.json +4 -1
  257. package/map/client/i18n/map_fr.json +4 -1
  258. package/map/client/mixins/globe/mixin.geojson-layers.js +11 -5
  259. package/map/client/mixins/mixin.activity.js +9 -0
  260. package/map/client/utils/utils.layers.js +0 -2
  261. package/package.json +1 -1
  262. package/test/api/core/push.test.js +1 -1
  263. package/test/api/core/test-log-2025-02-05.log +23 -0
  264. package/test/api/core/test-log-2025-05-21.log +15 -0
  265. package/test/api/core/test-log-2025-06-25.log +9 -0
  266. package/test/api/core/test-log-2025-07-24.log +44 -0
  267. package/test/api/map/test-log-2025-05-27.log +13 -0
  268. package/test/api/map/test-log-2025-06-23.log +7 -0
  269. package/test/api/map/{test-log-2025-05-26.log → test-log-2025-07-24.log} +3 -4
  270. package/coverage/tmp/coverage-122123-1739872365211-0.json +0 -1
  271. package/coverage/tmp/coverage-122135-1739872365196-0.json +0 -1
  272. package/coverage/tmp/coverage-122146-1739872365184-0.json +0 -1
  273. package/coverage/tmp/coverage-122158-1739872365169-0.json +0 -1
  274. package/coverage/tmp/coverage-122165-1739872365141-0.json +0 -1
  275. package/test/api/core/test-log-2025-05-26.log +0 -22
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">0% </span>
26
+ <span class="strong">81.22% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>0/261</span>
28
+ <span class='fraction'>212/261</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">0% </span>
33
+ <span class="strong">33.33% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>0/1</span>
35
+ <span class='fraction'>9/27</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
- <span class="strong">0% </span>
40
+ <span class="strong">88.88% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>0/1</span>
42
+ <span class='fraction'>8/9</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">0% </span>
47
+ <span class="strong">81.22% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>0/261</span>
49
+ <span class='fraction'>212/261</span>
50
50
  </div>
51
51
 
52
52
 
@@ -61,7 +61,7 @@
61
61
  </div>
62
62
  </template>
63
63
  </div>
64
- <div class='status-line low'></div>
64
+ <div class='status-line high'></div>
65
65
  <pre><table class="coverage">
66
66
  <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
67
  <a name='L2'></a><a href='#L2'>2</a>
@@ -324,503 +324,503 @@
324
324
  <a name='L259'></a><a href='#L259'>259</a>
325
325
  <a name='L260'></a><a href='#L260'>260</a>
326
326
  <a name='L261'></a><a href='#L261'>261</a>
327
- <a name='L262'></a><a href='#L262'>262</a></td><td class="line-coverage quiet"><span class="cline-any cline-no">&nbsp;</span>
328
- <span class="cline-any cline-no">&nbsp;</span>
329
- <span class="cline-any cline-no">&nbsp;</span>
330
- <span class="cline-any cline-no">&nbsp;</span>
331
- <span class="cline-any cline-no">&nbsp;</span>
332
- <span class="cline-any cline-no">&nbsp;</span>
333
- <span class="cline-any cline-no">&nbsp;</span>
334
- <span class="cline-any cline-no">&nbsp;</span>
335
- <span class="cline-any cline-no">&nbsp;</span>
336
- <span class="cline-any cline-no">&nbsp;</span>
337
- <span class="cline-any cline-no">&nbsp;</span>
338
- <span class="cline-any cline-no">&nbsp;</span>
339
- <span class="cline-any cline-no">&nbsp;</span>
340
- <span class="cline-any cline-no">&nbsp;</span>
341
- <span class="cline-any cline-no">&nbsp;</span>
342
- <span class="cline-any cline-no">&nbsp;</span>
343
- <span class="cline-any cline-no">&nbsp;</span>
344
- <span class="cline-any cline-no">&nbsp;</span>
345
- <span class="cline-any cline-no">&nbsp;</span>
346
- <span class="cline-any cline-no">&nbsp;</span>
347
- <span class="cline-any cline-no">&nbsp;</span>
348
- <span class="cline-any cline-no">&nbsp;</span>
349
- <span class="cline-any cline-no">&nbsp;</span>
350
- <span class="cline-any cline-no">&nbsp;</span>
351
- <span class="cline-any cline-no">&nbsp;</span>
352
- <span class="cline-any cline-no">&nbsp;</span>
353
- <span class="cline-any cline-no">&nbsp;</span>
354
- <span class="cline-any cline-no">&nbsp;</span>
355
- <span class="cline-any cline-no">&nbsp;</span>
356
- <span class="cline-any cline-no">&nbsp;</span>
357
- <span class="cline-any cline-no">&nbsp;</span>
358
- <span class="cline-any cline-no">&nbsp;</span>
359
- <span class="cline-any cline-no">&nbsp;</span>
360
- <span class="cline-any cline-no">&nbsp;</span>
361
- <span class="cline-any cline-no">&nbsp;</span>
362
- <span class="cline-any cline-no">&nbsp;</span>
363
- <span class="cline-any cline-no">&nbsp;</span>
364
- <span class="cline-any cline-no">&nbsp;</span>
365
- <span class="cline-any cline-no">&nbsp;</span>
366
- <span class="cline-any cline-no">&nbsp;</span>
367
- <span class="cline-any cline-no">&nbsp;</span>
368
- <span class="cline-any cline-no">&nbsp;</span>
369
- <span class="cline-any cline-no">&nbsp;</span>
370
- <span class="cline-any cline-no">&nbsp;</span>
371
- <span class="cline-any cline-no">&nbsp;</span>
372
- <span class="cline-any cline-no">&nbsp;</span>
373
- <span class="cline-any cline-no">&nbsp;</span>
374
- <span class="cline-any cline-no">&nbsp;</span>
375
- <span class="cline-any cline-no">&nbsp;</span>
376
- <span class="cline-any cline-no">&nbsp;</span>
377
- <span class="cline-any cline-no">&nbsp;</span>
378
- <span class="cline-any cline-no">&nbsp;</span>
379
- <span class="cline-any cline-no">&nbsp;</span>
380
- <span class="cline-any cline-no">&nbsp;</span>
381
- <span class="cline-any cline-no">&nbsp;</span>
382
- <span class="cline-any cline-no">&nbsp;</span>
383
- <span class="cline-any cline-no">&nbsp;</span>
384
- <span class="cline-any cline-no">&nbsp;</span>
385
- <span class="cline-any cline-no">&nbsp;</span>
386
- <span class="cline-any cline-no">&nbsp;</span>
387
- <span class="cline-any cline-no">&nbsp;</span>
388
- <span class="cline-any cline-no">&nbsp;</span>
389
- <span class="cline-any cline-no">&nbsp;</span>
390
- <span class="cline-any cline-no">&nbsp;</span>
391
- <span class="cline-any cline-no">&nbsp;</span>
392
- <span class="cline-any cline-no">&nbsp;</span>
393
- <span class="cline-any cline-no">&nbsp;</span>
394
- <span class="cline-any cline-no">&nbsp;</span>
395
- <span class="cline-any cline-no">&nbsp;</span>
396
- <span class="cline-any cline-no">&nbsp;</span>
397
- <span class="cline-any cline-no">&nbsp;</span>
398
- <span class="cline-any cline-no">&nbsp;</span>
399
- <span class="cline-any cline-no">&nbsp;</span>
400
- <span class="cline-any cline-no">&nbsp;</span>
401
- <span class="cline-any cline-no">&nbsp;</span>
402
- <span class="cline-any cline-no">&nbsp;</span>
403
- <span class="cline-any cline-no">&nbsp;</span>
404
- <span class="cline-any cline-no">&nbsp;</span>
405
- <span class="cline-any cline-no">&nbsp;</span>
406
- <span class="cline-any cline-no">&nbsp;</span>
407
- <span class="cline-any cline-no">&nbsp;</span>
408
- <span class="cline-any cline-no">&nbsp;</span>
409
- <span class="cline-any cline-no">&nbsp;</span>
410
- <span class="cline-any cline-no">&nbsp;</span>
411
- <span class="cline-any cline-no">&nbsp;</span>
412
- <span class="cline-any cline-no">&nbsp;</span>
413
- <span class="cline-any cline-no">&nbsp;</span>
414
- <span class="cline-any cline-no">&nbsp;</span>
415
- <span class="cline-any cline-no">&nbsp;</span>
416
- <span class="cline-any cline-no">&nbsp;</span>
417
- <span class="cline-any cline-no">&nbsp;</span>
418
- <span class="cline-any cline-no">&nbsp;</span>
419
- <span class="cline-any cline-no">&nbsp;</span>
420
- <span class="cline-any cline-no">&nbsp;</span>
421
- <span class="cline-any cline-no">&nbsp;</span>
422
- <span class="cline-any cline-no">&nbsp;</span>
423
- <span class="cline-any cline-no">&nbsp;</span>
424
- <span class="cline-any cline-no">&nbsp;</span>
425
- <span class="cline-any cline-no">&nbsp;</span>
426
- <span class="cline-any cline-no">&nbsp;</span>
427
- <span class="cline-any cline-no">&nbsp;</span>
428
- <span class="cline-any cline-no">&nbsp;</span>
429
- <span class="cline-any cline-no">&nbsp;</span>
430
- <span class="cline-any cline-no">&nbsp;</span>
431
- <span class="cline-any cline-no">&nbsp;</span>
432
- <span class="cline-any cline-no">&nbsp;</span>
433
- <span class="cline-any cline-no">&nbsp;</span>
434
- <span class="cline-any cline-no">&nbsp;</span>
435
- <span class="cline-any cline-no">&nbsp;</span>
436
- <span class="cline-any cline-no">&nbsp;</span>
437
- <span class="cline-any cline-no">&nbsp;</span>
438
- <span class="cline-any cline-no">&nbsp;</span>
439
- <span class="cline-any cline-no">&nbsp;</span>
440
- <span class="cline-any cline-no">&nbsp;</span>
441
- <span class="cline-any cline-no">&nbsp;</span>
442
- <span class="cline-any cline-no">&nbsp;</span>
443
- <span class="cline-any cline-no">&nbsp;</span>
444
- <span class="cline-any cline-no">&nbsp;</span>
445
- <span class="cline-any cline-no">&nbsp;</span>
446
- <span class="cline-any cline-no">&nbsp;</span>
447
- <span class="cline-any cline-no">&nbsp;</span>
448
- <span class="cline-any cline-no">&nbsp;</span>
449
- <span class="cline-any cline-no">&nbsp;</span>
450
- <span class="cline-any cline-no">&nbsp;</span>
451
- <span class="cline-any cline-no">&nbsp;</span>
452
- <span class="cline-any cline-no">&nbsp;</span>
453
- <span class="cline-any cline-no">&nbsp;</span>
454
- <span class="cline-any cline-no">&nbsp;</span>
455
- <span class="cline-any cline-no">&nbsp;</span>
456
- <span class="cline-any cline-no">&nbsp;</span>
457
- <span class="cline-any cline-no">&nbsp;</span>
458
- <span class="cline-any cline-no">&nbsp;</span>
459
- <span class="cline-any cline-no">&nbsp;</span>
460
- <span class="cline-any cline-no">&nbsp;</span>
461
- <span class="cline-any cline-no">&nbsp;</span>
462
- <span class="cline-any cline-no">&nbsp;</span>
463
- <span class="cline-any cline-no">&nbsp;</span>
464
- <span class="cline-any cline-no">&nbsp;</span>
465
- <span class="cline-any cline-no">&nbsp;</span>
466
- <span class="cline-any cline-no">&nbsp;</span>
467
- <span class="cline-any cline-no">&nbsp;</span>
468
- <span class="cline-any cline-no">&nbsp;</span>
469
- <span class="cline-any cline-no">&nbsp;</span>
470
- <span class="cline-any cline-no">&nbsp;</span>
471
- <span class="cline-any cline-no">&nbsp;</span>
472
- <span class="cline-any cline-no">&nbsp;</span>
473
- <span class="cline-any cline-no">&nbsp;</span>
474
- <span class="cline-any cline-no">&nbsp;</span>
475
- <span class="cline-any cline-no">&nbsp;</span>
476
- <span class="cline-any cline-no">&nbsp;</span>
477
- <span class="cline-any cline-no">&nbsp;</span>
478
- <span class="cline-any cline-no">&nbsp;</span>
479
- <span class="cline-any cline-no">&nbsp;</span>
480
- <span class="cline-any cline-no">&nbsp;</span>
481
- <span class="cline-any cline-no">&nbsp;</span>
482
- <span class="cline-any cline-no">&nbsp;</span>
483
- <span class="cline-any cline-no">&nbsp;</span>
484
- <span class="cline-any cline-no">&nbsp;</span>
485
- <span class="cline-any cline-no">&nbsp;</span>
486
- <span class="cline-any cline-no">&nbsp;</span>
487
- <span class="cline-any cline-no">&nbsp;</span>
488
- <span class="cline-any cline-no">&nbsp;</span>
489
- <span class="cline-any cline-no">&nbsp;</span>
490
- <span class="cline-any cline-no">&nbsp;</span>
491
- <span class="cline-any cline-no">&nbsp;</span>
492
- <span class="cline-any cline-no">&nbsp;</span>
493
- <span class="cline-any cline-no">&nbsp;</span>
494
- <span class="cline-any cline-no">&nbsp;</span>
495
- <span class="cline-any cline-no">&nbsp;</span>
496
- <span class="cline-any cline-no">&nbsp;</span>
497
- <span class="cline-any cline-no">&nbsp;</span>
498
- <span class="cline-any cline-no">&nbsp;</span>
499
- <span class="cline-any cline-no">&nbsp;</span>
500
- <span class="cline-any cline-no">&nbsp;</span>
501
- <span class="cline-any cline-no">&nbsp;</span>
502
- <span class="cline-any cline-no">&nbsp;</span>
503
- <span class="cline-any cline-no">&nbsp;</span>
504
- <span class="cline-any cline-no">&nbsp;</span>
505
- <span class="cline-any cline-no">&nbsp;</span>
506
- <span class="cline-any cline-no">&nbsp;</span>
507
- <span class="cline-any cline-no">&nbsp;</span>
508
- <span class="cline-any cline-no">&nbsp;</span>
509
- <span class="cline-any cline-no">&nbsp;</span>
510
- <span class="cline-any cline-no">&nbsp;</span>
511
- <span class="cline-any cline-no">&nbsp;</span>
512
- <span class="cline-any cline-no">&nbsp;</span>
513
- <span class="cline-any cline-no">&nbsp;</span>
514
- <span class="cline-any cline-no">&nbsp;</span>
515
- <span class="cline-any cline-no">&nbsp;</span>
516
- <span class="cline-any cline-no">&nbsp;</span>
517
- <span class="cline-any cline-no">&nbsp;</span>
518
- <span class="cline-any cline-no">&nbsp;</span>
519
- <span class="cline-any cline-no">&nbsp;</span>
520
- <span class="cline-any cline-no">&nbsp;</span>
521
- <span class="cline-any cline-no">&nbsp;</span>
522
- <span class="cline-any cline-no">&nbsp;</span>
523
- <span class="cline-any cline-no">&nbsp;</span>
524
- <span class="cline-any cline-no">&nbsp;</span>
525
- <span class="cline-any cline-no">&nbsp;</span>
526
- <span class="cline-any cline-no">&nbsp;</span>
527
- <span class="cline-any cline-no">&nbsp;</span>
528
- <span class="cline-any cline-no">&nbsp;</span>
529
- <span class="cline-any cline-no">&nbsp;</span>
530
- <span class="cline-any cline-no">&nbsp;</span>
531
- <span class="cline-any cline-no">&nbsp;</span>
532
- <span class="cline-any cline-no">&nbsp;</span>
533
- <span class="cline-any cline-no">&nbsp;</span>
534
- <span class="cline-any cline-no">&nbsp;</span>
535
- <span class="cline-any cline-no">&nbsp;</span>
536
- <span class="cline-any cline-no">&nbsp;</span>
537
- <span class="cline-any cline-no">&nbsp;</span>
538
- <span class="cline-any cline-no">&nbsp;</span>
539
- <span class="cline-any cline-no">&nbsp;</span>
540
- <span class="cline-any cline-no">&nbsp;</span>
541
- <span class="cline-any cline-no">&nbsp;</span>
542
- <span class="cline-any cline-no">&nbsp;</span>
543
- <span class="cline-any cline-no">&nbsp;</span>
544
- <span class="cline-any cline-no">&nbsp;</span>
545
- <span class="cline-any cline-no">&nbsp;</span>
546
- <span class="cline-any cline-no">&nbsp;</span>
547
- <span class="cline-any cline-no">&nbsp;</span>
548
- <span class="cline-any cline-no">&nbsp;</span>
549
- <span class="cline-any cline-no">&nbsp;</span>
550
- <span class="cline-any cline-no">&nbsp;</span>
551
- <span class="cline-any cline-no">&nbsp;</span>
552
- <span class="cline-any cline-no">&nbsp;</span>
553
- <span class="cline-any cline-no">&nbsp;</span>
554
- <span class="cline-any cline-no">&nbsp;</span>
555
- <span class="cline-any cline-no">&nbsp;</span>
556
- <span class="cline-any cline-no">&nbsp;</span>
557
- <span class="cline-any cline-no">&nbsp;</span>
558
- <span class="cline-any cline-no">&nbsp;</span>
559
- <span class="cline-any cline-no">&nbsp;</span>
560
- <span class="cline-any cline-no">&nbsp;</span>
561
- <span class="cline-any cline-no">&nbsp;</span>
562
- <span class="cline-any cline-no">&nbsp;</span>
563
- <span class="cline-any cline-no">&nbsp;</span>
564
- <span class="cline-any cline-no">&nbsp;</span>
565
- <span class="cline-any cline-no">&nbsp;</span>
566
- <span class="cline-any cline-no">&nbsp;</span>
567
- <span class="cline-any cline-no">&nbsp;</span>
568
- <span class="cline-any cline-no">&nbsp;</span>
569
- <span class="cline-any cline-no">&nbsp;</span>
570
- <span class="cline-any cline-no">&nbsp;</span>
571
- <span class="cline-any cline-no">&nbsp;</span>
572
- <span class="cline-any cline-no">&nbsp;</span>
573
- <span class="cline-any cline-no">&nbsp;</span>
574
- <span class="cline-any cline-no">&nbsp;</span>
575
- <span class="cline-any cline-no">&nbsp;</span>
576
- <span class="cline-any cline-no">&nbsp;</span>
577
- <span class="cline-any cline-no">&nbsp;</span>
578
- <span class="cline-any cline-no">&nbsp;</span>
579
- <span class="cline-any cline-no">&nbsp;</span>
580
- <span class="cline-any cline-no">&nbsp;</span>
581
- <span class="cline-any cline-no">&nbsp;</span>
582
- <span class="cline-any cline-no">&nbsp;</span>
583
- <span class="cline-any cline-no">&nbsp;</span>
584
- <span class="cline-any cline-no">&nbsp;</span>
585
- <span class="cline-any cline-no">&nbsp;</span>
586
- <span class="cline-any cline-no">&nbsp;</span>
587
- <span class="cline-any cline-no">&nbsp;</span>
588
- <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js"><span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" ><span class="branch-0 cbranch-no" title="branch not covered" >import _ from 'lodash'</span></span></span>
589
- <span class="cstat-no" title="statement not covered" >import { unitConverters, SortOrder, GridSource, Grid2D } from './grid.js'</span>
590
- <span class="cstat-no" title="statement not covered" >import * as dap from './opendap-utils.js'</span>
591
- <span class="cstat-no" title="statement not covered" ></span>
592
- <span class="cstat-no" title="statement not covered" >// https://opendap.github.io/documentation/UserGuideComprehensive.html#Constraint_Expressions</span>
593
- <span class="cstat-no" title="statement not covered" ></span>
594
- <span class="cstat-no" title="statement not covered" >// only assumes grid variable is a regular grid w.r.t lat/lon</span>
595
- <span class="cstat-no" title="statement not covered" >export class OpenDapGridSource extends GridSource {</span>
596
- <span class="cstat-no" title="statement not covered" > static getKey () {</span>
597
- <span class="cstat-no" title="statement not covered" > return 'opendap'</span>
598
- <span class="cstat-no" title="statement not covered" > }</span>
599
- <span class="cstat-no" title="statement not covered" ></span>
600
- <span class="cstat-no" title="statement not covered" > constructor (options) {</span>
601
- <span class="cstat-no" title="statement not covered" > super(options)</span>
602
- <span class="cstat-no" title="statement not covered" ></span>
603
- <span class="cstat-no" title="statement not covered" > this.usable = false</span>
604
- <span class="cstat-no" title="statement not covered" > }</span>
605
- <span class="cstat-no" title="statement not covered" ></span>
606
- <span class="cstat-no" title="statement not covered" > getBBox () {</span>
607
- <span class="cstat-no" title="statement not covered" > return this.usable ? [this.minMaxLat[0], this.minMaxLon[0], this.minMaxLat[1], this.minMaxLon[1]] : null</span>
608
- <span class="cstat-no" title="statement not covered" > }</span>
609
- <span class="cstat-no" title="statement not covered" ></span>
610
- <span class="cstat-no" title="statement not covered" > getDataBounds () {</span>
327
+ <a name='L262'></a><a href='#L262'>262</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
328
+ <span class="cline-any cline-yes">1x</span>
329
+ <span class="cline-any cline-yes">1x</span>
330
+ <span class="cline-any cline-yes">1x</span>
331
+ <span class="cline-any cline-yes">1x</span>
332
+ <span class="cline-any cline-yes">1x</span>
333
+ <span class="cline-any cline-yes">1x</span>
334
+ <span class="cline-any cline-yes">1x</span>
335
+ <span class="cline-any cline-yes">1x</span>
336
+ <span class="cline-any cline-yes">1x</span>
337
+ <span class="cline-any cline-yes">1x</span>
338
+ <span class="cline-any cline-yes">1x</span>
339
+ <span class="cline-any cline-yes">1x</span>
340
+ <span class="cline-any cline-yes">1x</span>
341
+ <span class="cline-any cline-yes">1x</span>
342
+ <span class="cline-any cline-yes">1x</span>
343
+ <span class="cline-any cline-yes">1x</span>
344
+ <span class="cline-any cline-yes">1x</span>
345
+ <span class="cline-any cline-yes">1x</span>
346
+ <span class="cline-any cline-yes">1x</span>
347
+ <span class="cline-any cline-yes">1x</span>
348
+ <span class="cline-any cline-yes">1x</span>
349
+ <span class="cline-any cline-yes">1x</span>
350
+ <span class="cline-any cline-no">&nbsp;</span>
351
+ <span class="cline-any cline-no">&nbsp;</span>
352
+ <span class="cline-any cline-yes">1x</span>
353
+ <span class="cline-any cline-yes">1x</span>
354
+ <span class="cline-any cline-yes">1x</span>
355
+ <span class="cline-any cline-yes">1x</span>
356
+ <span class="cline-any cline-yes">1x</span>
357
+ <span class="cline-any cline-yes">1x</span>
358
+ <span class="cline-any cline-yes">1x</span>
359
+ <span class="cline-any cline-yes">1x</span>
360
+ <span class="cline-any cline-yes">1x</span>
361
+ <span class="cline-any cline-yes">1x</span>
362
+ <span class="cline-any cline-yes">1x</span>
363
+ <span class="cline-any cline-yes">1x</span>
364
+ <span class="cline-any cline-yes">1x</span>
365
+ <span class="cline-any cline-yes">1x</span>
366
+ <span class="cline-any cline-yes">1x</span>
367
+ <span class="cline-any cline-yes">1x</span>
368
+ <span class="cline-any cline-yes">1x</span>
369
+ <span class="cline-any cline-yes">1x</span>
370
+ <span class="cline-any cline-yes">1x</span>
371
+ <span class="cline-any cline-yes">1x</span>
372
+ <span class="cline-any cline-yes">1x</span>
373
+ <span class="cline-any cline-yes">1x</span>
374
+ <span class="cline-any cline-yes">1x</span>
375
+ <span class="cline-any cline-yes">1x</span>
376
+ <span class="cline-any cline-yes">1x</span>
377
+ <span class="cline-any cline-yes">1x</span>
378
+ <span class="cline-any cline-yes">1x</span>
379
+ <span class="cline-any cline-yes">1x</span>
380
+ <span class="cline-any cline-no">&nbsp;</span>
381
+ <span class="cline-any cline-no">&nbsp;</span>
382
+ <span class="cline-any cline-no">&nbsp;</span>
383
+ <span class="cline-any cline-no">&nbsp;</span>
384
+ <span class="cline-any cline-no">&nbsp;</span>
385
+ <span class="cline-any cline-yes">1x</span>
386
+ <span class="cline-any cline-yes">1x</span>
387
+ <span class="cline-any cline-yes">1x</span>
388
+ <span class="cline-any cline-yes">1x</span>
389
+ <span class="cline-any cline-yes">1x</span>
390
+ <span class="cline-any cline-yes">1x</span>
391
+ <span class="cline-any cline-yes">1x</span>
392
+ <span class="cline-any cline-yes">1x</span>
393
+ <span class="cline-any cline-yes">1x</span>
394
+ <span class="cline-any cline-yes">1x</span>
395
+ <span class="cline-any cline-yes">1x</span>
396
+ <span class="cline-any cline-yes">1x</span>
397
+ <span class="cline-any cline-yes">1x</span>
398
+ <span class="cline-any cline-yes">1x</span>
399
+ <span class="cline-any cline-yes">1x</span>
400
+ <span class="cline-any cline-yes">1x</span>
401
+ <span class="cline-any cline-yes">1x</span>
402
+ <span class="cline-any cline-yes">1x</span>
403
+ <span class="cline-any cline-yes">1x</span>
404
+ <span class="cline-any cline-yes">1x</span>
405
+ <span class="cline-any cline-yes">1x</span>
406
+ <span class="cline-any cline-yes">1x</span>
407
+ <span class="cline-any cline-yes">1x</span>
408
+ <span class="cline-any cline-yes">1x</span>
409
+ <span class="cline-any cline-yes">1x</span>
410
+ <span class="cline-any cline-yes">1x</span>
411
+ <span class="cline-any cline-yes">1x</span>
412
+ <span class="cline-any cline-yes">1x</span>
413
+ <span class="cline-any cline-yes">1x</span>
414
+ <span class="cline-any cline-yes">1x</span>
415
+ <span class="cline-any cline-yes">1x</span>
416
+ <span class="cline-any cline-no">&nbsp;</span>
417
+ <span class="cline-any cline-no">&nbsp;</span>
418
+ <span class="cline-any cline-yes">1x</span>
419
+ <span class="cline-any cline-no">&nbsp;</span>
420
+ <span class="cline-any cline-no">&nbsp;</span>
421
+ <span class="cline-any cline-no">&nbsp;</span>
422
+ <span class="cline-any cline-no">&nbsp;</span>
423
+ <span class="cline-any cline-yes">1x</span>
424
+ <span class="cline-any cline-yes">1x</span>
425
+ <span class="cline-any cline-yes">1x</span>
426
+ <span class="cline-any cline-yes">1x</span>
427
+ <span class="cline-any cline-yes">1x</span>
428
+ <span class="cline-any cline-yes">1x</span>
429
+ <span class="cline-any cline-yes">1x</span>
430
+ <span class="cline-any cline-yes">1x</span>
431
+ <span class="cline-any cline-yes">1x</span>
432
+ <span class="cline-any cline-yes">1x</span>
433
+ <span class="cline-any cline-yes">1x</span>
434
+ <span class="cline-any cline-yes">1x</span>
435
+ <span class="cline-any cline-yes">1x</span>
436
+ <span class="cline-any cline-yes">1x</span>
437
+ <span class="cline-any cline-yes">1x</span>
438
+ <span class="cline-any cline-yes">1x</span>
439
+ <span class="cline-any cline-yes">1x</span>
440
+ <span class="cline-any cline-yes">1x</span>
441
+ <span class="cline-any cline-yes">1x</span>
442
+ <span class="cline-any cline-yes">1x</span>
443
+ <span class="cline-any cline-yes">1x</span>
444
+ <span class="cline-any cline-yes">1x</span>
445
+ <span class="cline-any cline-yes">1x</span>
446
+ <span class="cline-any cline-yes">1x</span>
447
+ <span class="cline-any cline-yes">1x</span>
448
+ <span class="cline-any cline-yes">1x</span>
449
+ <span class="cline-any cline-yes">1x</span>
450
+ <span class="cline-any cline-yes">1x</span>
451
+ <span class="cline-any cline-yes">1x</span>
452
+ <span class="cline-any cline-yes">1x</span>
453
+ <span class="cline-any cline-yes">1x</span>
454
+ <span class="cline-any cline-yes">1x</span>
455
+ <span class="cline-any cline-yes">1x</span>
456
+ <span class="cline-any cline-yes">1x</span>
457
+ <span class="cline-any cline-yes">1x</span>
458
+ <span class="cline-any cline-yes">1x</span>
459
+ <span class="cline-any cline-yes">1x</span>
460
+ <span class="cline-any cline-yes">1x</span>
461
+ <span class="cline-any cline-yes">1x</span>
462
+ <span class="cline-any cline-no">&nbsp;</span>
463
+ <span class="cline-any cline-no">&nbsp;</span>
464
+ <span class="cline-any cline-no">&nbsp;</span>
465
+ <span class="cline-any cline-no">&nbsp;</span>
466
+ <span class="cline-any cline-no">&nbsp;</span>
467
+ <span class="cline-any cline-no">&nbsp;</span>
468
+ <span class="cline-any cline-no">&nbsp;</span>
469
+ <span class="cline-any cline-yes">1x</span>
470
+ <span class="cline-any cline-yes">1x</span>
471
+ <span class="cline-any cline-yes">1x</span>
472
+ <span class="cline-any cline-yes">1x</span>
473
+ <span class="cline-any cline-yes">1x</span>
474
+ <span class="cline-any cline-yes">1x</span>
475
+ <span class="cline-any cline-yes">1x</span>
476
+ <span class="cline-any cline-yes">1x</span>
477
+ <span class="cline-any cline-yes">1x</span>
478
+ <span class="cline-any cline-yes">1x</span>
479
+ <span class="cline-any cline-yes">1x</span>
480
+ <span class="cline-any cline-yes">1x</span>
481
+ <span class="cline-any cline-yes">1x</span>
482
+ <span class="cline-any cline-yes">1x</span>
483
+ <span class="cline-any cline-yes">1x</span>
484
+ <span class="cline-any cline-yes">1x</span>
485
+ <span class="cline-any cline-yes">1x</span>
486
+ <span class="cline-any cline-yes">1x</span>
487
+ <span class="cline-any cline-yes">1x</span>
488
+ <span class="cline-any cline-yes">1x</span>
489
+ <span class="cline-any cline-yes">1x</span>
490
+ <span class="cline-any cline-yes">1x</span>
491
+ <span class="cline-any cline-yes">1x</span>
492
+ <span class="cline-any cline-yes">1x</span>
493
+ <span class="cline-any cline-yes">1x</span>
494
+ <span class="cline-any cline-yes">1x</span>
495
+ <span class="cline-any cline-no">&nbsp;</span>
496
+ <span class="cline-any cline-no">&nbsp;</span>
497
+ <span class="cline-any cline-no">&nbsp;</span>
498
+ <span class="cline-any cline-no">&nbsp;</span>
499
+ <span class="cline-any cline-yes">1x</span>
500
+ <span class="cline-any cline-yes">1x</span>
501
+ <span class="cline-any cline-yes">1x</span>
502
+ <span class="cline-any cline-yes">1x</span>
503
+ <span class="cline-any cline-yes">1x</span>
504
+ <span class="cline-any cline-yes">1x</span>
505
+ <span class="cline-any cline-yes">1x</span>
506
+ <span class="cline-any cline-yes">1x</span>
507
+ <span class="cline-any cline-yes">1x</span>
508
+ <span class="cline-any cline-no">&nbsp;</span>
509
+ <span class="cline-any cline-no">&nbsp;</span>
510
+ <span class="cline-any cline-yes">1x</span>
511
+ <span class="cline-any cline-no">&nbsp;</span>
512
+ <span class="cline-any cline-no">&nbsp;</span>
513
+ <span class="cline-any cline-yes">1x</span>
514
+ <span class="cline-any cline-yes">1x</span>
515
+ <span class="cline-any cline-yes">1x</span>
516
+ <span class="cline-any cline-yes">1x</span>
517
+ <span class="cline-any cline-yes">1x</span>
518
+ <span class="cline-any cline-yes">1x</span>
519
+ <span class="cline-any cline-yes">1x</span>
520
+ <span class="cline-any cline-yes">1x</span>
521
+ <span class="cline-any cline-yes">1x</span>
522
+ <span class="cline-any cline-yes">1x</span>
523
+ <span class="cline-any cline-yes">1x</span>
524
+ <span class="cline-any cline-yes">1x</span>
525
+ <span class="cline-any cline-yes">1x</span>
526
+ <span class="cline-any cline-yes">1x</span>
527
+ <span class="cline-any cline-yes">1x</span>
528
+ <span class="cline-any cline-yes">1x</span>
529
+ <span class="cline-any cline-yes">1x</span>
530
+ <span class="cline-any cline-yes">1x</span>
531
+ <span class="cline-any cline-yes">1x</span>
532
+ <span class="cline-any cline-yes">1x</span>
533
+ <span class="cline-any cline-yes">1x</span>
534
+ <span class="cline-any cline-yes">1x</span>
535
+ <span class="cline-any cline-yes">1x</span>
536
+ <span class="cline-any cline-yes">1x</span>
537
+ <span class="cline-any cline-yes">1x</span>
538
+ <span class="cline-any cline-yes">1x</span>
539
+ <span class="cline-any cline-yes">1x</span>
540
+ <span class="cline-any cline-yes">1x</span>
541
+ <span class="cline-any cline-yes">1x</span>
542
+ <span class="cline-any cline-yes">1x</span>
543
+ <span class="cline-any cline-yes">1x</span>
544
+ <span class="cline-any cline-yes">1x</span>
545
+ <span class="cline-any cline-yes">1x</span>
546
+ <span class="cline-any cline-yes">1x</span>
547
+ <span class="cline-any cline-yes">1x</span>
548
+ <span class="cline-any cline-yes">1x</span>
549
+ <span class="cline-any cline-yes">1x</span>
550
+ <span class="cline-any cline-yes">1x</span>
551
+ <span class="cline-any cline-yes">1x</span>
552
+ <span class="cline-any cline-yes">1x</span>
553
+ <span class="cline-any cline-yes">1x</span>
554
+ <span class="cline-any cline-yes">1x</span>
555
+ <span class="cline-any cline-yes">1x</span>
556
+ <span class="cline-any cline-yes">1x</span>
557
+ <span class="cline-any cline-yes">1x</span>
558
+ <span class="cline-any cline-yes">1x</span>
559
+ <span class="cline-any cline-yes">1x</span>
560
+ <span class="cline-any cline-yes">1x</span>
561
+ <span class="cline-any cline-yes">1x</span>
562
+ <span class="cline-any cline-yes">1x</span>
563
+ <span class="cline-any cline-no">&nbsp;</span>
564
+ <span class="cline-any cline-no">&nbsp;</span>
565
+ <span class="cline-any cline-no">&nbsp;</span>
566
+ <span class="cline-any cline-no">&nbsp;</span>
567
+ <span class="cline-any cline-no">&nbsp;</span>
568
+ <span class="cline-any cline-no">&nbsp;</span>
569
+ <span class="cline-any cline-no">&nbsp;</span>
570
+ <span class="cline-any cline-no">&nbsp;</span>
571
+ <span class="cline-any cline-no">&nbsp;</span>
572
+ <span class="cline-any cline-no">&nbsp;</span>
573
+ <span class="cline-any cline-no">&nbsp;</span>
574
+ <span class="cline-any cline-no">&nbsp;</span>
575
+ <span class="cline-any cline-no">&nbsp;</span>
576
+ <span class="cline-any cline-no">&nbsp;</span>
577
+ <span class="cline-any cline-no">&nbsp;</span>
578
+ <span class="cline-any cline-no">&nbsp;</span>
579
+ <span class="cline-any cline-no">&nbsp;</span>
580
+ <span class="cline-any cline-no">&nbsp;</span>
581
+ <span class="cline-any cline-no">&nbsp;</span>
582
+ <span class="cline-any cline-no">&nbsp;</span>
583
+ <span class="cline-any cline-no">&nbsp;</span>
584
+ <span class="cline-any cline-yes">1x</span>
585
+ <span class="cline-any cline-yes">1x</span>
586
+ <span class="cline-any cline-yes">1x</span>
587
+ <span class="cline-any cline-yes">1x</span>
588
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import _ from 'lodash'
589
+ import { unitConverters, SortOrder, GridSource, Grid2D } from './grid.js'
590
+ import * as dap from './opendap-utils.js'
591
+ &nbsp;
592
+ // https://opendap.github.io/documentation/UserGuideComprehensive.html#Constraint_Expressions
593
+ &nbsp;
594
+ // only assumes grid variable is a regular grid w.r.t lat/lon
595
+ export class OpenDapGridSource extends GridSource {
596
+ static getKey () {
597
+ return 'opendap'
598
+ }
599
+ &nbsp;
600
+ constructor (options) {
601
+ super(options)
602
+ &nbsp;
603
+ this.usable = false
604
+ }
605
+ &nbsp;
606
+ getBBox () {
607
+ return this.usable ? [this.minMaxLat[0], this.minMaxLon[0], this.minMaxLat[1], this.minMaxLon[1]] <span class="branch-0 cbranch-no" title="branch not covered" >: null</span>
608
+ }
609
+ &nbsp;
610
+ <span class="fstat-no" title="function not covered" > getDataBounds () {</span>
611
611
  <span class="cstat-no" title="statement not covered" > return this.usable ? this.minMaxVal : null</span>
612
612
  <span class="cstat-no" title="statement not covered" > }</span>
613
- <span class="cstat-no" title="statement not covered" ></span>
614
- <span class="cstat-no" title="statement not covered" > async setup (config) {</span>
615
- <span class="cstat-no" title="statement not covered" > this.usable = false</span>
616
- <span class="cstat-no" title="statement not covered" > ++this.sourceKey</span>
617
- <span class="cstat-no" title="statement not covered" ></span>
618
- <span class="cstat-no" title="statement not covered" > this.descriptor = null</span>
619
- <span class="cstat-no" title="statement not covered" > this.indices = null</span>
620
- <span class="cstat-no" title="statement not covered" > this.latCount = 0</span>
621
- <span class="cstat-no" title="statement not covered" > this.latIndex = 0</span>
622
- <span class="cstat-no" title="statement not covered" > this.lonCount = 0</span>
623
- <span class="cstat-no" title="statement not covered" > this.lonIndex = 0</span>
624
- <span class="cstat-no" title="statement not covered" ></span>
625
- <span class="cstat-no" title="statement not covered" > this.minMaxLat = null</span>
626
- <span class="cstat-no" title="statement not covered" > this.minMaxLon = null</span>
627
- <span class="cstat-no" title="statement not covered" > this.minMaxVal = null</span>
628
- <span class="cstat-no" title="statement not covered" > this.latStep = 0</span>
629
- <span class="cstat-no" title="statement not covered" > this.lonStep = 0</span>
630
- <span class="cstat-no" title="statement not covered" > this.latSortOrder = SortOrder.ASCENDING</span>
631
- <span class="cstat-no" title="statement not covered" > this.lonSortOrder = SortOrder.ASCENDING</span>
632
- <span class="cstat-no" title="statement not covered" ></span>
633
- <span class="cstat-no" title="statement not covered" > this.canUseGrid2D = false</span>
634
- <span class="cstat-no" title="statement not covered" ></span>
635
- <span class="cstat-no" title="statement not covered" > this.config = config</span>
636
- <span class="cstat-no" title="statement not covered" > this.converter = unitConverters[this.config.converter]</span>
637
- <span class="cstat-no" title="statement not covered" ></span>
638
- <span class="cstat-no" title="statement not covered" > try {</span>
639
- <span class="cstat-no" title="statement not covered" > this.descriptor = await dap.fetchDescriptor(this.config.url)</span>
640
- <span class="cstat-no" title="statement not covered" > } catch (error) {</span>
613
+ &nbsp;
614
+ async setup (config) {
615
+ this.usable = false
616
+ ++this.sourceKey
617
+ &nbsp;
618
+ this.descriptor = null
619
+ this.indices = null
620
+ this.latCount = 0
621
+ this.latIndex = 0
622
+ this.lonCount = 0
623
+ this.lonIndex = 0
624
+ &nbsp;
625
+ this.minMaxLat = null
626
+ this.minMaxLon = null
627
+ this.minMaxVal = null
628
+ this.latStep = 0
629
+ this.lonStep = 0
630
+ this.latSortOrder = SortOrder.ASCENDING
631
+ this.lonSortOrder = SortOrder.ASCENDING
632
+ &nbsp;
633
+ this.canUseGrid2D = false
634
+ &nbsp;
635
+ this.config = config
636
+ this.converter = unitConverters[this.config.converter]
637
+ &nbsp;
638
+ try {
639
+ this.descriptor = await dap.fetchDescriptor(this.config.url)
640
+ } <span class="branch-0 cbranch-no" title="branch not covered" >catch (error) {</span>
641
641
  <span class="cstat-no" title="statement not covered" > // fetching may fail, in this case the source</span>
642
642
  <span class="cstat-no" title="statement not covered" > // will remain in unusable state</span>
643
643
  <span class="cstat-no" title="statement not covered" > this.descriptor = null</span>
644
644
  <span class="cstat-no" title="statement not covered" > console.log(`Failed fetching opendap descriptor from ${this.config.url}`)</span>
645
645
  <span class="cstat-no" title="statement not covered" > }</span>
646
- <span class="cstat-no" title="statement not covered" ></span>
647
- <span class="cstat-no" title="statement not covered" > if (this.descriptor) {</span>
648
- <span class="cstat-no" title="statement not covered" > const varIsGrid = dap.variableIsGrid(this.descriptor, this.config.variable)</span>
649
- <span class="cstat-no" title="statement not covered" > const latIsArray = dap.variableIsArray(this.descriptor, this.config.latitude)</span>
650
- <span class="cstat-no" title="statement not covered" > const lonIsArray = dap.variableIsArray(this.descriptor, this.config.longitude)</span>
651
- <span class="cstat-no" title="statement not covered" > if (varIsGrid &amp;&amp; latIsArray &amp;&amp; lonIsArray) {</span>
652
- <span class="cstat-no" title="statement not covered" > this.latIndex = dap.getGridDimensionIndex(this.descriptor, this.config.variable, this.config.latitude)</span>
653
- <span class="cstat-no" title="statement not covered" > this.latCount = dap.getGridDimensionLength(this.descriptor, this.config.variable, this.latIndex)</span>
654
- <span class="cstat-no" title="statement not covered" > this.lonIndex = dap.getGridDimensionIndex(this.descriptor, this.config.variable, this.config.longitude)</span>
655
- <span class="cstat-no" title="statement not covered" > this.lonCount = dap.getGridDimensionLength(this.descriptor, this.config.variable, this.lonIndex)</span>
656
- <span class="cstat-no" title="statement not covered" ></span>
657
- <span class="cstat-no" title="statement not covered" > // build grid indexing array</span>
658
- <span class="cstat-no" title="statement not covered" > const dimensions = await this.getDimensionsAsIndices()</span>
659
- <span class="cstat-no" title="statement not covered" > dimensions[this.config.latitude] = `0:${this.latCount - 1}`</span>
660
- <span class="cstat-no" title="statement not covered" > dimensions[this.config.longitude] = `0:${this.lonCount - 1}`</span>
661
- <span class="cstat-no" title="statement not covered" > this.indices = dap.makeGridIndices(this.descriptor, this.config.variable, dimensions)</span>
662
- <span class="cstat-no" title="statement not covered" > if (this.indices.length !== 0) {</span>
663
- <span class="cstat-no" title="statement not covered" > // if lat and lon dimensions are the last in the query, we can</span>
664
- <span class="cstat-no" title="statement not covered" > // use a Grid2D directly (cheaper on cpu)</span>
665
- <span class="cstat-no" title="statement not covered" > const last = this.indices.length - 1</span>
666
- <span class="cstat-no" title="statement not covered" > if ((this.latIndex === last &amp;&amp; this.lonIndex === (last - 1)) ||</span>
667
- <span class="cstat-no" title="statement not covered" > (this.latIndex === (last - 1) &amp;&amp; this.lonIndex === last)) {</span>
668
- <span class="cstat-no" title="statement not covered" > this.canUseGrid2D = true</span>
669
- <span class="cstat-no" title="statement not covered" > }</span>
670
- <span class="cstat-no" title="statement not covered" ></span>
671
- <span class="cstat-no" title="statement not covered" > // TODO: store metadata somewhere instead of requesting the whole variable</span>
672
- <span class="cstat-no" title="statement not covered" > await this.computeMetaDataFromData()</span>
673
- <span class="cstat-no" title="statement not covered" ></span>
674
- <span class="cstat-no" title="statement not covered" > // flag source as usable</span>
675
- <span class="cstat-no" title="statement not covered" > this.usable = true</span>
676
- <span class="cstat-no" title="statement not covered" > } else {</span>
646
+ &nbsp;
647
+ if (this.descriptor) {
648
+ const varIsGrid = dap.variableIsGrid(this.descriptor, this.config.variable)
649
+ const latIsArray = dap.variableIsArray(this.descriptor, this.config.latitude)
650
+ const lonIsArray = dap.variableIsArray(this.descriptor, this.config.longitude)
651
+ if (varIsGrid &amp;&amp; latIsArray &amp;&amp; lonIsArray) {
652
+ this.latIndex = dap.getGridDimensionIndex(this.descriptor, this.config.variable, this.config.latitude)
653
+ this.latCount = dap.getGridDimensionLength(this.descriptor, this.config.variable, this.latIndex)
654
+ this.lonIndex = dap.getGridDimensionIndex(this.descriptor, this.config.variable, this.config.longitude)
655
+ this.lonCount = dap.getGridDimensionLength(this.descriptor, this.config.variable, this.lonIndex)
656
+ &nbsp;
657
+ // build grid indexing array
658
+ const dimensions = await this.getDimensionsAsIndices()
659
+ dimensions[this.config.latitude] = `0:${this.latCount - 1}`
660
+ dimensions[this.config.longitude] = `0:${this.lonCount - 1}`
661
+ this.indices = dap.makeGridIndices(this.descriptor, this.config.variable, dimensions)
662
+ if (this.indices.length !== 0) {
663
+ // if lat and lon dimensions are the last in the query, we can
664
+ // use a Grid2D directly (cheaper on cpu)
665
+ const last = this.indices.length - 1
666
+ if ((this.latIndex === last <span class="branch-0 cbranch-no" title="branch not covered" >&amp;&amp; this.lonIndex === (last - 1))</span> ||
667
+ (this.latIndex === (last - 1) &amp;&amp; this.lonIndex === last)) {
668
+ this.canUseGrid2D = true
669
+ }
670
+ &nbsp;
671
+ // TODO: store metadata somewhere instead of requesting the whole variable
672
+ await this.computeMetaDataFromData()
673
+ &nbsp;
674
+ // flag source as usable
675
+ this.usable = true
676
+ }<span class="branch-0 cbranch-no" title="branch not covered" > else {</span>
677
677
  <span class="cstat-no" title="statement not covered" > console.log("Couldn't create index array for grid")</span>
678
678
  <span class="cstat-no" title="statement not covered" > }</span>
679
- <span class="cstat-no" title="statement not covered" > } else {</span>
679
+ }<span class="branch-0 cbranch-no" title="branch not covered" > else {</span>
680
680
  <span class="cstat-no" title="statement not covered" > if (!varIsGrid) console.log(`${this.config.variable} is not a grid variable!`)</span>
681
681
  <span class="cstat-no" title="statement not covered" > if (!latIsArray) console.log(`${this.config.latitude} is expected to be an array variable!`)</span>
682
682
  <span class="cstat-no" title="statement not covered" > if (!lonIsArray) console.log(`${this.config.longitude} is expected to be an array variable!`)</span>
683
683
  <span class="cstat-no" title="statement not covered" > }</span>
684
- <span class="cstat-no" title="statement not covered" > }</span>
685
- <span class="cstat-no" title="statement not covered" ></span>
686
- <span class="cstat-no" title="statement not covered" > this.dataChanged()</span>
687
- <span class="cstat-no" title="statement not covered" > }</span>
688
- <span class="cstat-no" title="statement not covered" ></span>
689
- <span class="cstat-no" title="statement not covered" > async fetch (abort, bbox, resolution) {</span>
690
- <span class="cstat-no" title="statement not covered" > if (!this.usable) { return null }</span>
691
- <span class="cstat-no" title="statement not covered" ></span>
692
- <span class="cstat-no" title="statement not covered" > const query = this.makeQuery(bbox, resolution)</span>
693
- <span class="cstat-no" title="statement not covered" > if (!query) { return null }</span>
694
- <span class="cstat-no" title="statement not covered" ></span>
695
- <span class="cstat-no" title="statement not covered" > const sourceKey = this.sourceKey</span>
696
- <span class="cstat-no" title="statement not covered" ></span>
697
- <span class="cstat-no" title="statement not covered" > const data = await dap.fetchData(query, abort)</span>
698
- <span class="cstat-no" title="statement not covered" > const req = data[this.config.variable]</span>
699
- <span class="cstat-no" title="statement not covered" > const valData = req[0]</span>
700
- <span class="cstat-no" title="statement not covered" > const latData = req[this.latIndex + 1]</span>
701
- <span class="cstat-no" title="statement not covered" > const lonData = req[this.lonIndex + 1]</span>
702
- <span class="cstat-no" title="statement not covered" ></span>
703
- <span class="cstat-no" title="statement not covered" > const lat0 = latData[0]</span>
704
- <span class="cstat-no" title="statement not covered" > const lat1 = latData[latData.length - 1]</span>
705
- <span class="cstat-no" title="statement not covered" > let lon0 = lonData[0]</span>
706
- <span class="cstat-no" title="statement not covered" > let lon1 = lonData[lonData.length - 1]</span>
707
- <span class="cstat-no" title="statement not covered" ></span>
708
- <span class="cstat-no" title="statement not covered" > // normalize bounds</span>
709
- <span class="cstat-no" title="statement not covered" > if (lon0 &gt; 180.0) lon0 -= 360.0</span>
710
- <span class="cstat-no" title="statement not covered" > if (lon1 &gt; 180.0) lon1 -= 360.0</span>
711
- <span class="cstat-no" title="statement not covered" > const databbox = [Math.min(lat0, lat1), Math.min(lon0, lon1), Math.max(lat0, lat1), Math.max(lon0, lon1)]</span>
712
- <span class="cstat-no" title="statement not covered" ></span>
713
- <span class="cstat-no" title="statement not covered" > if (this.canUseGrid2D) {</span>
714
- <span class="cstat-no" title="statement not covered" > const indices = this.indices.slice(0, this.indices.length - 2)</span>
715
- <span class="cstat-no" title="statement not covered" > indices.fill(0)</span>
716
- <span class="cstat-no" title="statement not covered" > const subgrid = dap.getGridValue(valData, indices)</span>
717
- <span class="cstat-no" title="statement not covered" > return new Grid2D(</span>
718
- <span class="cstat-no" title="statement not covered" > sourceKey,</span>
719
- <span class="cstat-no" title="statement not covered" > databbox, [latData.length, lonData.length],</span>
720
- <span class="cstat-no" title="statement not covered" > subgrid, this.latIndex &lt; this.lonIndex, this.latSortOrder, this.lonSortOrder,</span>
721
- <span class="cstat-no" title="statement not covered" > this.nodata, this.converter)</span>
722
- <span class="cstat-no" title="statement not covered" > }</span>
723
- <span class="cstat-no" title="statement not covered" ></span>
684
+ }
685
+ &nbsp;
686
+ this.dataChanged()
687
+ }
688
+ &nbsp;
689
+ async fetch (abort, bbox, resolution) {
690
+ if (!this.usable) <span class="branch-0 cbranch-no" title="branch not covered" >{ return null }</span>
691
+ &nbsp;
692
+ const query = this.makeQuery(bbox, resolution)
693
+ if (!query) <span class="branch-0 cbranch-no" title="branch not covered" >{ return null }</span>
694
+ &nbsp;
695
+ const sourceKey = this.sourceKey
696
+ &nbsp;
697
+ const data = await dap.fetchData(query, abort)
698
+ const req = data[this.config.variable]
699
+ const valData = req[0]
700
+ const latData = req[this.latIndex + 1]
701
+ const lonData = req[this.lonIndex + 1]
702
+ &nbsp;
703
+ const lat0 = latData[0]
704
+ const lat1 = latData[latData.length - 1]
705
+ let lon0 = lonData[0]
706
+ let lon1 = lonData[lonData.length - 1]
707
+ &nbsp;
708
+ // normalize bounds
709
+ if (lon0 &gt; 180.0) <span class="branch-0 cbranch-no" title="branch not covered" >lon0 -= 360.0</span>
710
+ if (lon1 &gt; 180.0) <span class="branch-0 cbranch-no" title="branch not covered" >lon1 -= 360.0</span>
711
+ const databbox = [Math.min(lat0, lat1), Math.min(lon0, lon1), Math.max(lat0, lat1), Math.max(lon0, lon1)]
712
+ &nbsp;
713
+ if (this.canUseGrid2D) {
714
+ const indices = this.indices.slice(0, this.indices.length - 2)
715
+ indices.fill(0)
716
+ const subgrid = dap.getGridValue(valData, indices)
717
+ return new Grid2D(
718
+ sourceKey,
719
+ databbox, [latData.length, lonData.length],
720
+ subgrid, this.latIndex &lt; this.lonIndex, this.latSortOrder, this.lonSortOrder,
721
+ this.nodata, this.converter)
722
+ }
723
+ <span class="cstat-no" title="statement not covered" ><span class="branch-0 cbranch-no" title="branch not covered" ></span></span>
724
724
  <span class="cstat-no" title="statement not covered" > return new dap.OpenDAPGrid(</span>
725
725
  <span class="cstat-no" title="statement not covered" > sourceKey,</span>
726
726
  <span class="cstat-no" title="statement not covered" > databbox, [latData.length, lonData.length],</span>
727
727
  <span class="cstat-no" title="statement not covered" > valData, this.indices, this.latIndex, this.lonIndex,</span>
728
728
  <span class="cstat-no" title="statement not covered" > this.latSortOrder, this.lonSortOrder,</span>
729
729
  <span class="cstat-no" title="statement not covered" > this.nodata, this.converter)</span>
730
- <span class="cstat-no" title="statement not covered" > }</span>
731
- <span class="cstat-no" title="statement not covered" ></span>
732
- <span class="cstat-no" title="statement not covered" > makeQuery (bbox, resolution) {</span>
733
- <span class="cstat-no" title="statement not covered" > const reqMinLat = bbox[0]</span>
734
- <span class="cstat-no" title="statement not covered" > const reqMinLon = bbox[1]</span>
735
- <span class="cstat-no" title="statement not covered" > const reqMaxLat = bbox[2]</span>
736
- <span class="cstat-no" title="statement not covered" > const reqMaxLon = bbox[3]</span>
737
- <span class="cstat-no" title="statement not covered" ></span>
738
- <span class="cstat-no" title="statement not covered" > // compute coordinates indices (assume lat/lon both ascending)</span>
739
- <span class="cstat-no" title="statement not covered" > let iMinLat = Math.floor((reqMinLat - this.minMaxLat[0]) / this.latStep)</span>
740
- <span class="cstat-no" title="statement not covered" > let iMinLon = Math.floor((reqMinLon - this.minMaxLon[0]) / this.lonStep)</span>
741
- <span class="cstat-no" title="statement not covered" > let iMaxLat = Math.ceil((reqMaxLat - this.minMaxLat[0]) / this.latStep)</span>
742
- <span class="cstat-no" title="statement not covered" > let iMaxLon = Math.ceil((reqMaxLon - this.minMaxLon[0]) / this.lonStep)</span>
743
- <span class="cstat-no" title="statement not covered" ></span>
744
- <span class="cstat-no" title="statement not covered" > // clamp indices</span>
745
- <span class="cstat-no" title="statement not covered" > iMinLat = Math.min(Math.max(iMinLat, 0), this.latCount - 1)</span>
746
- <span class="cstat-no" title="statement not covered" > iMinLon = Math.min(Math.max(iMinLon, 0), this.lonCount - 1)</span>
747
- <span class="cstat-no" title="statement not covered" > iMaxLat = Math.min(Math.max(iMaxLat, 0), this.latCount - 1)</span>
748
- <span class="cstat-no" title="statement not covered" > iMaxLon = Math.min(Math.max(iMaxLon, 0), this.lonCount - 1)</span>
749
- <span class="cstat-no" title="statement not covered" ></span>
750
- <span class="cstat-no" title="statement not covered" > if (this.latSortOrder === SortOrder.DESCENDING) {</span>
751
- <span class="cstat-no" title="statement not covered" > const tmp = iMinLat</span>
752
- <span class="cstat-no" title="statement not covered" > iMinLat = this.latCount - 1 - iMaxLat</span>
753
- <span class="cstat-no" title="statement not covered" > iMaxLat = this.latCount - 1 - tmp</span>
754
- <span class="cstat-no" title="statement not covered" > }</span>
755
- <span class="cstat-no" title="statement not covered" > if (this.lonSortOrder === SortOrder.DESCENDING) {</span>
730
+ }
731
+ &nbsp;
732
+ makeQuery (bbox, resolution) {
733
+ const reqMinLat = bbox[0]
734
+ const reqMinLon = bbox[1]
735
+ const reqMaxLat = bbox[2]
736
+ const reqMaxLon = bbox[3]
737
+ &nbsp;
738
+ // compute coordinates indices (assume lat/lon both ascending)
739
+ let iMinLat = Math.floor((reqMinLat - this.minMaxLat[0]) / this.latStep)
740
+ let iMinLon = Math.floor((reqMinLon - this.minMaxLon[0]) / this.lonStep)
741
+ let iMaxLat = Math.ceil((reqMaxLat - this.minMaxLat[0]) / this.latStep)
742
+ let iMaxLon = Math.ceil((reqMaxLon - this.minMaxLon[0]) / this.lonStep)
743
+ &nbsp;
744
+ // clamp indices
745
+ iMinLat = Math.min(Math.max(iMinLat, 0), this.latCount - 1)
746
+ iMinLon = Math.min(Math.max(iMinLon, 0), this.lonCount - 1)
747
+ iMaxLat = Math.min(Math.max(iMaxLat, 0), this.latCount - 1)
748
+ iMaxLon = Math.min(Math.max(iMaxLon, 0), this.lonCount - 1)
749
+ &nbsp;
750
+ if (this.latSortOrder === SortOrder.DESCENDING) {
751
+ const tmp = iMinLat
752
+ iMinLat = this.latCount - 1 - iMaxLat
753
+ iMaxLat = this.latCount - 1 - tmp
754
+ }
755
+ if (this.lonSortOrder === SortOrder.DESCENDING) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
756
756
  <span class="cstat-no" title="statement not covered" > const tmp = iMinLon</span>
757
757
  <span class="cstat-no" title="statement not covered" > iMinLon = this.lonCount - 1 - iMaxLon</span>
758
758
  <span class="cstat-no" title="statement not covered" > iMaxLon = this.lonCount - 1 - tmp</span>
759
759
  <span class="cstat-no" title="statement not covered" > }</span>
760
- <span class="cstat-no" title="statement not covered" ></span>
761
- <span class="cstat-no" title="statement not covered" > // compute ideal stride according to requested resolution</span>
762
- <span class="cstat-no" title="statement not covered" > const strideLat = Math.max(1, Math.floor(resolution[0] / this.latStep))</span>
763
- <span class="cstat-no" title="statement not covered" > const strideLon = Math.max(1, Math.floor(resolution[1] / this.lonStep))</span>
764
- <span class="cstat-no" title="statement not covered" ></span>
765
- <span class="cstat-no" title="statement not covered" > // eventually adjust iMLax{Lat,Lon} when using a stride != 1</span>
766
- <span class="cstat-no" title="statement not covered" > // this ensure we'll get our initial iMin/iMax range no matter</span>
767
- <span class="cstat-no" title="statement not covered" > // what the stride is</span>
768
- <span class="cstat-no" title="statement not covered" > if (strideLat &gt; 1) {</span>
760
+ &nbsp;
761
+ // compute ideal stride according to requested resolution
762
+ const strideLat = Math.max(1, Math.floor(resolution[0] / this.latStep))
763
+ const strideLon = Math.max(1, Math.floor(resolution[1] / this.lonStep))
764
+ &nbsp;
765
+ // eventually adjust iMLax{Lat,Lon} when using a stride != 1
766
+ // this ensure we'll get our initial iMin/iMax range no matter
767
+ // what the stride is
768
+ if (strideLat &gt; 1) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
769
769
  <span class="cstat-no" title="statement not covered" > iMaxLat = Math.min(this.latCount - 1, iMaxLat + strideLat)</span>
770
770
  <span class="cstat-no" title="statement not covered" > }</span>
771
- <span class="cstat-no" title="statement not covered" > if (strideLon &gt; 1) {</span>
771
+ if (strideLon &gt; 1) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
772
772
  <span class="cstat-no" title="statement not covered" > iMaxLon = Math.min(this.lonCount - 1, iMaxLon + strideLon)</span>
773
773
  <span class="cstat-no" title="statement not covered" > }</span>
774
- <span class="cstat-no" title="statement not covered" ></span>
775
- <span class="cstat-no" title="statement not covered" > // These are indices to index in the opendap variable grid, we're filling the</span>
776
- <span class="cstat-no" title="statement not covered" > // latitude/longitude indices with correct values to cover the requested</span>
777
- <span class="cstat-no" title="statement not covered" > // bounding box with the requested resolution</span>
778
- <span class="cstat-no" title="statement not covered" > const indices = [...this.indices]</span>
779
- <span class="cstat-no" title="statement not covered" > indices[this.latIndex] = `${iMinLat}:${strideLat}:${iMaxLat}`</span>
780
- <span class="cstat-no" title="statement not covered" > indices[this.lonIndex] = `${iMinLon}:${strideLon}:${iMaxLon}`</span>
781
- <span class="cstat-no" title="statement not covered" ></span>
782
- <span class="cstat-no" title="statement not covered" > const conf = {}</span>
783
- <span class="cstat-no" title="statement not covered" > conf[this.config.variable] = indices.join('][')</span>
784
- <span class="cstat-no" title="statement not covered" > return dap.makeQuery(this.config.url, conf)</span>
785
- <span class="cstat-no" title="statement not covered" > }</span>
786
- <span class="cstat-no" title="statement not covered" ></span>
787
- <span class="cstat-no" title="statement not covered" > async computeMetaDataFromData () {</span>
788
- <span class="cstat-no" title="statement not covered" > // Query first and last latitude and longitude</span>
789
- <span class="cstat-no" title="statement not covered" > const query = {}</span>
790
- <span class="cstat-no" title="statement not covered" > query[this.config.latitude] = `0:${this.latCount - 1}:${this.latCount - 1}`</span>
791
- <span class="cstat-no" title="statement not covered" > query[this.config.longitude] = `0:${this.lonCount - 1}:${this.lonCount - 1}`</span>
792
- <span class="cstat-no" title="statement not covered" > const url = dap.makeQuery(this.config.url, query)</span>
793
- <span class="cstat-no" title="statement not covered" > const res = await dap.fetchData(url)</span>
794
- <span class="cstat-no" title="statement not covered" ></span>
795
- <span class="cstat-no" title="statement not covered" > const latData = res[this.config.latitude]</span>
796
- <span class="cstat-no" title="statement not covered" > const lonData = res[this.config.longitude]</span>
797
- <span class="cstat-no" title="statement not covered" ></span>
798
- <span class="cstat-no" title="statement not covered" > const lat0 = latData[0]</span>
799
- <span class="cstat-no" title="statement not covered" > const lat1 = latData[latData.length - 1]</span>
800
- <span class="cstat-no" title="statement not covered" > this.minMaxLat = [Math.min(lat0, lat1), Math.max(lat0, lat1)]</span>
801
- <span class="cstat-no" title="statement not covered" > const lon0 = lonData[0] &gt; 180.0 ? lonData[0] - 360.0 : lonData[0]</span>
802
- <span class="cstat-no" title="statement not covered" > const lon1 = lonData[lonData.length - 1] &gt; 180.0 ? lonData[lonData.length - 1] - 360.0 : lonData[lonData.length - 1]</span>
803
- <span class="cstat-no" title="statement not covered" > this.minMaxLon = [Math.min(lon0, lon1), Math.max(lon0, lon1)]</span>
804
- <span class="cstat-no" title="statement not covered" ></span>
805
- <span class="cstat-no" title="statement not covered" > // grid resolution</span>
806
- <span class="cstat-no" title="statement not covered" > this.latStep = (this.minMaxLat[1] - this.minMaxLat[0]) / (this.latCount - 1)</span>
807
- <span class="cstat-no" title="statement not covered" > this.lonStep = (this.minMaxLon[1] - this.minMaxLon[0]) / (this.lonCount - 1)</span>
808
- <span class="cstat-no" title="statement not covered" ></span>
809
- <span class="cstat-no" title="statement not covered" > // deduce whether lat/lon dimensions are store in ascending or descending order</span>
810
- <span class="cstat-no" title="statement not covered" > this.latSortOrder = lat0 &lt; lat1 ? SortOrder.ASCENDING : SortOrder.DESCENDING</span>
811
- <span class="cstat-no" title="statement not covered" > this.lonSortOrder = lon0 &lt; lon1 ? SortOrder.ASCENDING : SortOrder.DESCENDING</span>
812
- <span class="cstat-no" title="statement not covered" > }</span>
813
- <span class="cstat-no" title="statement not covered" ></span>
814
- <span class="cstat-no" title="statement not covered" > async getDimensionsAsIndices () {</span>
815
- <span class="cstat-no" title="statement not covered" > // config.dimensionsAsIndices contains indices</span>
816
- <span class="cstat-no" title="statement not covered" > // config.dimensionsAsValues contains dimension values for which we</span>
817
- <span class="cstat-no" title="statement not covered" > // need to lookup actual index</span>
818
- <span class="cstat-no" title="statement not covered" ></span>
819
- <span class="cstat-no" title="statement not covered" > const dimensions = {}</span>
820
- <span class="cstat-no" title="statement not covered" > if (this.config.dimensionsAsIndices) {</span>
821
- <span class="cstat-no" title="statement not covered" > Object.assign(dimensions, this.config.dimensionsAsIndices)</span>
822
- <span class="cstat-no" title="statement not covered" > }</span>
823
- <span class="cstat-no" title="statement not covered" > if (this.config.dimensionsAsValues) {</span>
774
+ &nbsp;
775
+ // These are indices to index in the opendap variable grid, we're filling the
776
+ // latitude/longitude indices with correct values to cover the requested
777
+ // bounding box with the requested resolution
778
+ const indices = [...this.indices]
779
+ indices[this.latIndex] = `${iMinLat}:${strideLat}:${iMaxLat}`
780
+ indices[this.lonIndex] = `${iMinLon}:${strideLon}:${iMaxLon}`
781
+ &nbsp;
782
+ const conf = {}
783
+ conf[this.config.variable] = indices.join('][')
784
+ return dap.makeQuery(this.config.url, conf)
785
+ }
786
+ &nbsp;
787
+ async computeMetaDataFromData () {
788
+ // Query first and last latitude and longitude
789
+ const query = {}
790
+ query[this.config.latitude] = `0:${this.latCount - 1}:${this.latCount - 1}`
791
+ query[this.config.longitude] = `0:${this.lonCount - 1}:${this.lonCount - 1}`
792
+ const url = dap.makeQuery(this.config.url, query)
793
+ const res = await dap.fetchData(url)
794
+ &nbsp;
795
+ const latData = res[this.config.latitude]
796
+ const lonData = res[this.config.longitude]
797
+ &nbsp;
798
+ const lat0 = latData[0]
799
+ const lat1 = latData[latData.length - 1]
800
+ this.minMaxLat = [Math.min(lat0, lat1), Math.max(lat0, lat1)]
801
+ const lon0 = lonData[0] &gt; 180.0 <span class="branch-0 cbranch-no" title="branch not covered" >? lonData[0] - 360.0 </span>: lonData[0]
802
+ const lon1 = lonData[lonData.length - 1] &gt; 180.0 <span class="branch-0 cbranch-no" title="branch not covered" >? lonData[lonData.length - 1] - 360.0 </span>: lonData[lonData.length - 1]
803
+ this.minMaxLon = [Math.min(lon0, lon1), Math.max(lon0, lon1)]
804
+ &nbsp;
805
+ // grid resolution
806
+ this.latStep = (this.minMaxLat[1] - this.minMaxLat[0]) / (this.latCount - 1)
807
+ this.lonStep = (this.minMaxLon[1] - this.minMaxLon[0]) / (this.lonCount - 1)
808
+ &nbsp;
809
+ // deduce whether lat/lon dimensions are store in ascending or descending order
810
+ this.latSortOrder = lat0 &lt; lat1 <span class="branch-0 cbranch-no" title="branch not covered" >? SortOrder.ASCENDING </span>: SortOrder.DESCENDING
811
+ this.lonSortOrder = lon0 &lt; lon1 ? SortOrder.ASCENDING <span class="branch-0 cbranch-no" title="branch not covered" >: SortOrder.DESCENDING</span>
812
+ }
813
+ &nbsp;
814
+ async getDimensionsAsIndices () {
815
+ // config.dimensionsAsIndices contains indices
816
+ // config.dimensionsAsValues contains dimension values for which we
817
+ // need to lookup actual index
818
+ &nbsp;
819
+ const dimensions = {}
820
+ if (this.config.dimensionsAsIndices) {
821
+ Object.assign(dimensions, this.config.dimensionsAsIndices)
822
+ }
823
+ if (this.config.dimensionsAsValues) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
824
824
  <span class="cstat-no" title="statement not covered" > // build a request to query the values for each dimension for which we have a value</span>
825
825
  <span class="cstat-no" title="statement not covered" > // const requested = _.keys(this.config.dimensionsAsValues)</span>
826
826
  <span class="cstat-no" title="statement not covered" > const variables = _.keys(this.config.dimensionsAsValues)</span>
@@ -842,10 +842,10 @@
842
842
  <span class="cstat-no" title="statement not covered" > dimensions[variables[i]] = valueIndex</span>
843
843
  <span class="cstat-no" title="statement not covered" > }</span>
844
844
  <span class="cstat-no" title="statement not covered" > }</span>
845
- <span class="cstat-no" title="statement not covered" ></span>
846
- <span class="cstat-no" title="statement not covered" > return dimensions</span>
847
- <span class="cstat-no" title="statement not covered" > }</span>
848
- <span class="cstat-no" title="statement not covered" >}</span>
845
+ &nbsp;
846
+ return dimensions
847
+ }
848
+ }
849
849
  &nbsp;</pre></td></tr></table></pre>
850
850
 
851
851
  <div class='push'></div><!-- for sticky footer -->
@@ -853,7 +853,7 @@
853
853
  <div class='footer quiet pad2 space-top1 center small'>
854
854
  Code coverage generated by
855
855
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
856
- at 2025-02-18T09:52:45.637Z
856
+ at 2025-07-24T10:00:20.508Z
857
857
  </div>
858
858
  <script src="../../prettify.js"></script>
859
859
  <script>