@kalisio/kdk 2.1.8 → 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.
- package/.travis.test.sh +42 -10
- package/README.md +2 -2
- package/core/api/application.js +6 -1
- package/core/api/authentication.js +17 -1
- package/core/api/db.js +7 -2
- package/core/api/hooks/hooks.authentication.js +4 -2
- package/core/api/hooks/hooks.authorisations.js +12 -2
- package/core/api/hooks/hooks.model.js +5 -5
- package/core/api/hooks/hooks.organisations.js +0 -4
- package/core/api/services/account/account.hooks.js +10 -6
- package/core/api/services/account/account.service.js +1 -1
- package/{map/api/services/geocoder/geocoder.hooks.js → core/api/services/import-export/import-export.hooks.js} +7 -5
- package/core/api/services/import-export/import-export.service.js +11 -0
- package/core/api/services/index.js +13 -1
- package/core/api/services/users/users.hooks.js +2 -3
- package/core/client/api.js +16 -14
- package/core/client/capabilities.js +6 -2
- package/core/client/components/KContent.vue +11 -1
- package/core/client/components/KDialog.vue +17 -15
- package/core/client/components/KSponsor.vue +1 -1
- package/core/client/components/KTextArea.vue +5 -1
- package/core/client/components/app/KAbout.vue +1 -2
- package/core/client/components/app/KWelcome.vue +3 -5
- package/core/client/components/chart/KTimeSeriesChart.vue +24 -37
- package/core/client/components/collection/KColumn.vue +20 -17
- package/core/client/components/editor/KModalEditor.vue +0 -2
- package/core/client/components/form/KChipsField.vue +12 -2
- package/core/client/components/form/KColorField.vue +12 -2
- package/core/client/components/form/KColorScaleField.vue +12 -2
- package/core/client/components/form/KDateTimeRangeField.vue +12 -2
- package/core/client/components/form/KDatetimeField.vue +12 -2
- package/core/client/components/form/KEmailField.vue +12 -2
- package/core/client/components/form/KFileField.vue +12 -2
- package/core/client/components/form/KForm.vue +43 -9
- package/core/client/components/form/KIconField.vue +12 -2
- package/core/client/components/form/KItemField.vue +25 -4
- package/core/client/components/form/KNumberField.vue +12 -2
- package/core/client/components/form/KOptionsField.vue +12 -2
- package/core/client/components/form/KPasswordField.vue +12 -2
- package/core/client/components/form/KPhoneField.vue +13 -3
- package/core/client/components/form/KPropertyItemField.vue +12 -2
- package/core/client/components/form/KResolutionField.vue +126 -0
- package/core/client/components/form/KRoleField.vue +12 -2
- package/core/client/components/form/KSelectField.vue +14 -4
- package/core/client/components/form/KTextField.vue +12 -2
- package/core/client/components/form/KTextareaField.vue +13 -3
- package/core/client/components/form/KToggleField.vue +12 -2
- package/core/client/components/form/KTokenField.vue +12 -2
- package/core/client/components/form/KUnitField.vue +12 -2
- package/core/client/components/form/KUrlField.vue +12 -2
- package/core/client/components/input/KIconChooser.vue +10 -12
- package/core/client/components/input/KPalette.vue +2 -1
- package/core/client/components/layout/KPage.vue +5 -4
- package/core/client/components/layout/KWindow.vue +10 -10
- package/core/client/components/media/KColorScale.vue +26 -20
- package/core/client/components/media/KImageViewer.vue +57 -33
- package/core/client/components/media/KShape.vue +14 -103
- package/core/client/components/screen/KRegisterScreen.vue +0 -1
- package/core/client/components/screen/KScreenFooter.vue +0 -18
- package/core/client/components/team/KAddMember.vue +14 -11
- package/core/client/components/team/KGroupsActivity.vue +14 -0
- package/core/client/components/team/KMembersActivity.vue +12 -0
- package/core/client/components/team/KTagsActivity.vue +14 -0
- package/core/client/components/time/KDateTime.vue +23 -7
- package/core/client/components/time/KTimeControl.vue +142 -0
- package/core/client/components/tool/KExportTool.vue +57 -0
- package/core/client/composables/collection.js +0 -1
- package/core/client/composables/pwa.js +0 -1
- package/core/client/composables/schema.js +1 -1
- package/core/client/composables/session.js +30 -6
- package/core/client/exporter.js +141 -0
- package/core/client/i18n/core_en.json +93 -24
- package/core/client/i18n/core_fr.json +94 -24
- package/core/client/index.js +3 -0
- package/core/client/layout.js +34 -14
- package/core/client/local-storage.js +8 -6
- package/core/client/mixins/index.js +0 -1
- package/core/client/mixins/mixin.base-field.js +24 -2
- package/core/client/mixins/mixin.object-proxy.js +0 -1
- package/core/client/readers/reader.csv.js +1 -1
- package/core/client/search.js +2 -1
- package/core/client/services/index.js +2 -1
- package/core/client/services/local-settings.service.js +4 -4
- package/core/client/theme.js +3 -3
- package/core/client/time.js +4 -0
- package/core/client/units.js +149 -4
- package/core/client/utils/index.js +13 -6
- package/core/client/utils/utils.account.js +1 -1
- package/core/client/utils/utils.colors.js +43 -0
- package/core/client/utils/utils.platform.js +0 -1
- package/core/client/utils/utils.pwa.js +14 -14
- package/core/client/utils/utils.session.js +1 -1
- package/core/client/utils/utils.shapes.js +270 -0
- package/core/client/utils/utils.time.js +37 -0
- package/core/common/permissions.js +3 -0
- package/core/common/schemas/settings.update.json +50 -29
- package/extras/css/core.variables.scss +3 -1
- package/extras/tours/map/navigation-bar.js +17 -15
- package/extras/tours/map/timeline.js +33 -33
- package/map/api/config/categories.cjs +4 -1
- package/map/api/hooks/hooks.catalog.js +39 -0
- package/map/api/hooks/hooks.features.js +23 -3
- package/map/api/hooks/hooks.query.js +31 -10
- package/map/api/models/projects.model.mongodb.js +8 -0
- package/map/api/services/catalog/catalog.hooks.js +5 -3
- package/map/api/services/features/features.hooks.js +18 -6
- package/map/api/services/index.js +22 -6
- package/map/api/services/projects/projects.hooks.js +118 -0
- package/map/client/capture.js +16 -0
- package/map/client/cesium/utils/index.js +3 -0
- package/map/client/cesium/utils/utils.events.js +30 -0
- package/map/client/cesium/utils/utils.popup.js +17 -0
- package/map/client/cesium/{utils.js → utils/utils.style.js} +53 -49
- package/map/client/components/KCapture.vue +50 -0
- package/map/client/components/KCaptureTextArea.vue +53 -0
- package/map/client/components/KCompass.vue +2 -2
- package/map/client/components/KFeaturesChart.vue +1 -1
- package/map/client/components/KFeaturesFilter.vue +2 -2
- package/map/client/components/KLayerStyleForm.vue +256 -430
- package/map/client/components/KLevelSlider.vue +1 -1
- package/map/client/components/KNorth.vue +31 -0
- package/map/client/components/KProjectMenu.vue +88 -0
- package/map/client/components/KTimezoneMap.vue +36 -23
- package/map/client/components/catalog/KAddLayer.vue +3 -4
- package/map/client/components/catalog/KConnectLayer.vue +16 -4
- package/map/client/components/catalog/KCreateLayer.vue +1 -2
- package/map/client/components/catalog/KCreateProject.vue +100 -0
- package/map/client/components/catalog/KCreateView.vue +25 -2
- package/map/client/components/catalog/KLayersPanel.vue +24 -27
- package/map/client/components/catalog/KLayersSelector.vue +1 -1
- package/map/client/components/catalog/KProjectEditor.vue +91 -0
- package/map/client/components/catalog/KProjectManager.vue +60 -0
- package/map/client/components/catalog/KProjectSelector.vue +38 -0
- package/map/client/components/catalog/KProjectsPanel.vue +153 -0
- package/map/client/components/catalog/KSelectLayers.vue +96 -0
- package/map/client/components/catalog/KSelectViews.vue +96 -0
- package/map/client/components/catalog/KViewsPanel.vue +66 -30
- package/map/client/components/form/KDirectionField.vue +24 -5
- package/map/client/components/form/KLayerCategoryField.vue +12 -2
- package/map/client/components/form/KLocationField.vue +20 -5
- package/map/client/components/form/KOwsLayerField.vue +12 -2
- package/map/client/components/form/KOwsServiceField.vue +12 -2
- package/map/client/components/form/KSelectLayersField.vue +159 -0
- package/map/client/components/form/KSelectViewsField.vue +121 -0
- package/map/client/components/form/KTimezoneField.vue +24 -17
- package/map/client/components/legend/KColorScaleLegend.vue +1 -1
- package/map/client/components/legend/KLayerLegend.vue +61 -0
- package/map/client/components/legend/KLegend.vue +45 -44
- package/map/client/components/legend/KLegendRenderer.vue +5 -3
- package/map/client/components/legend/KSymbolsLegend.vue +12 -10
- package/map/client/components/legend/KVariablesLegend.vue +78 -0
- package/map/client/components/location/KGeocodersFilter.vue +2 -4
- package/map/client/components/location/KLocationMap.vue +48 -17
- package/map/client/components/location/KLocationSearch.vue +13 -3
- package/map/client/components/tools/KSearchTool.vue +17 -12
- package/map/client/components/widget/KElevationProfile.vue +16 -19
- package/map/client/components/widget/KMapillaryViewer.vue +21 -22
- package/map/client/components/widget/KTimeSeries.vue +35 -23
- package/map/client/composables/activity.js +15 -2
- package/map/client/composables/catalog.js +66 -0
- package/map/client/composables/highlight.js +56 -20
- package/map/client/composables/index.js +2 -0
- package/map/client/composables/location.js +25 -18
- package/map/client/composables/project.js +122 -0
- package/map/client/geolocation.js +1 -1
- package/map/client/globe.js +2 -0
- package/map/client/i18n/map_en.json +123 -76
- package/map/client/i18n/map_fr.json +124 -72
- package/map/client/index.js +3 -0
- package/map/client/init.js +17 -0
- package/map/client/leaflet/GSMaPLayer.js +16 -17
- package/map/client/leaflet/ShapeMarker.js +40 -0
- package/map/client/leaflet/TiledFeatureLayer.js +1 -1
- package/map/client/leaflet/TiledMeshLayer.js +11 -15
- package/map/client/leaflet/TiledWindLayer.js +6 -10
- package/map/client/leaflet/utils/index.js +4 -0
- package/map/client/leaflet/utils/utils.events.js +41 -0
- package/map/client/leaflet/utils/utils.popup.js +21 -0
- package/map/client/leaflet/utils/utils.style.js +191 -0
- package/map/client/leaflet/utils/utils.tiles.js +87 -0
- package/map/client/map.js +2 -0
- package/map/client/mixins/globe/mixin.base-globe.js +29 -21
- package/map/client/mixins/globe/mixin.geojson-layers.js +132 -69
- package/map/client/mixins/globe/mixin.popup.js +2 -1
- package/map/client/mixins/globe/mixin.style.js +6 -4
- package/map/client/mixins/globe/mixin.tooltip.js +8 -3
- package/map/client/mixins/map/mixin.base-map.js +13 -11
- package/map/client/mixins/map/mixin.edit-layers.js +15 -15
- package/map/client/mixins/map/mixin.forecast-layers.js +3 -1
- package/map/client/mixins/map/mixin.geojson-layers.js +56 -20
- package/map/client/mixins/map/mixin.georaster-layers.js +4 -11
- package/map/client/mixins/map/mixin.heatmap-layers.js +1 -1
- package/map/client/mixins/map/mixin.popup.js +2 -1
- package/map/client/mixins/map/mixin.style.js +4 -67
- package/map/client/mixins/map/mixin.tiled-mesh-layers.js +2 -1
- package/map/client/mixins/map/mixin.tiled-wind-layers.js +4 -2
- package/map/client/mixins/map/mixin.tooltip.js +2 -1
- package/map/client/mixins/mixin.activity.js +66 -191
- package/map/client/mixins/mixin.catalog-panel.js +6 -6
- package/map/client/mixins/mixin.context.js +13 -10
- package/map/client/mixins/mixin.feature-service.js +29 -300
- package/map/client/mixins/mixin.weacast.js +11 -17
- package/map/client/pixi-utils.js +1 -1
- package/map/client/planets.js +58 -0
- package/map/client/utils/index.js +6 -0
- package/map/client/utils/utils.capture.js +176 -0
- package/map/client/utils/utils.catalog.js +149 -0
- package/map/client/utils/utils.features.js +364 -0
- package/map/client/utils/utils.js +0 -151
- package/map/client/utils/utils.layers.js +174 -0
- package/map/client/utils/utils.location.js +91 -23
- package/map/client/utils/utils.project.js +8 -0
- package/map/client/utils/utils.schema.js +0 -1
- package/map/client/utils/utils.style.js +297 -0
- package/map/client/utils.all.js +2 -2
- package/map/client/utils.globe.js +1 -1
- package/map/client/utils.map.js +1 -1
- package/map/common/permissions.js +2 -0
- package/map/common/schemas/capture.create.json +132 -0
- package/map/common/schemas/projects.create.json +52 -0
- package/map/common/schemas/projects.update.json +52 -0
- package/package.json +6 -5
- package/test/api/core/account.test.js +20 -0
- package/test/api/core/config/default.cjs +16 -3
- package/test/api/core/import-export.test.js +86 -0
- package/test/api/core/test-log-2023-12-19.log +7 -0
- package/test/api/core/test-log-2024-01-04.log +14 -0
- package/test/api/map/catalog.test.js +164 -0
- package/test/api/map/index.test.js +25 -61
- package/test/api/map/test-log-2023-11-24.log +121 -0
- package/test/api/map/test-log-2023-12-12.log +29 -0
- package/test/api/map/test-log-2023-12-13.log +5 -0
- package/test/api/map/test-log-2024-01-04.log +2 -0
- package/test/api/map/test-log-2024-01-11.log +1 -0
- package/test/api/map/test-log-2024-01-25.log +19 -0
- package/test/client/core/layout.js +25 -5
- package/test/client/core/utils.js +7 -0
- package/test/client/map/catalog.js +78 -1
- package/test/client/map/time.js +2 -1
- package/core/client/components/screen/KEndpointScreen.vue +0 -80
- package/core/client/mixins/mixin.account.js +0 -61
- package/extras/icons/kdk.png +0 -0
- package/map/api/services/geocoder/geocoder.service.js +0 -79
- package/map/client/components/KCaptureToolbar.vue +0 -155
- package/map/client/components/KColorLegend.vue +0 -349
- package/map/client/components/KTimeline.vue +0 -293
- package/map/client/components/KUrlLegend.vue +0 -122
- package/map/client/leaflet/utils.js +0 -246
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import _ from 'lodash'
|
|
2
2
|
import logger from 'loglevel'
|
|
3
3
|
import config from 'config'
|
|
4
|
-
import
|
|
5
|
-
import { Loading, Dialog } from 'quasar'
|
|
4
|
+
import { Store, utils as kCoreUtils } from '../../../core/client/index.js'
|
|
6
5
|
import { Geolocation } from '../geolocation.js'
|
|
7
|
-
import { setEngineJwt } from '../utils.js'
|
|
8
|
-
import
|
|
6
|
+
import { setEngineJwt, getLayers, getCategories } from '../utils/utils.catalog.js'
|
|
7
|
+
import * as layers from '../utils/utils.layers.js'
|
|
8
|
+
import { getCatalogProjectQuery } from '../utils/utils.project.js'
|
|
9
9
|
|
|
10
10
|
export const activity = {
|
|
11
11
|
data () {
|
|
@@ -41,33 +41,27 @@ export const activity = {
|
|
|
41
41
|
return []
|
|
42
42
|
},
|
|
43
43
|
async getCatalogLayers () {
|
|
44
|
-
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
const query = {}
|
|
45
|
+
// Do we get layers coming from project ?
|
|
46
|
+
if (this.project) {
|
|
47
|
+
Object.assign(query, this.catalogProjectQuery ? this.catalogProjectQuery : getCatalogProjectQuery(this.project))
|
|
48
|
+
} else {
|
|
49
|
+
this.project = null
|
|
50
50
|
}
|
|
51
|
+
|
|
52
|
+
// We get layers coming from global catalog first if any
|
|
53
|
+
let layers = await getLayers({ query })
|
|
51
54
|
// Then we get layers coming from contextual catalog if any
|
|
52
|
-
const
|
|
53
|
-
if (
|
|
54
|
-
const response = await catalogService.find()
|
|
55
|
-
layers = layers.concat(response.data)
|
|
56
|
-
}
|
|
57
|
-
// Do we need to inject a token ?
|
|
58
|
-
await setEngineJwt(layers)
|
|
55
|
+
const context = Store.get('context')
|
|
56
|
+
if (context) layers = layers.concat(await getLayers({ query, context }))
|
|
59
57
|
return layers
|
|
60
58
|
},
|
|
61
59
|
async addCatalogLayer (layer) {
|
|
62
60
|
// Check if available for current engine
|
|
63
61
|
if (layer[this.engine]) {
|
|
64
|
-
// Process i18n
|
|
65
|
-
if (layer.i18n) i18n.registerTranslation(layer.i18n)
|
|
66
|
-
layer.label = this.$tie(layer.name)
|
|
67
|
-
layer.description = this.$tie(layer.description)
|
|
68
62
|
// Check for Weacast API availability
|
|
69
63
|
const isWeacastLayer = _.get(layer, `${this.engine}.type`, '').startsWith('weacast.')
|
|
70
|
-
if (isWeacastLayer && (!this.
|
|
64
|
+
if (isWeacastLayer && (!this.getWeacastApi() || !this.forecastModel)) return
|
|
71
65
|
await this.addLayer(layer)
|
|
72
66
|
}
|
|
73
67
|
// Filter layers with variables, not just visible ones because we might want to
|
|
@@ -82,26 +76,14 @@ export const activity = {
|
|
|
82
76
|
}
|
|
83
77
|
},
|
|
84
78
|
async getCatalogCategories () {
|
|
85
|
-
let categories = []
|
|
86
79
|
// We get categories coming from global catalog first if any
|
|
87
|
-
|
|
88
|
-
if (globalCatalogService) {
|
|
89
|
-
const response = await globalCatalogService.find({ query: { type: 'Category' } })
|
|
90
|
-
categories = categories.concat(response.data)
|
|
91
|
-
}
|
|
80
|
+
let categories = await getCategories()
|
|
92
81
|
// Then we get categories coming from contextual catalog if any
|
|
93
|
-
const
|
|
94
|
-
if (
|
|
95
|
-
const response = await catalogService.find({ query: { type: 'Category' } })
|
|
96
|
-
categories = categories.concat(response.data)
|
|
97
|
-
}
|
|
82
|
+
const context = Store.get('context')
|
|
83
|
+
if (context) categories = categories.concat(await getCategories({ context }))
|
|
98
84
|
return categories
|
|
99
85
|
},
|
|
100
86
|
async addCatalogCategory (category) {
|
|
101
|
-
// Process i18n
|
|
102
|
-
if (category.i18n) i18n.registerTranslation(category.i18n)
|
|
103
|
-
category.label = this.$tie(category.name)
|
|
104
|
-
category.description = this.$tie(category.description)
|
|
105
87
|
this.layerCategories.push(category)
|
|
106
88
|
},
|
|
107
89
|
async refreshLayerCategories () {
|
|
@@ -128,45 +110,21 @@ export const activity = {
|
|
|
128
110
|
if (baseLayer) await this.showLayer(baseLayer.name)
|
|
129
111
|
}
|
|
130
112
|
},
|
|
131
|
-
isInMemoryLayer
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
return (_.get(layer, 'scope') === 'user')
|
|
136
|
-
},
|
|
137
|
-
isFeatureLayer (layer) {
|
|
138
|
-
return (_.get(layer, 'service') === 'features')
|
|
139
|
-
},
|
|
140
|
-
hasFeatureSchema (layer) {
|
|
141
|
-
return _.has(layer, 'schema')
|
|
142
|
-
},
|
|
113
|
+
isInMemoryLayer: layers.isInMemoryLayer,
|
|
114
|
+
isUserLayer: layers.isUserLayer,
|
|
115
|
+
isFeatureLayer: layers.isFeatureLayer,
|
|
116
|
+
hasFeatureSchema: layers.hasFeatureSchema,
|
|
143
117
|
isLayerSelectable (layer) {
|
|
144
118
|
// Only possible when not edited by default
|
|
145
119
|
if ((typeof this.isLayerEdited === 'function') && this.isLayerEdited(layer)) return false
|
|
146
|
-
return
|
|
147
|
-
},
|
|
148
|
-
isLayerProbable
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
return _.get(layer, 'isStorable', this.isUserLayer(layer))
|
|
155
|
-
},
|
|
156
|
-
isLayerEditable (layer) {
|
|
157
|
-
// Only possible when saved by default
|
|
158
|
-
if (!layer._id) return false
|
|
159
|
-
return _.get(layer, 'isEditable', this.isUserLayer(layer))
|
|
160
|
-
},
|
|
161
|
-
isLayerRemovable (layer) {
|
|
162
|
-
return _.get(layer, 'isRemovable', this.isUserLayer(layer))
|
|
163
|
-
},
|
|
164
|
-
isLayerStyleEditable (layer) {
|
|
165
|
-
return _.get(layer, 'isStyleEditable', this.isUserLayer(layer))
|
|
166
|
-
},
|
|
167
|
-
isLayerDataEditable (layer) {
|
|
168
|
-
return _.get(layer, 'isDataEditable', this.isUserLayer(layer) && this.isFeatureLayer(layer))
|
|
169
|
-
},
|
|
120
|
+
return layers.isLayerSelectable(layer)
|
|
121
|
+
},
|
|
122
|
+
isLayerProbable: layers.isLayerProbable,
|
|
123
|
+
isLayerStorable: layers.isLayerStorable,
|
|
124
|
+
isLayerEditable: layers.isLayerEditable,
|
|
125
|
+
isLayerRemovable: layers.isLayerRemovable,
|
|
126
|
+
isLayerStyleEditable: layers.isLayerStyleEditable,
|
|
127
|
+
isLayerDataEditable: layers.isLayerDataEditable,
|
|
170
128
|
async resetLayer (layer) {
|
|
171
129
|
// Reset layer with new setup but keep track of current visibility state
|
|
172
130
|
// as adding the layer back will restore default visibility state
|
|
@@ -217,90 +175,26 @@ export const activity = {
|
|
|
217
175
|
async onSaveLayer (layer) {
|
|
218
176
|
// Stop any running edition
|
|
219
177
|
if ((typeof this.isLayerEdited === 'function') && this.isLayerEdited(layer)) await this.stopEditLayer('accept')
|
|
178
|
+
let createdLayer
|
|
220
179
|
// Take care that WFS layers rely on the same type as our own feature layers
|
|
221
180
|
if (!_.has(layer, 'wfs') && _.get(layer, `${this.engine}.type`) === 'geoJson') {
|
|
222
181
|
const geoJson = this.toGeoJson(layer.name)
|
|
223
|
-
|
|
224
|
-
const check = this.checkFeatures(geoJson)
|
|
225
|
-
if (check.kinks.length > 0) {
|
|
226
|
-
const result = await kCoreUtils.dialog({
|
|
227
|
-
title: this.$t('mixins.activity.INVALID_FEATURES_DIALOG_TITLE', { features: check.kinks }),
|
|
228
|
-
message: this.$t('mixins.activity.INVALID_FEATURES_DIALOG_MESSAGE', { features: check.kinks }),
|
|
229
|
-
options: {
|
|
230
|
-
type: 'toggle',
|
|
231
|
-
model: [],
|
|
232
|
-
items: [
|
|
233
|
-
{ label: this.$t('mixins.activity.DOWNLOAD_INVALID_FEATURES_LABEL'), value: 'download' }
|
|
234
|
-
]
|
|
235
|
-
},
|
|
236
|
-
html: true,
|
|
237
|
-
ok: {
|
|
238
|
-
label: this.$t('OK'),
|
|
239
|
-
flat: true
|
|
240
|
-
},
|
|
241
|
-
cancel: {
|
|
242
|
-
label: this.$t('CANCEL'),
|
|
243
|
-
flat: true
|
|
244
|
-
}
|
|
245
|
-
})
|
|
246
|
-
if (!result.ok) return
|
|
247
|
-
// Export invalid features if required
|
|
248
|
-
if (_.get(result, 'data', []).includes('download')) {
|
|
249
|
-
kCoreUtils.downloadAsBlob(JSON.stringify({ type: 'FeatureCollection', features: check.kinks }),
|
|
250
|
-
this.$t('mixins.activity.INVALID_FEATURES_FILE'), 'application/json;charset=utf-8;')
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
// Change data source from in-memory to features service
|
|
254
|
-
_.set(layer, 'service', 'features')
|
|
255
|
-
if (_.has(layer, 'leaflet')) _.set(layer, 'leaflet.source', '/api/features')
|
|
256
|
-
if (_.has(layer, 'cesium')) _.set(layer, 'cesium.source', '/api/features')
|
|
257
|
-
const features = (geoJson.type === 'FeatureCollection' ? geoJson.features : [geoJson])
|
|
258
|
-
// If too much data use tiling
|
|
259
|
-
// The threshold is based on the number of points and not features.
|
|
260
|
-
// Indeed otherwise the complexity will be different depending on the geometry type
|
|
261
|
-
// (eg a bucket of 1000 polygons can actually contains a lot of points).
|
|
262
|
-
let nbPoints = 0
|
|
263
|
-
features.forEach(feature => {
|
|
264
|
-
nbPoints += explode(feature).features.length
|
|
265
|
-
})
|
|
266
|
-
if (this.is2D() && (nbPoints > 5000)) {
|
|
267
|
-
_.set(layer, 'leaflet.tiled', true)
|
|
268
|
-
_.set(layer, 'leaflet.minZoom', 15)
|
|
269
|
-
}
|
|
270
|
-
Loading.show({ message: this.$t('mixins.activity.SAVING_LABEL', { processed: 0, total: features.length }), html: true })
|
|
271
|
-
try {
|
|
272
|
-
let createdLayer = await this.$api.getService('catalog')
|
|
273
|
-
.create(_.omit(layer, ['actions', 'label', 'isVisible', 'isDisabled']))
|
|
274
|
-
const chunkSize = _.get(this, 'activityOptions.featuresChunkSize', 5000)
|
|
275
|
-
let nbFeatures = 0
|
|
276
|
-
// We use the generated DB ID as layer ID on features
|
|
277
|
-
await this.createFeatures(geoJson, createdLayer._id, chunkSize, (i, chunk) => {
|
|
278
|
-
// Update saving message according to new chunk data
|
|
279
|
-
nbFeatures += chunk.length
|
|
280
|
-
Loading.show({
|
|
281
|
-
message: this.$t('mixins.activity.SAVING_LABEL', { processed: nbFeatures, total: features.length }),
|
|
282
|
-
html: true
|
|
283
|
-
})
|
|
284
|
-
})
|
|
285
|
-
// Because we save all features in a single service use filtering to separate layers
|
|
286
|
-
createdLayer = await this.$api.getService('catalog').patch(createdLayer._id, { baseQuery: { layer: createdLayer._id } })
|
|
287
|
-
// Reset layer with new setup
|
|
288
|
-
await this.resetLayer(createdLayer)
|
|
289
|
-
if (_.get(layer, 'leaflet.tiled')) {
|
|
290
|
-
this.$notify({ type: 'positive', message: this.$t('mixins.activity.SAVE_DIALOG_MESSAGE'), timeout: 10000, html: true })
|
|
291
|
-
}
|
|
292
|
-
} catch (error) {
|
|
293
|
-
// User error message on operation should be raised by error hook, otherwise this is more a coding error
|
|
294
|
-
logger.error(`[KDK] ${error}`)
|
|
295
|
-
}
|
|
296
|
-
Loading.hide()
|
|
182
|
+
createdLayer = await layers.saveGeoJsonLayer(layer, geoJson, _.get(this, 'activityOptions.featuresChunkSize', 5000))
|
|
297
183
|
} else {
|
|
298
184
|
// Otherwise simply save in catalog
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
185
|
+
createdLayer = await layers.saveLayer(layer)
|
|
186
|
+
}
|
|
187
|
+
// Add layer to current project ?
|
|
188
|
+
if (this.project) {
|
|
189
|
+
this.project.layers.push({ _id: createdLayer._id })
|
|
190
|
+
await this.$api.getService('projects').patch(this.project._id, {
|
|
191
|
+
layers: this.project.layers
|
|
192
|
+
})
|
|
303
193
|
}
|
|
194
|
+
// Reset layer with new setup
|
|
195
|
+
// It should be triggerred by real-time event
|
|
196
|
+
// but as we might not always use sockets perform it anyway
|
|
197
|
+
if (createdLayer) await this.resetLayer(createdLayer)
|
|
304
198
|
},
|
|
305
199
|
editLayerByName (name, editOptions = {}) {
|
|
306
200
|
// this one is used through postRobot to trigger edition
|
|
@@ -324,39 +218,14 @@ export const activity = {
|
|
|
324
218
|
await this.stopEditLayer(status)
|
|
325
219
|
},
|
|
326
220
|
async onRemoveLayer (layer) {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
cancel: {
|
|
336
|
-
label: this.$t('CANCEL'),
|
|
337
|
-
flat: true
|
|
338
|
-
}
|
|
339
|
-
}).onOk(async () => {
|
|
340
|
-
Loading.show({ message: this.$t('mixins.activity.REMOVING_LABEL'), html: true })
|
|
341
|
-
try {
|
|
342
|
-
// Stop any running edition
|
|
343
|
-
if ((typeof this.isLayerEdited === 'function') && this.isLayerEdited(layer)) await this.stopEditLayer('reject')
|
|
344
|
-
if (layer._id) {
|
|
345
|
-
// If persistent feature layer remove features as well
|
|
346
|
-
if (this.isFeatureLayer(layer)) {
|
|
347
|
-
await this.removeFeatures(layer._id)
|
|
348
|
-
}
|
|
349
|
-
await this.$api.getService('catalog').remove(layer._id)
|
|
350
|
-
}
|
|
351
|
-
// Actual layer removal should be triggerred by real-time event
|
|
352
|
-
// but as we might not always use sockets perform it anyway
|
|
353
|
-
this.removeLayer(layer.name)
|
|
354
|
-
} catch (error) {
|
|
355
|
-
// User error message on operation should be raised by error hook, otherwise this is more a coding error
|
|
356
|
-
logger.error(`[KDK] ${error}`)
|
|
357
|
-
}
|
|
358
|
-
Loading.hide()
|
|
359
|
-
})
|
|
221
|
+
// Stop any running edition
|
|
222
|
+
if ((typeof this.isLayerEdited === 'function') && this.isLayerEdited(layer)) await this.stopEditLayer('reject')
|
|
223
|
+
if (await layers.removeLayer(layer)) {
|
|
224
|
+
// Actual layer removal should be triggerred by real-time event
|
|
225
|
+
// but as we might not always use sockets perform it anyway
|
|
226
|
+
this.removeLayer(layer.name)
|
|
227
|
+
}
|
|
228
|
+
// Removing the layer should automatically update all projects
|
|
360
229
|
},
|
|
361
230
|
onEngineReady (engine) {
|
|
362
231
|
this.engine = engine
|
|
@@ -401,10 +270,13 @@ export const activity = {
|
|
|
401
270
|
this.catalogListeners = {}
|
|
402
271
|
if (globalCatalogService.events !== undefined) {
|
|
403
272
|
globalCatalogService.events.forEach(event => {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
273
|
+
// Avoid reentrance
|
|
274
|
+
if (!this.catalogListeners[event]) {
|
|
275
|
+
this.catalogListeners[event] = (object) => this.onCatalogUpdated(event, object)
|
|
276
|
+
globalCatalogService.on(event, this.catalogListeners[event])
|
|
277
|
+
if (catalogService && (catalogService !== globalCatalogService)) {
|
|
278
|
+
catalogService.on(event, this.catalogListeners[event])
|
|
279
|
+
}
|
|
408
280
|
}
|
|
409
281
|
})
|
|
410
282
|
}
|
|
@@ -415,9 +287,12 @@ export const activity = {
|
|
|
415
287
|
const catalogService = this.$api.getService('catalog')
|
|
416
288
|
if (globalCatalogService.events !== undefined) {
|
|
417
289
|
globalCatalogService.events.forEach(event => {
|
|
418
|
-
|
|
419
|
-
if (
|
|
420
|
-
|
|
290
|
+
// Avoid reentrance
|
|
291
|
+
if (this.catalogListeners[event]) {
|
|
292
|
+
globalCatalogService.removeListener(event, this.catalogListeners[event])
|
|
293
|
+
if (catalogService && (catalogService !== globalCatalogService)) {
|
|
294
|
+
catalogService.removeListener(event, this.catalogListeners[event])
|
|
295
|
+
}
|
|
421
296
|
}
|
|
422
297
|
})
|
|
423
298
|
}
|
|
@@ -3,24 +3,24 @@ export const catalogPanel = {
|
|
|
3
3
|
panelStyle () {
|
|
4
4
|
const screenHeight = this.$q.screen.height
|
|
5
5
|
this.scrollAreaMaxHeight = screenHeight * 0.75 // 75vh
|
|
6
|
-
this.
|
|
6
|
+
this.scrollAreaMinWidth = 390
|
|
7
7
|
if (this.$q.screen.lt.sm) {
|
|
8
8
|
this.scrollAreaMaxHeight = screenHeight * 0.6
|
|
9
|
-
this.
|
|
9
|
+
this.scrollAreaMinWidth = 300
|
|
10
10
|
} else if (this.$q.screen.lt.md) {
|
|
11
11
|
this.scrollAreaMaxHeight = screenHeight * 0.65
|
|
12
|
-
this.
|
|
12
|
+
this.scrollAreaMinWidth = 330
|
|
13
13
|
} else if (this.$q.screen.lt.lg) {
|
|
14
14
|
this.scrollAreaMaxHeight = screenHeight * 0.7
|
|
15
|
-
this.
|
|
15
|
+
this.scrollAreaMinWidth = 360
|
|
16
16
|
}
|
|
17
|
-
return `height: ${this.scrollAreaMaxHeight}px; width: ${this.
|
|
17
|
+
return `height: ${this.scrollAreaMaxHeight}px; min-width: ${this.scrollAreaMinWidth}px;'`
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
data () {
|
|
21
21
|
return {
|
|
22
22
|
scrollAreaMaxHeight: 0,
|
|
23
|
-
|
|
23
|
+
scrollAreaMinWidth: 390
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import _ from 'lodash'
|
|
2
2
|
import moment from 'moment'
|
|
3
3
|
import sift from 'sift'
|
|
4
|
-
import { utils as kCoreUtils, Time, Store } from '../../../core/client/index.js'
|
|
4
|
+
import { utils as kCoreUtils, Time, Store, LocalStorage } from '../../../core/client/index.js'
|
|
5
|
+
import { isTerrainLayer } from '../utils/utils.layers.js'
|
|
5
6
|
|
|
6
7
|
export const context = {
|
|
7
8
|
methods: {
|
|
8
9
|
getContextKey (context) {
|
|
9
10
|
// Generate a unique key to store context based on app name, map activity name and context type
|
|
10
|
-
return
|
|
11
|
+
return `${this.activityName}-${context}`
|
|
11
12
|
},
|
|
12
13
|
shouldRestoreContext (context) {
|
|
13
14
|
// Use user settings except if the view has explicitly revoked restoration
|
|
@@ -61,7 +62,7 @@ export const context = {
|
|
|
61
62
|
break
|
|
62
63
|
case 'time': {
|
|
63
64
|
targetParameters = {
|
|
64
|
-
time: Time.getCurrentTime()
|
|
65
|
+
time: Time.getCurrentTime()
|
|
65
66
|
}
|
|
66
67
|
break
|
|
67
68
|
}
|
|
@@ -130,8 +131,8 @@ export const context = {
|
|
|
130
131
|
// Take care that 3D requires at least a terrain layer.
|
|
131
132
|
// So if we try to remove a terrain layer without activating a new one, keep it active
|
|
132
133
|
// (this can be the case when the view has been saved from the 2D activity and restored in the 3D activity).
|
|
133
|
-
const inactivatedTerrainLayer = _.find(inactivatedLayers, (name) => this.hasLayer(name) && (this.getLayerByName(name)
|
|
134
|
-
const activatedTerrainLayer = _.find(activedLayers, (name) => this.hasLayer(name) && (this.getLayerByName(name)
|
|
134
|
+
const inactivatedTerrainLayer = _.find(inactivatedLayers, (name) => this.hasLayer(name) && isTerrainLayer(this.getLayerByName(name)))
|
|
135
|
+
const activatedTerrainLayer = _.find(activedLayers, (name) => this.hasLayer(name) && isTerrainLayer(this.getLayerByName(name)))
|
|
135
136
|
if (inactivatedTerrainLayer && !activatedTerrainLayer) _.pull(inactivatedLayers, inactivatedTerrainLayer)
|
|
136
137
|
await Promise.all(activedLayers.map(layer => this.showLayer(layer)))
|
|
137
138
|
await Promise.all(inactivatedLayers.map(layer => this.hideLayer(layer)))
|
|
@@ -160,16 +161,16 @@ export const context = {
|
|
|
160
161
|
if (!_.isEqual(this.getRouteContext(context), targetParameters)) {
|
|
161
162
|
this.updateRouteContext(context, targetParameters)
|
|
162
163
|
}
|
|
163
|
-
|
|
164
|
+
LocalStorage.set(this.getContextKey(context), targetParameters)
|
|
164
165
|
}
|
|
165
166
|
},
|
|
166
167
|
async restoreContext (context) {
|
|
167
168
|
let targetParameters = this.getRouteContext(context)
|
|
168
169
|
// Restore from local storage/catalog if no route parameters
|
|
169
170
|
if (_.isEmpty(targetParameters)) {
|
|
170
|
-
const savedParameters =
|
|
171
|
-
if (this.shouldRestoreContext(context) && savedParameters) {
|
|
172
|
-
targetParameters =
|
|
171
|
+
const savedParameters = LocalStorage.get(this.getContextKey(context))
|
|
172
|
+
if (this.shouldRestoreContext(context) && !_.isEmpty(savedParameters)) {
|
|
173
|
+
targetParameters = savedParameters
|
|
173
174
|
// Backward compatibility: we previously stored the bounds as an array
|
|
174
175
|
if (Array.isArray(targetParameters)) {
|
|
175
176
|
targetParameters = {
|
|
@@ -227,7 +228,8 @@ export const context = {
|
|
|
227
228
|
if (hasLayers) {
|
|
228
229
|
Object.assign(context, this.getContextParameters('layers'))
|
|
229
230
|
}
|
|
230
|
-
await this.$api.getService('catalog').create(context)
|
|
231
|
+
context = await this.$api.getService('catalog').create(context)
|
|
232
|
+
return context
|
|
231
233
|
},
|
|
232
234
|
async loadContext (context) {
|
|
233
235
|
// If not context object retrieve it from catalog first
|
|
@@ -242,6 +244,7 @@ export const context = {
|
|
|
242
244
|
if (!context) throw new Error('Cannot find or invalid context')
|
|
243
245
|
this.setContextParameters('view', context)
|
|
244
246
|
this.setContextParameters('layers', context)
|
|
247
|
+
return context
|
|
245
248
|
},
|
|
246
249
|
updateViewSettings (enabled) {
|
|
247
250
|
if (!enabled) this.clearContext('view')
|