@kalisio/kdk 2.1.9 → 2.2.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 (243) hide show
  1. package/.travis.test.sh +42 -10
  2. package/README.md +2 -2
  3. package/core/api/application.js +6 -1
  4. package/core/api/authentication.js +17 -1
  5. package/core/api/db.js +7 -2
  6. package/core/api/hooks/hooks.authentication.js +4 -2
  7. package/core/api/hooks/hooks.authorisations.js +12 -2
  8. package/core/api/hooks/hooks.model.js +5 -5
  9. package/core/api/hooks/hooks.organisations.js +0 -4
  10. package/core/api/services/account/account.hooks.js +10 -6
  11. package/core/api/services/account/account.service.js +1 -1
  12. package/{map/api/services/geocoder/geocoder.hooks.js → core/api/services/import-export/import-export.hooks.js} +7 -5
  13. package/core/api/services/import-export/import-export.service.js +11 -0
  14. package/core/api/services/index.js +13 -1
  15. package/core/api/services/users/users.hooks.js +2 -3
  16. package/core/client/api.js +16 -14
  17. package/core/client/capabilities.js +6 -2
  18. package/core/client/components/KContent.vue +11 -1
  19. package/core/client/components/KDialog.vue +17 -15
  20. package/core/client/components/KSponsor.vue +1 -1
  21. package/core/client/components/KTextArea.vue +5 -1
  22. package/core/client/components/app/KAbout.vue +1 -2
  23. package/core/client/components/app/KWelcome.vue +3 -5
  24. package/core/client/components/chart/KTimeSeriesChart.vue +24 -37
  25. package/core/client/components/collection/KColumn.vue +20 -17
  26. package/core/client/components/editor/KModalEditor.vue +0 -2
  27. package/core/client/components/form/KChipsField.vue +12 -2
  28. package/core/client/components/form/KColorField.vue +12 -2
  29. package/core/client/components/form/KColorScaleField.vue +12 -2
  30. package/core/client/components/form/KDateTimeRangeField.vue +12 -2
  31. package/core/client/components/form/KDatetimeField.vue +12 -2
  32. package/core/client/components/form/KEmailField.vue +12 -2
  33. package/core/client/components/form/KFileField.vue +12 -2
  34. package/core/client/components/form/KForm.vue +43 -9
  35. package/core/client/components/form/KIconField.vue +12 -2
  36. package/core/client/components/form/KItemField.vue +25 -4
  37. package/core/client/components/form/KNumberField.vue +12 -2
  38. package/core/client/components/form/KOptionsField.vue +12 -2
  39. package/core/client/components/form/KPasswordField.vue +12 -2
  40. package/core/client/components/form/KPhoneField.vue +13 -3
  41. package/core/client/components/form/KPropertyItemField.vue +12 -2
  42. package/core/client/components/form/KResolutionField.vue +126 -0
  43. package/core/client/components/form/KRoleField.vue +12 -2
  44. package/core/client/components/form/KSelectField.vue +14 -4
  45. package/core/client/components/form/KTextField.vue +12 -2
  46. package/core/client/components/form/KTextareaField.vue +13 -3
  47. package/core/client/components/form/KToggleField.vue +12 -2
  48. package/core/client/components/form/KTokenField.vue +12 -2
  49. package/core/client/components/form/KUnitField.vue +12 -2
  50. package/core/client/components/form/KUrlField.vue +12 -2
  51. package/core/client/components/input/KIconChooser.vue +10 -12
  52. package/core/client/components/input/KPalette.vue +2 -1
  53. package/core/client/components/layout/KPage.vue +5 -4
  54. package/core/client/components/layout/KWindow.vue +10 -10
  55. package/core/client/components/media/KColorScale.vue +26 -20
  56. package/core/client/components/media/KImageViewer.vue +57 -33
  57. package/core/client/components/media/KShape.vue +14 -103
  58. package/core/client/components/screen/KRegisterScreen.vue +0 -1
  59. package/core/client/components/screen/KScreenFooter.vue +0 -18
  60. package/core/client/components/team/KAddMember.vue +16 -22
  61. package/core/client/components/team/KGroupsActivity.vue +14 -0
  62. package/core/client/components/team/KMembersActivity.vue +12 -0
  63. package/core/client/components/team/KTagsActivity.vue +14 -0
  64. package/core/client/components/time/KDateTime.vue +23 -7
  65. package/core/client/components/time/KTimeControl.vue +142 -0
  66. package/core/client/components/tool/KExportTool.vue +57 -0
  67. package/core/client/composables/collection.js +0 -1
  68. package/core/client/composables/pwa.js +0 -1
  69. package/core/client/composables/schema.js +1 -1
  70. package/core/client/composables/session.js +30 -6
  71. package/core/client/exporter.js +141 -0
  72. package/core/client/i18n/core_en.json +91 -23
  73. package/core/client/i18n/core_fr.json +92 -23
  74. package/core/client/index.js +3 -0
  75. package/core/client/layout.js +34 -14
  76. package/core/client/local-storage.js +8 -6
  77. package/core/client/mixins/index.js +0 -1
  78. package/core/client/mixins/mixin.base-field.js +24 -2
  79. package/core/client/mixins/mixin.object-proxy.js +0 -1
  80. package/core/client/search.js +2 -1
  81. package/core/client/services/index.js +2 -1
  82. package/core/client/services/local-settings.service.js +4 -4
  83. package/core/client/theme.js +3 -3
  84. package/core/client/time.js +4 -0
  85. package/core/client/units.js +149 -4
  86. package/core/client/utils/index.js +13 -6
  87. package/core/client/utils/utils.account.js +1 -1
  88. package/core/client/utils/utils.colors.js +43 -0
  89. package/core/client/utils/utils.platform.js +0 -1
  90. package/core/client/utils/utils.pwa.js +14 -14
  91. package/core/client/utils/utils.session.js +1 -1
  92. package/core/client/utils/utils.shapes.js +270 -0
  93. package/core/client/utils/utils.time.js +37 -0
  94. package/core/common/permissions.js +3 -0
  95. package/core/common/schemas/settings.update.json +50 -29
  96. package/extras/css/core.variables.scss +3 -1
  97. package/extras/tours/map/navigation-bar.js +17 -15
  98. package/extras/tours/map/timeline.js +33 -33
  99. package/map/api/config/categories.cjs +4 -1
  100. package/map/api/hooks/hooks.catalog.js +39 -0
  101. package/map/api/hooks/hooks.features.js +23 -3
  102. package/map/api/hooks/hooks.query.js +31 -10
  103. package/map/api/models/projects.model.mongodb.js +8 -0
  104. package/map/api/services/catalog/catalog.hooks.js +5 -3
  105. package/map/api/services/features/features.hooks.js +18 -6
  106. package/map/api/services/index.js +22 -6
  107. package/map/api/services/projects/projects.hooks.js +118 -0
  108. package/map/client/capture.js +16 -0
  109. package/map/client/cesium/utils/index.js +3 -0
  110. package/map/client/cesium/utils/utils.events.js +30 -0
  111. package/map/client/cesium/utils/utils.popup.js +17 -0
  112. package/map/client/cesium/{utils.js → utils/utils.style.js} +53 -49
  113. package/map/client/components/KCapture.vue +50 -0
  114. package/map/client/components/KCaptureTextArea.vue +53 -0
  115. package/map/client/components/KCompass.vue +2 -2
  116. package/map/client/components/KFeaturesChart.vue +1 -1
  117. package/map/client/components/KFeaturesFilter.vue +2 -2
  118. package/map/client/components/KLayerStyleForm.vue +256 -430
  119. package/map/client/components/KLevelSlider.vue +1 -1
  120. package/map/client/components/KNorth.vue +31 -0
  121. package/map/client/components/KProjectMenu.vue +88 -0
  122. package/map/client/components/KTimezoneMap.vue +36 -23
  123. package/map/client/components/catalog/KAddLayer.vue +3 -4
  124. package/map/client/components/catalog/KConnectLayer.vue +16 -4
  125. package/map/client/components/catalog/KCreateLayer.vue +1 -2
  126. package/map/client/components/catalog/KCreateProject.vue +100 -0
  127. package/map/client/components/catalog/KCreateView.vue +25 -2
  128. package/map/client/components/catalog/KLayersPanel.vue +24 -27
  129. package/map/client/components/catalog/KLayersSelector.vue +1 -1
  130. package/map/client/components/catalog/KProjectEditor.vue +91 -0
  131. package/map/client/components/catalog/KProjectManager.vue +60 -0
  132. package/map/client/components/catalog/KProjectSelector.vue +38 -0
  133. package/map/client/components/catalog/KProjectsPanel.vue +153 -0
  134. package/map/client/components/catalog/KSelectLayers.vue +96 -0
  135. package/map/client/components/catalog/KSelectViews.vue +96 -0
  136. package/map/client/components/catalog/KViewsPanel.vue +66 -30
  137. package/map/client/components/form/KDirectionField.vue +24 -5
  138. package/map/client/components/form/KLayerCategoryField.vue +12 -2
  139. package/map/client/components/form/KLocationField.vue +20 -5
  140. package/map/client/components/form/KOwsLayerField.vue +12 -2
  141. package/map/client/components/form/KOwsServiceField.vue +12 -2
  142. package/map/client/components/form/KSelectLayersField.vue +159 -0
  143. package/map/client/components/form/KSelectViewsField.vue +121 -0
  144. package/map/client/components/form/KTimezoneField.vue +24 -17
  145. package/map/client/components/legend/KColorScaleLegend.vue +1 -1
  146. package/map/client/components/legend/KLayerLegend.vue +61 -0
  147. package/map/client/components/legend/KLegend.vue +45 -44
  148. package/map/client/components/legend/KLegendRenderer.vue +5 -3
  149. package/map/client/components/legend/KSymbolsLegend.vue +12 -10
  150. package/map/client/components/legend/KVariablesLegend.vue +78 -0
  151. package/map/client/components/location/KGeocodersFilter.vue +2 -4
  152. package/map/client/components/location/KLocationMap.vue +48 -17
  153. package/map/client/components/location/KLocationSearch.vue +13 -3
  154. package/map/client/components/tools/KSearchTool.vue +17 -12
  155. package/map/client/components/widget/KElevationProfile.vue +16 -19
  156. package/map/client/components/widget/KMapillaryViewer.vue +21 -22
  157. package/map/client/components/widget/KTimeSeries.vue +35 -23
  158. package/map/client/composables/activity.js +15 -2
  159. package/map/client/composables/catalog.js +66 -0
  160. package/map/client/composables/highlight.js +56 -20
  161. package/map/client/composables/index.js +2 -0
  162. package/map/client/composables/location.js +25 -18
  163. package/map/client/composables/project.js +122 -0
  164. package/map/client/geolocation.js +1 -1
  165. package/map/client/globe.js +2 -0
  166. package/map/client/i18n/map_en.json +123 -76
  167. package/map/client/i18n/map_fr.json +124 -72
  168. package/map/client/index.js +3 -0
  169. package/map/client/init.js +17 -0
  170. package/map/client/leaflet/GSMaPLayer.js +16 -17
  171. package/map/client/leaflet/ShapeMarker.js +40 -0
  172. package/map/client/leaflet/TiledFeatureLayer.js +1 -1
  173. package/map/client/leaflet/TiledMeshLayer.js +11 -15
  174. package/map/client/leaflet/TiledWindLayer.js +6 -10
  175. package/map/client/leaflet/utils/index.js +4 -0
  176. package/map/client/leaflet/utils/utils.events.js +41 -0
  177. package/map/client/leaflet/utils/utils.popup.js +21 -0
  178. package/map/client/leaflet/utils/utils.style.js +191 -0
  179. package/map/client/leaflet/utils/utils.tiles.js +87 -0
  180. package/map/client/map.js +2 -0
  181. package/map/client/mixins/globe/mixin.base-globe.js +29 -21
  182. package/map/client/mixins/globe/mixin.geojson-layers.js +132 -69
  183. package/map/client/mixins/globe/mixin.popup.js +2 -1
  184. package/map/client/mixins/globe/mixin.style.js +6 -4
  185. package/map/client/mixins/globe/mixin.tooltip.js +8 -3
  186. package/map/client/mixins/map/mixin.base-map.js +13 -11
  187. package/map/client/mixins/map/mixin.edit-layers.js +15 -15
  188. package/map/client/mixins/map/mixin.forecast-layers.js +3 -1
  189. package/map/client/mixins/map/mixin.geojson-layers.js +56 -20
  190. package/map/client/mixins/map/mixin.georaster-layers.js +4 -11
  191. package/map/client/mixins/map/mixin.heatmap-layers.js +1 -1
  192. package/map/client/mixins/map/mixin.popup.js +2 -1
  193. package/map/client/mixins/map/mixin.style.js +4 -67
  194. package/map/client/mixins/map/mixin.tiled-mesh-layers.js +2 -1
  195. package/map/client/mixins/map/mixin.tiled-wind-layers.js +4 -2
  196. package/map/client/mixins/map/mixin.tooltip.js +2 -1
  197. package/map/client/mixins/mixin.activity.js +66 -191
  198. package/map/client/mixins/mixin.catalog-panel.js +6 -6
  199. package/map/client/mixins/mixin.context.js +12 -9
  200. package/map/client/mixins/mixin.feature-service.js +29 -300
  201. package/map/client/mixins/mixin.weacast.js +11 -17
  202. package/map/client/pixi-utils.js +1 -1
  203. package/map/client/planets.js +58 -0
  204. package/map/client/utils/index.js +6 -0
  205. package/map/client/utils/utils.capture.js +176 -0
  206. package/map/client/utils/utils.catalog.js +149 -0
  207. package/map/client/utils/utils.features.js +364 -0
  208. package/map/client/utils/utils.js +0 -151
  209. package/map/client/utils/utils.layers.js +174 -0
  210. package/map/client/utils/utils.location.js +91 -23
  211. package/map/client/utils/utils.project.js +8 -0
  212. package/map/client/utils/utils.schema.js +0 -1
  213. package/map/client/utils/utils.style.js +297 -0
  214. package/map/client/utils.all.js +2 -2
  215. package/map/client/utils.globe.js +1 -1
  216. package/map/client/utils.map.js +1 -1
  217. package/map/common/permissions.js +2 -0
  218. package/map/common/schemas/capture.create.json +132 -0
  219. package/map/common/schemas/projects.create.json +52 -0
  220. package/map/common/schemas/projects.update.json +52 -0
  221. package/package.json +6 -5
  222. package/test/api/core/account.test.js +20 -0
  223. package/test/api/core/config/default.cjs +16 -3
  224. package/test/api/core/import-export.test.js +86 -0
  225. package/test/api/core/test-log-2024-01-04.log +14 -0
  226. package/test/api/map/catalog.test.js +164 -0
  227. package/test/api/map/index.test.js +25 -61
  228. package/test/api/map/test-log-2024-01-04.log +2 -0
  229. package/test/api/map/test-log-2024-01-11.log +1 -0
  230. package/test/api/map/test-log-2024-01-25.log +19 -0
  231. package/test/client/core/layout.js +25 -5
  232. package/test/client/core/utils.js +7 -0
  233. package/test/client/map/catalog.js +78 -1
  234. package/test/client/map/time.js +2 -1
  235. package/core/client/components/screen/KEndpointScreen.vue +0 -80
  236. package/core/client/mixins/mixin.account.js +0 -61
  237. package/extras/icons/kdk.png +0 -0
  238. package/map/api/services/geocoder/geocoder.service.js +0 -79
  239. package/map/client/components/KCaptureToolbar.vue +0 -155
  240. package/map/client/components/KColorLegend.vue +0 -349
  241. package/map/client/components/KTimeline.vue +0 -293
  242. package/map/client/components/KUrlLegend.vue +0 -122
  243. package/map/client/leaflet/utils.js +0 -246
@@ -0,0 +1,41 @@
1
+ // Get the unique global symbol to store event listeners on a leaflet object
2
+ const LISTENERS_KEY = Symbol.for('leaflet-event-listeners')
3
+
4
+ // Bind a set of events on given Leaflet object to a vue component
5
+ export function bindLeafletEvents (object, events, component, options) {
6
+ object[LISTENERS_KEY] = []
7
+ events.forEach(eventName => {
8
+ const listener = (...args) => {
9
+ if (options) component.$engineEvents.emit(eventName, options, ...args)
10
+ else component.$engineEvents.emit(eventName, ...args)
11
+ }
12
+ object[LISTENERS_KEY].push(listener)
13
+ object.on(eventName, listener)
14
+ })
15
+ }
16
+
17
+ export function unbindLeafletEvents (object, events) {
18
+ const listeners = object[LISTENERS_KEY]
19
+ if (listeners) {
20
+ events.forEach((eventName, index) => {
21
+ object.off(eventName, object[LISTENERS_KEY][index])
22
+ })
23
+ delete object[LISTENERS_KEY]
24
+ }
25
+ }
26
+
27
+ export const LeafletEvents = {
28
+ Map: ['baselayerchange', 'overlayadd', 'overlayremove', 'layeradd', 'layerremove', 'zoomlevelschange',
29
+ 'resize', 'unload', 'viewreset', 'load',
30
+ 'zoomstart', 'boxzoomstart', 'boxselectionstart', 'movestart',
31
+ 'zoom', 'move',
32
+ 'zoomend', 'boxzoomend', 'boxselectionend', 'moveend',
33
+ 'click', 'dblclick', 'mousedown', 'mouseup', 'mouseover', 'mouseout', 'mousemove', 'contextmenu',
34
+ 'keypress', 'preclick', 'moveend', 'zoomanim', 'fullscreenchange'],
35
+ Popup: ['add', 'remove'],
36
+ Tooltip: ['add', 'remove'],
37
+ Layer: ['add', 'remove', 'popupopen', 'popupclose', 'tooltipopen', 'tooltipclose'],
38
+ Feature: ['click', 'dblclick', 'mousedown', 'mouseup', 'mouseover', 'mouseout', 'contextmenu',
39
+ 'dragstart', 'dragend', 'drag', 'movestart', 'moveend', 'move'],
40
+ Cluster: ['spiderfied', 'unspiderfied']
41
+ }
@@ -0,0 +1,21 @@
1
+ import _ from 'lodash'
2
+ import { utils as kdkCoreUtils } from '../../../../core/client/index.js'
3
+
4
+ export function getHtmlTable (properties) {
5
+ properties = kdkCoreUtils.dotify(properties)
6
+ properties = _.pickBy(properties, value => !_.isNil(value))
7
+ const keys = _.keys(properties)
8
+ let html
9
+ if (keys.length === 0) return null
10
+ else if (keys.length === 1) html = _.get(properties, keys[0])
11
+ else {
12
+ const borderStyle = ' style="border: 1px solid black; border-collapse: collapse;"'
13
+ html = '<table' + borderStyle + '>'
14
+ html += keys
15
+ .map(key => '<tr' + borderStyle + '><th' +
16
+ borderStyle + '>' + key + '</th><th>' + _.get(properties, key) + '</th></tr>')
17
+ .join('')
18
+ html += '</table>'
19
+ }
20
+ return html
21
+ }
@@ -0,0 +1,191 @@
1
+ import _ from 'lodash'
2
+ import logger from 'loglevel'
3
+ import chroma from 'chroma-js'
4
+ import moment from 'moment'
5
+ import L from 'leaflet'
6
+ import { Time, Units, utils as kdkCoreUtils } from '../../../../core/client/index.js'
7
+ import { convertStyle, convertSimpleStyleToPointStyle, convertSimpleStyleToLineStyle, convertSimpleStyleToPolygonStyle,
8
+ PointStyleTemplateMappings, LineStyleTemplateMappings, PolygonStyleTemplateMappings } from '../../utils/utils.style.js'
9
+ import { ShapeMarker } from '../ShapeMarker.js'
10
+
11
+ L.shapeMarker = function (latlng, options) {
12
+ return new ShapeMarker(latlng, options)
13
+ }
14
+
15
+ export const LeafletStyleMappings = {
16
+ 'z-index': 'pane',
17
+ pane: 'pane',
18
+ stroke: 'color',
19
+ 'stroke-color': 'color',
20
+ 'stroke-opacity': 'opacity',
21
+ 'stroke-width': 'weight',
22
+ fill: 'fillColor',
23
+ 'fill-opacity': 'fillOpacity',
24
+ 'fill-color': 'fillColor',
25
+ weight: 'weight',
26
+ radius: 'radius',
27
+ 'line-cap': 'lineCap',
28
+ 'line-join': 'lineJoin',
29
+ 'dash-array': 'dashArray',
30
+ 'dash-offset': 'dashOffset',
31
+ 'marker-symbol': 'style.point.shape',
32
+ 'marker-size': 'style.point.size',
33
+ 'marker-color': 'style.point.color',
34
+ 'marker-anchor': 'style.point.anchor',
35
+ 'icon-url': 'style.point.icon.url',
36
+ 'icon-html': 'style.point.html',
37
+ 'icon-color': 'style.point.icon.color',
38
+ 'icon-size': 'style.point.icon.size',
39
+ 'icon-anchor': 'style.point.anchor',
40
+ 'icon-class': 'style.point.icon.classes',
41
+ 'icon-opacity': 'style.point.icon.opacity',
42
+ 'icon-classes': 'style.point.icon.classes',
43
+ 'icon-x-offset': 'style.point.icon.xOffset',
44
+ 'icon-y-offset': 'style.point.icon.yOffset',
45
+ 'style-line-color': 'color',
46
+ 'style-line-width': 'weight',
47
+ 'style-line-opacity': 'opacity',
48
+ 'style-line-cap': 'lineCap',
49
+ 'style-line-join': 'lineJoin',
50
+ 'style-line-dash-array': 'dashArray',
51
+ 'style-line-dash-offset': 'dashOffset',
52
+ 'style-polygon-color': 'fillColor',
53
+ 'style-polygon-opacity': 'fillOpacity',
54
+ 'style-polygon-rule': 'fillRule',
55
+ 'style-polygon-stroke-color': 'color',
56
+ 'style-polygon-stroke-width': 'weight',
57
+ 'style-polygon-stroke-opacity': 'opacity',
58
+ 'style-polygon-stroke-cap': 'lineCap',
59
+ 'style-polygon-stroke-join': 'lineJoin',
60
+ 'style-polygon-stroke-dash-array': 'dashArray',
61
+ 'style-polygon-stroke-dash-offset': 'dashOffset'
62
+ }
63
+
64
+ const LineStyleToLeafletPath = {
65
+ color: 'color',
66
+ width: 'weight',
67
+ opacity: 'opacity',
68
+ cap: 'lineCap',
69
+ join: 'lineJoin',
70
+ dashArray: 'dashArray',
71
+ dashOffset: 'dashOffset'
72
+ }
73
+
74
+ const PolygonStyleToLeafletPath = {
75
+ color: 'fillColor',
76
+ opacity: 'fillOpacity',
77
+ rule: 'fillRule',
78
+ }
79
+
80
+ // TODO: to be removed when updating 3D style
81
+ export function convertToLeafletFromSimpleStyleSpec (style, inPlace) {
82
+ if (!style) return {}
83
+ const leafletStyle = (inPlace ? style : {})
84
+ // Compute flags first because if updating in place options in style spec will be replaced
85
+ let isIconSpec = _.has(style, 'icon')
86
+ // First copy any icon spec as not supported by simple style spec
87
+ if (isIconSpec) _.set(leafletStyle, 'icon', _.get(style, 'icon'))
88
+ _.forOwn(style, (value, key) => {
89
+ if (_.has(LeafletStyleMappings, key)) {
90
+ const mapping = _.get(LeafletStyleMappings, key)
91
+ // Specific options
92
+ switch (key) {
93
+ case 'marker-size':
94
+ case 'marker-anchor':
95
+ case 'icon-anchor':
96
+ if (!Array.isArray(value)) value = [value, value]
97
+ _.set(leafletStyle, mapping, value)
98
+ break
99
+ default:
100
+ _.set(leafletStyle, mapping, value)
101
+ }
102
+ if (inPlace) _.unset(style, key)
103
+ // In this case we have a marker with icon spec
104
+ if (mapping.startsWith('icon')) isIconSpec = true
105
+ }
106
+ })
107
+ if (isIconSpec) {
108
+ // Select the right marker type based on icon properties if not already set
109
+ if (!_.has(style, 'marker.type')) {
110
+ if (_.has(style, 'icon-url') || _.has(style, 'icon-html')) _.set(leafletStyle, 'type', 'marker')
111
+ else if (_.has(style, 'icon-classes')) _.set(leafletStyle, 'type', 'shapeMarker')
112
+ }
113
+ }
114
+ // Manage panes to make z-index work for all types of layers,
115
+ // pane name can actually be a z-index value
116
+ if (_.has(leafletStyle, 'pane')) _.set(leafletStyle, 'pane', _.get(leafletStyle, 'pane').toString())
117
+ if (_.has(leafletStyle, 'shadowPane')) _.set(leafletStyle, 'shadowPane', _.get(leafletStyle, 'shadowPane').toString())
118
+ return leafletStyle
119
+ }
120
+
121
+ export function createMarkerFromPointStyle (latlng, style) {
122
+ if (!latlng) {
123
+ logger.warn(`[KDK] 'latlng' should be defined`)
124
+ return
125
+ }
126
+ return L.shapeMarker(latlng, style)
127
+ }
128
+
129
+ export function convertLineStyleToLeafletPath (style) {
130
+ if (!style) return
131
+ let leafletStyle = convertStyle(style, LineStyleToLeafletPath)
132
+ // handle quasar color/default if needed
133
+ leafletStyle.color = kdkCoreUtils.getHtmlColor(leafletStyle.color, 'black')
134
+ return leafletStyle
135
+ }
136
+
137
+ export function convertPolygonStyleToLeafletPath (style) {
138
+ if (!style) return
139
+ let leafletStyle = convertStyle(style, PolygonStyleToLeafletPath)
140
+ Object.assign(leafletStyle, convertLineStyleToLeafletPath(style.stroke))
141
+ // handle quasar/default color if needed
142
+ leafletStyle.fillColor = kdkCoreUtils.getHtmlColor(leafletStyle.fillColor, 'black')
143
+ return leafletStyle
144
+ }
145
+
146
+ function processStyle (style, feature, options, mappings) {
147
+ if (!options) return
148
+ const leafletOptions = options.leaflet || options
149
+ // We allow to template style properties according to feature,
150
+ // because it can be slow you have to specify a subset of properties
151
+ const context = { properties: feature.properties, feature, chroma, moment, Units, Time }
152
+ if (leafletOptions.template) {
153
+ // Create the map of variables
154
+ if (options.variables) context.variables = _.reduce(options.variables,
155
+ (result, variable) => Object.assign(result, { [variable.name]: variable }), {})
156
+ leafletOptions.template.forEach(entry => {
157
+ _.set(style, _.get(mappings, _.kebabCase(entry.property), entry.property), entry.compiler(context))
158
+ })
159
+ }
160
+ // We manage panes for z-index, so we need to forward it to marker options (only if not already defined)
161
+ if (leafletOptions.pane && !style.pane) style.pane = leafletOptions.pane
162
+ if (leafletOptions.shadowPane && !style.shadowPane) style.shadowPane = leafletOptions.shadowPane
163
+ return style
164
+ }
165
+
166
+ export function getDefaultPointStyle (feature, options, engine, engineStylePath = 'style.point') {
167
+ const engineStyle = _.get(engine, engineStylePath, {})
168
+ const layerStyle = options ? _.get(options.leaflet || options, 'layerPointStyle') : {}
169
+ const featureStyle = feature.style ? _.get(feature, 'style', {}) : convertSimpleStyleToPointStyle(feature.properties)
170
+ const style = Object.assign({}, engineStyle, layerStyle, featureStyle)
171
+ processStyle({ style: { point: style } }, feature, options, PointStyleTemplateMappings)
172
+ return style
173
+ }
174
+
175
+ export function getDefaultLineStyle (feature, options, engine, engineStylePath = 'style.line') {
176
+ const engineStyle = _.get(engine, engineStylePath, {})
177
+ const layerStyle = options ? _.get(options.leaflet || options, 'layerLineStyle') : {}
178
+ const featureStyle = feature.style ? _.get(feature, 'style', {}) : convertSimpleStyleToLineStyle(feature.properties)
179
+ const style = Object.assign({}, engineStyle, layerStyle, featureStyle)
180
+ processStyle({ style: { line: style } }, feature, options, LineStyleTemplateMappings)
181
+ return convertLineStyleToLeafletPath(style)
182
+ }
183
+
184
+ export function getDefaultPolygonStyle (feature, options, engine, engineStylePath = 'style.polygon') {
185
+ const engineStyle = _.get(engine, engineStylePath, {})
186
+ const layerStyle = options ? _.get(options.leaflet || options, 'layerPolygonStyle') : {}
187
+ const featureStyle = feature.style ? _.get(feature, 'style', {}) : convertSimpleStyleToPolygonStyle(feature.properties)
188
+ const style = Object.assign({}, engineStyle, layerStyle, featureStyle)
189
+ processStyle({ style: { polygon: style } }, feature, options, PolygonStyleTemplateMappings)
190
+ return convertPolygonStyleToLeafletPath(style)
191
+ }
@@ -0,0 +1,87 @@
1
+ export function tile2key (coords) {
2
+ // JS Number.MAX_SAFE_INTEGER = 2^53 - 1, so 53 bits available
3
+ // put z value on 5 bits (0 - 32)
4
+ // put y value on 24 bits (0 - 16777216)
5
+ // put x value on 24 bits (0 - 16777216)
6
+ // shift y by 5 bits (* 32)
7
+ // shift x by 5+24 bits (* 536870912)
8
+ return (coords.x * 536870912) + (coords.y * 32) + coords.z
9
+ }
10
+
11
+ export function key2tile (key) {
12
+ // JS Number.MAX_SAFE_INTEGER = 2^53 - 1, so 53 bits available
13
+ // put z value on 5 bits (0 - 32)
14
+ // put y value on 24 bits (0 - 16777216)
15
+ // put x value on 24 bits (0 - 16777216)
16
+ // shift y by 5 bits (* 32)
17
+ // shift x by 5+24 bits (* 536870912)
18
+ const x = Math.floor(key / 536870912)
19
+ const y = Math.floor((key - (x * 536870912)) / 32)
20
+ const p = L.point(x, y)
21
+ p.z = key - ((x * 536870912) + (y * 32))
22
+ return p
23
+ }
24
+
25
+ export function tileSetContainsParent (tileset, coords) {
26
+ const triplet = {
27
+ x: coords.x,
28
+ y: coords.y,
29
+ z: coords.z
30
+ }
31
+ while (triplet.z > 1) {
32
+ const tilekey = tile2key(triplet)
33
+ if (tileset.has(tilekey)) return true
34
+ triplet.x = Math.floor(triplet.x / 2)
35
+ triplet.y = Math.floor(triplet.y / 2)
36
+ triplet.z -= 1
37
+ }
38
+ return false
39
+ }
40
+
41
+ export function getParentTileInTileSet (tileset, coords) {
42
+ const triplet = {
43
+ x: coords.x,
44
+ y: coords.y,
45
+ z: coords.z
46
+ }
47
+
48
+ triplet.x = Math.floor(triplet.x / 2)
49
+ triplet.y = Math.floor(triplet.y / 2)
50
+ triplet.z -= 1
51
+
52
+ while (triplet.z > 1) {
53
+ const tilekey = tile2key(triplet)
54
+ if (tileset.has(tilekey)) return triplet
55
+
56
+ triplet.x = Math.floor(triplet.x / 2)
57
+ triplet.y = Math.floor(triplet.y / 2)
58
+ triplet.z -= 1
59
+ }
60
+
61
+ return undefined
62
+ }
63
+
64
+ export function computeIdealMaxNativeZoom (gridLayer, dataSetBounds, dataSetTileSize) {
65
+ // compute optimal maxNativeZoom value to ensure
66
+ // the smallest leaflet tile will approximately match a dataset tile
67
+
68
+ // compute tile size farthest from equator
69
+ const nw = dataSetBounds.getNorthWest()
70
+ let z = 1
71
+ while (true) {
72
+ const nwPoint = gridLayer._map.project(nw, z)
73
+ const coords = nwPoint.unscaleBy(gridLayer.getTileSize())
74
+ coords.x = Math.floor(coords.x)
75
+ coords.y = Math.floor(coords.y)
76
+ coords.z = z
77
+
78
+ const tileBounds = gridLayer._tileCoordsToBounds(coords)
79
+ const tileWidth = tileBounds.getEast() - tileBounds.getWest()
80
+ const tileHeight = tileBounds.getNorth() - tileBounds.getSouth()
81
+ if (tileWidth < dataSetTileSize.lng || tileHeight < dataSetTileSize.lat) break
82
+
83
+ z += 1
84
+ }
85
+
86
+ return Math.max(1, z - 1)
87
+ }
package/map/client/map.js CHANGED
@@ -7,9 +7,11 @@ import init from './init.js'
7
7
  const mixins = Object.assign({}, commonMixins, { map: mapMixins })
8
8
 
9
9
  export * from './geolocation.js'
10
+ export * from './planets.js'
10
11
  export { utils }
11
12
  export { composables }
12
13
  export { mixins }
13
14
  export * from '../common/index.js'
15
+ export * from './init.js'
14
16
 
15
17
  export default init
@@ -8,7 +8,7 @@ import Cesium from 'cesium/Source/Cesium.js'
8
8
  import 'cesium/Source/Widgets/widgets.css'
9
9
  import BuildModuleUrl from 'cesium/Source/Core/buildModuleUrl.js'
10
10
  import { Geolocation } from '../../geolocation.js'
11
- import { convertCesiumHandlerEvent } from '../../utils.globe.js'
11
+ import { convertCesiumHandlerEvent, isTerrainLayer } from '../../utils.globe.js'
12
12
  // Cesium has its own dynamic module loader requiring to be configured
13
13
  // Cesium files need to be also added as static assets of the applciation
14
14
  BuildModuleUrl.setBaseUrl('/Cesium/')
@@ -81,13 +81,17 @@ export const baseGlobe = {
81
81
  processedOptions.cesium.attribution = processedOptions.attribution
82
82
  return processedOptions
83
83
  },
84
- isTerrainLayer (options) {
85
- return (options.type === 'Cesium') || (options.type === 'Ellipsoid')
86
- },
87
84
  createCesiumLayer (options) {
88
85
  const cesiumOptions = options.cesium || options
86
+ if (cesiumOptions.type === '3DTileset') {
87
+ const convertedOptions = this.convertToCesiumObjects(cesiumOptions)
88
+ const tileset = new Cesium.Cesium3DTileset(_.omit(convertedOptions, ['style']))
89
+ // Not possible to get style as constructor options
90
+ if (_.has(convertedOptions, 'style')) tileset.style = _.get(convertedOptions, 'style')
91
+ return tileset
92
+ }
89
93
  let provider
90
- if (this.isTerrainLayer(cesiumOptions)) {
94
+ if (isTerrainLayer(cesiumOptions)) {
91
95
  if (cesiumOptions.url || (cesiumOptions.type === 'Ellipsoid')) provider = cesiumOptions.type + 'TerrainProvider'
92
96
  // If no url given will use default terrain creation function createWorldTerrain()
93
97
  else provider = 'WorldTerrain'
@@ -96,9 +100,10 @@ export const baseGlobe = {
96
100
  }
97
101
  // Handle specific case of built-in creation functions
98
102
  const createFunction = 'create' + provider
99
- provider = (Cesium[createFunction] ? Cesium[createFunction](cesiumOptions) : new Cesium[provider](cesiumOptions))
103
+ if (Cesium[provider]) provider = new Cesium[provider](cesiumOptions)
104
+ else provider = Cesium[createFunction](cesiumOptions)
100
105
  // Terrain is directly managed using a provider
101
- return (this.isTerrainLayer(cesiumOptions) ? provider : new Cesium.ImageryLayer(provider))
106
+ return (isTerrainLayer(cesiumOptions) ? provider : new Cesium.ImageryLayer(provider))
102
107
  },
103
108
  registerCesiumConstructor (constructor) {
104
109
  this.cesiumFactory.push(constructor)
@@ -134,7 +139,7 @@ export const baseGlobe = {
134
139
  const layer = this.getLayerByName(name)
135
140
  if (!layer) return false
136
141
  const cesiumLayer = this.getCesiumLayerByName(name)
137
- if (this.isTerrainLayer(layer.cesium)) {
142
+ if (isTerrainLayer(layer)) {
138
143
  return this.viewer.terrainProvider === cesiumLayer
139
144
  } else if (cesiumLayer instanceof Cesium.ImageryLayer) {
140
145
  return this.viewer.scene.imageryLayers.contains(cesiumLayer)
@@ -182,7 +187,7 @@ export const baseGlobe = {
182
187
  }
183
188
  // Add the cesium layer to the globe
184
189
  this.cesiumLayers[name] = cesiumLayer
185
- if (this.isTerrainLayer(layer.cesium)) {
190
+ if (isTerrainLayer(layer)) {
186
191
  this.viewer.terrainProvider = cesiumLayer
187
192
  } else if (cesiumLayer instanceof Cesium.ImageryLayer) {
188
193
  this.viewer.scene.imageryLayers.add(cesiumLayer)
@@ -209,7 +214,7 @@ export const baseGlobe = {
209
214
  // Remove the cesium layer from globe
210
215
  const cesiumLayer = this.cesiumLayers[name]
211
216
  delete this.cesiumLayers[name]
212
- if (this.isTerrainLayer(layer.cesium)) {
217
+ if (isTerrainLayer(layer)) {
213
218
  this.viewer.terrainProvider = null
214
219
  } else if (cesiumLayer instanceof Cesium.ImageryLayer) {
215
220
  this.viewer.scene.imageryLayers.remove(cesiumLayer, false)
@@ -419,19 +424,22 @@ export const baseGlobe = {
419
424
  // If feature have been lost at import try to recreate it in order to be compatible with 2D
420
425
  if (!emittedEvent.target.feature) {
421
426
  let feature = { type: 'Feature' }
422
- // FIXME: Generate GeoJson feature if possible (requires Cesium 1.59)
427
+ /* FIXME: Generate GeoJson feature if possible (requires Cesium 1.59)
428
+ However this does not work yet and could be too much slow
423
429
  if (typeof Cesium.exportKml === 'function') {
424
- const kmlEntities = Cesium.exportKml({ entities: [emittedEvent.target] })
425
- const geoJson = kml(kmlEntities)
430
+ const selection = new Cesium.EntityCollection()
431
+ selection.add(emittedEvent.target)
432
+ const kmlEntities = await Cesium.exportKml({ entities: selection, modelCallback: () => '' })
433
+ const geoJson = kml(kmlEntities.kml)
426
434
  if (geoJson.features.length > 0) feature = geoJson.features[0]
427
- } else {
428
- const position = Cesium.Cartographic.fromCartesian(emittedEvent.target.position
429
- ? emittedEvent.target.position.getValue(0)
430
- : emittedEvent.pickedPosition)
431
- feature.geometry = {
432
- type: 'Point',
433
- coordinates: [Cesium.Math.toDegrees(position.longitude), Cesium.Math.toDegrees(position.latitude)]
434
- }
435
+ }
436
+ */
437
+ const position = Cesium.Cartographic.fromCartesian(emittedEvent.target.position
438
+ ? emittedEvent.target.position.getValue(0)
439
+ : emittedEvent.pickedPosition)
440
+ feature.geometry = {
441
+ type: 'Point',
442
+ coordinates: [Cesium.Math.toDegrees(position.longitude), Cesium.Math.toDegrees(position.latitude)]
435
443
  }
436
444
  feature.properties = (emittedEvent.target.properties ? emittedEvent.target.properties.getValue(0) : {})
437
445
  emittedEvent.target.feature = feature