@kalisio/kdk 2.2.0 → 2.2.2
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/core/api/application.js +2 -3
- package/core/client/components/KModal.vue +1 -1
- package/core/client/components/form/KForm.vue +12 -3
- package/core/client/components/media/KColorScale.vue +1 -1
- package/core/client/exporter.js +14 -8
- package/core/client/mixins/mixin.base-field.js +4 -1
- package/core/client/units.js +3 -3
- package/core/client/utils/utils.shapes.js +1 -1
- package/extras/icons/wind-speed-0.svg +8 -0
- package/extras/icons/wind-speed-10.svg +8 -0
- package/extras/icons/wind-speed-100.svg +12 -0
- package/extras/icons/wind-speed-105.svg +13 -0
- package/extras/icons/wind-speed-15.svg +9 -0
- package/extras/icons/wind-speed-20.svg +9 -0
- package/extras/icons/wind-speed-25.svg +10 -0
- package/extras/icons/wind-speed-30.svg +10 -0
- package/extras/icons/wind-speed-35.svg +11 -0
- package/extras/icons/wind-speed-40.svg +11 -0
- package/extras/icons/wind-speed-45.svg +12 -0
- package/extras/icons/wind-speed-5.svg +9 -0
- package/extras/icons/wind-speed-50.svg +9 -0
- package/extras/icons/wind-speed-55.svg +10 -0
- package/extras/icons/wind-speed-60.svg +10 -0
- package/extras/icons/wind-speed-65.svg +11 -0
- package/extras/icons/wind-speed-70.svg +11 -0
- package/extras/icons/wind-speed-75.svg +12 -0
- package/extras/icons/wind-speed-80.svg +12 -0
- package/extras/icons/wind-speed-85.svg +13 -0
- package/extras/icons/wind-speed-90.svg +13 -0
- package/extras/icons/wind-speed-95.svg +14 -0
- package/map/api/hooks/hooks.query.js +34 -11
- package/map/client/cesium/utils/index.js +2 -1
- package/map/client/cesium/utils/utils.features.js +8 -0
- package/map/client/cesium/utils/utils.style.js +4 -4
- package/map/client/components/KFeatureEditor.vue +2 -3
- package/map/client/components/KLayerStyleForm.vue +32 -24
- package/map/client/components/KTimezoneMap.vue +3 -4
- package/map/client/components/catalog/KConnectLayer.vue +14 -10
- package/map/client/components/legend/KColorScaleLegend.vue +6 -2
- package/map/client/components/legend/KLayerLegend.vue +13 -3
- package/map/client/components/legend/KLegend.vue +12 -10
- package/map/client/components/location/KLocationCardSection.vue +8 -4
- package/map/client/components/widget/KTimeSeries.vue +0 -6
- package/map/client/composables/catalog.js +17 -2
- package/map/client/composables/highlight.js +9 -30
- package/map/client/composables/probe.js +4 -1
- package/map/client/composables/weather.js +3 -3
- package/map/client/i18n/map_en.json +4 -0
- package/map/client/i18n/map_fr.json +4 -0
- package/map/client/leaflet/ShapeMarker.js +23 -12
- package/map/client/leaflet/TiledFeatureLayer.js +38 -8
- package/map/client/leaflet/TiledMeshLayer.js +3 -1
- package/map/client/leaflet/utils/utils.style.js +7 -3
- package/map/client/mixins/globe/mixin.base-globe.js +29 -16
- package/map/client/mixins/globe/mixin.geojson-layers.js +7 -0
- package/map/client/mixins/map/mixin.base-map.js +40 -17
- package/map/client/mixins/map/mixin.geojson-layers.js +7 -3
- package/map/client/mixins/mixin.activity.js +5 -1
- package/map/client/planets.js +8 -0
- package/map/client/utils/utils.catalog.js +17 -0
- package/map/client/utils/utils.layers.js +2 -1
- package/map/client/utils/utils.schema.js +0 -28
- package/map/client/utils/utils.style.js +12 -0
- package/map/common/wms-utils.js +8 -3
- package/package.json +1 -1
- package/test/client/core/layout.js +0 -1
- package/test/client/map/catalog.js +1 -1
- package/test/api/core/test-log-2023-12-19.log +0 -7
- package/test/api/core/test-log-2024-01-04.log +0 -14
- package/test/api/map/test-log-2023-11-24.log +0 -121
- package/test/api/map/test-log-2023-12-12.log +0 -29
- package/test/api/map/test-log-2023-12-13.log +0 -5
- package/test/api/map/test-log-2024-01-04.log +0 -2
- package/test/api/map/test-log-2024-01-11.log +0 -1
- package/test/api/map/test-log-2024-01-25.log +0 -19
|
@@ -281,13 +281,15 @@ const TiledMeshLayer = L.GridLayer.extend({
|
|
|
281
281
|
},
|
|
282
282
|
|
|
283
283
|
updateColorMap () {
|
|
284
|
+
const chromajs = this.conf.chromajs
|
|
285
|
+
if (_.isNil(chromajs)) return
|
|
286
|
+
|
|
284
287
|
// create color map using domain or classes
|
|
285
288
|
// domain and classes can be specified from options
|
|
286
289
|
// if not, domain can be gathered from grid source
|
|
287
290
|
this.colorMap = null
|
|
288
291
|
this.colorMapShaderCode = null
|
|
289
292
|
|
|
290
|
-
const chromajs = _.get(this.conf, 'chromajs')
|
|
291
293
|
const classes = chromajs.classes
|
|
292
294
|
let domain
|
|
293
295
|
if (!classes) {
|
|
@@ -4,6 +4,7 @@ import chroma from 'chroma-js'
|
|
|
4
4
|
import moment from 'moment'
|
|
5
5
|
import L from 'leaflet'
|
|
6
6
|
import { Time, Units, utils as kdkCoreUtils } from '../../../../core/client/index.js'
|
|
7
|
+
import { getFeatureStyleType } from '../../utils/utils.features.js'
|
|
7
8
|
import { convertStyle, convertSimpleStyleToPointStyle, convertSimpleStyleToLineStyle, convertSimpleStyleToPolygonStyle,
|
|
8
9
|
PointStyleTemplateMappings, LineStyleTemplateMappings, PolygonStyleTemplateMappings } from '../../utils/utils.style.js'
|
|
9
10
|
import { ShapeMarker } from '../ShapeMarker.js'
|
|
@@ -68,13 +69,15 @@ const LineStyleToLeafletPath = {
|
|
|
68
69
|
cap: 'lineCap',
|
|
69
70
|
join: 'lineJoin',
|
|
70
71
|
dashArray: 'dashArray',
|
|
71
|
-
dashOffset: 'dashOffset'
|
|
72
|
+
dashOffset: 'dashOffset',
|
|
73
|
+
pane: 'pane'
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
const PolygonStyleToLeafletPath = {
|
|
75
77
|
color: 'fillColor',
|
|
76
78
|
opacity: 'fillOpacity',
|
|
77
79
|
rule: 'fillRule',
|
|
80
|
+
pane: 'pane'
|
|
78
81
|
}
|
|
79
82
|
|
|
80
83
|
// TODO: to be removed when updating 3D style
|
|
@@ -158,8 +161,9 @@ function processStyle (style, feature, options, mappings) {
|
|
|
158
161
|
})
|
|
159
162
|
}
|
|
160
163
|
// We manage panes for z-index, so we need to forward it to marker options (only if not already defined)
|
|
161
|
-
|
|
162
|
-
if (leafletOptions.
|
|
164
|
+
const type = getFeatureStyleType(feature)
|
|
165
|
+
if (leafletOptions.pane && !_.has(style, `${type}.pane`)) _.set(style, `${type}.pane`, leafletOptions.pane)
|
|
166
|
+
if (leafletOptions.shadowPane && !_.has(style, `${type}.shadowPane`)) _.set(style, `${type}.shadowPane`, leafletOptions.shadowPane)
|
|
163
167
|
return style
|
|
164
168
|
}
|
|
165
169
|
|
|
@@ -3,12 +3,11 @@ import sift from 'sift'
|
|
|
3
3
|
import logger from 'loglevel'
|
|
4
4
|
import Emitter from 'tiny-emitter'
|
|
5
5
|
import { getCssVar } from 'quasar'
|
|
6
|
-
import { kml } from '@tmcw/togeojson'
|
|
7
6
|
import Cesium from 'cesium/Source/Cesium.js'
|
|
8
7
|
import 'cesium/Source/Widgets/widgets.css'
|
|
9
8
|
import BuildModuleUrl from 'cesium/Source/Core/buildModuleUrl.js'
|
|
10
9
|
import { Geolocation } from '../../geolocation.js'
|
|
11
|
-
import { convertCesiumHandlerEvent, isTerrainLayer } from '../../utils.globe.js'
|
|
10
|
+
import { convertCesiumHandlerEvent, isTerrainLayer, convertEntitiesToGeoJson } from '../../utils.globe.js'
|
|
12
11
|
// Cesium has its own dynamic module loader requiring to be configured
|
|
13
12
|
// Cesium files need to be also added as static assets of the applciation
|
|
14
13
|
BuildModuleUrl.setBaseUrl('/Cesium/')
|
|
@@ -279,6 +278,12 @@ export const baseGlobe = {
|
|
|
279
278
|
clearLayers () {
|
|
280
279
|
Object.keys(this.layers).forEach((layer) => this.removeLayer(layer))
|
|
281
280
|
},
|
|
281
|
+
async toGeoJson (name) {
|
|
282
|
+
const layer = this.getCesiumLayerByName(name)
|
|
283
|
+
if (!layer.entities) return
|
|
284
|
+
const geoJson = await convertEntitiesToGeoJson(layer.entities)
|
|
285
|
+
return geoJson
|
|
286
|
+
},
|
|
282
287
|
zoomToBounds (bounds) {
|
|
283
288
|
this.viewer.camera.flyTo({
|
|
284
289
|
duration: 0,
|
|
@@ -402,7 +407,7 @@ export const baseGlobe = {
|
|
|
402
407
|
}
|
|
403
408
|
return position
|
|
404
409
|
},
|
|
405
|
-
getDefaultPickHandler (event) {
|
|
410
|
+
async getDefaultPickHandler (event) {
|
|
406
411
|
const emittedEvent = {}
|
|
407
412
|
let options
|
|
408
413
|
let pickedPosition = this.viewer.camera.pickEllipsoid(event.endPosition || event.position, this.viewer.scene.globe.ellipsoid)
|
|
@@ -422,24 +427,32 @@ export const baseGlobe = {
|
|
|
422
427
|
emittedEvent.target = pickedObject.id || pickedObject.primitive.id
|
|
423
428
|
if (emittedEvent.target instanceof Cesium.Entity) {
|
|
424
429
|
// If feature have been lost at import try to recreate it in order to be compatible with 2D
|
|
430
|
+
// We attach it to the target entity so that we won't compute it each time the mouse move
|
|
431
|
+
// FIXME: should it be a problem with real-time updates ?
|
|
425
432
|
if (!emittedEvent.target.feature) {
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
433
|
+
// Cesium expect id to be in a 'id' property but internally we use _id
|
|
434
|
+
// Get it back as otherwise it might break code relying on feature ID
|
|
435
|
+
let feature = {
|
|
436
|
+
_id: emittedEvent.target.id,
|
|
437
|
+
type: 'Feature'
|
|
438
|
+
}
|
|
439
|
+
// Generate GeoJson feature if possible (requires Cesium 1.59)
|
|
429
440
|
if (typeof Cesium.exportKml === 'function') {
|
|
430
441
|
const selection = new Cesium.EntityCollection()
|
|
431
442
|
selection.add(emittedEvent.target)
|
|
432
|
-
const
|
|
433
|
-
|
|
434
|
-
|
|
443
|
+
const geoJson = await convertEntitiesToGeoJson(selection)
|
|
444
|
+
if (geoJson.features.length > 0) {
|
|
445
|
+
Object.assign(feature, geoJson.features[0])
|
|
446
|
+
}
|
|
435
447
|
}
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
448
|
+
if (!feature.geometry) {
|
|
449
|
+
const position = Cesium.Cartographic.fromCartesian(emittedEvent.target.position
|
|
450
|
+
? emittedEvent.target.position.getValue(0)
|
|
451
|
+
: emittedEvent.pickedPosition)
|
|
452
|
+
feature.geometry = {
|
|
453
|
+
type: 'Point',
|
|
454
|
+
coordinates: [Cesium.Math.toDegrees(position.longitude), Cesium.Math.toDegrees(position.latitude)]
|
|
455
|
+
}
|
|
443
456
|
}
|
|
444
457
|
feature.properties = (emittedEvent.target.properties ? emittedEvent.target.properties.getValue(0) : {})
|
|
445
458
|
emittedEvent.target.feature = feature
|
|
@@ -2,6 +2,7 @@ import Cesium from 'cesium/Source/Cesium.js'
|
|
|
2
2
|
import _ from 'lodash'
|
|
3
3
|
import logger from 'loglevel'
|
|
4
4
|
import sift from 'sift'
|
|
5
|
+
import { uid } from 'quasar'
|
|
5
6
|
import { Time } from '../../../../core/client/time.js'
|
|
6
7
|
import { fetchGeoJson, getFeatureId, processFeatures, getFeatureStyleType, isInMemoryLayer } from '../../utils.js'
|
|
7
8
|
import { convertSimpleStyleToPointStyle, convertSimpleStyleToLineStyle, convertSimpleStyleToPolygonStyle } from '../../utils/utils.style.js'
|
|
@@ -120,6 +121,10 @@ export const geojsonLayers = {
|
|
|
120
121
|
}
|
|
121
122
|
})
|
|
122
123
|
}
|
|
124
|
+
// Billboard with 'none' shape should be removed as Cesium creates it even if the maki icon id is unknown
|
|
125
|
+
if (entity.billboard && (_.get(properties, 'marker-symbol') === 'none')) {
|
|
126
|
+
entitiesToRemove.push(entity)
|
|
127
|
+
}
|
|
123
128
|
// Labels
|
|
124
129
|
const text = _.get(properties, 'icon-text')
|
|
125
130
|
if (text) {
|
|
@@ -197,6 +202,8 @@ export const geojsonLayers = {
|
|
|
197
202
|
if (cesiumOptions.type !== 'geoJson') return
|
|
198
203
|
const engine = _.get(this, 'activityOptions.engine')
|
|
199
204
|
options.processor = (feature) => {
|
|
205
|
+
// File import
|
|
206
|
+
if (!options.featureId && !feature._id) feature._id = uid().toString()
|
|
200
207
|
// Cesium expect id to be in a 'id' property
|
|
201
208
|
feature.id = getFeatureId(feature, options)
|
|
202
209
|
// We cannot access data outside the properties object of a feature in Cesium
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _ from 'lodash'
|
|
2
2
|
import sift from 'sift'
|
|
3
3
|
import logger from 'loglevel'
|
|
4
|
+
import moment from 'moment'
|
|
4
5
|
import L from 'leaflet'
|
|
5
6
|
import Emitter from 'tiny-emitter'
|
|
6
7
|
import 'leaflet/dist/leaflet.css'
|
|
@@ -146,14 +147,20 @@ export const baseMap = {
|
|
|
146
147
|
leafletOptions.attribution = processedOptions.attribution
|
|
147
148
|
return processedOptions
|
|
148
149
|
},
|
|
150
|
+
getLeafletPaneName (paneOrZIndex) {
|
|
151
|
+
return (typeof paneOrZIndex === 'object' ? paneOrZIndex.name || paneOrZIndex.zIndex.toString() : paneOrZIndex.toString())
|
|
152
|
+
},
|
|
149
153
|
createLeafletPane (paneOrZIndex) {
|
|
150
|
-
//
|
|
151
|
-
const paneName =
|
|
154
|
+
// Input can be a name, a z-index, an object with both options
|
|
155
|
+
const paneName = this.getLeafletPaneName(paneOrZIndex)
|
|
152
156
|
let pane = this.map.getPane(paneName)
|
|
157
|
+
// Create pane if required
|
|
153
158
|
if (!pane) {
|
|
159
|
+
let zIndex
|
|
160
|
+
if (typeof paneOrZIndex === 'object') zIndex = paneOrZIndex.zIndex || 400
|
|
161
|
+
else if (typeof paneOrZIndex === 'number') zIndex = paneOrZIndex
|
|
154
162
|
pane = this.map.createPane(paneName)
|
|
155
|
-
|
|
156
|
-
else _.set(pane, 'style.zIndex', 400) // Defaults for overlay in Leaflet
|
|
163
|
+
_.set(pane, 'style.zIndex', zIndex || 400) // Defaults for overlay in Leaflet
|
|
157
164
|
}
|
|
158
165
|
this.leafletPanes[paneName] = pane
|
|
159
166
|
return pane
|
|
@@ -168,12 +175,10 @@ export const baseMap = {
|
|
|
168
175
|
if (!pane) return
|
|
169
176
|
delete this.leafletPanes[paneName]
|
|
170
177
|
},
|
|
171
|
-
updateLeafletPanesVisibility (
|
|
178
|
+
updateLeafletPanesVisibility () {
|
|
172
179
|
const zoom = this.map.getZoom()
|
|
173
180
|
// Check if we need to hide/show some panes based on current zoom level
|
|
174
181
|
_.forOwn(this.leafletPanes, (pane, paneName) => {
|
|
175
|
-
// Filter only some panes ?
|
|
176
|
-
if (panes && panes.includes(paneName)) return
|
|
177
182
|
const hasMinZoom = !!_.get(pane, 'minZoom')
|
|
178
183
|
const hasMaxZoom = !!_.get(pane, 'maxZoom')
|
|
179
184
|
if (!hasMinZoom && !hasMaxZoom) return
|
|
@@ -207,10 +212,10 @@ export const baseMap = {
|
|
|
207
212
|
const panes = _.get(leafletOptions, 'panes')
|
|
208
213
|
if (panes) {
|
|
209
214
|
panes.forEach(paneOptions => {
|
|
210
|
-
const pane = this.createLeafletPane(paneOptions
|
|
215
|
+
const pane = this.createLeafletPane(paneOptions)
|
|
211
216
|
Object.assign(pane, paneOptions)
|
|
212
217
|
})
|
|
213
|
-
this.updateLeafletPanesVisibility(
|
|
218
|
+
this.updateLeafletPanesVisibility()
|
|
214
219
|
}
|
|
215
220
|
|
|
216
221
|
// Some Leaflet constructors can have additional arguments given as options
|
|
@@ -256,19 +261,36 @@ export const baseMap = {
|
|
|
256
261
|
if (timeDimension) {
|
|
257
262
|
// It appears that sometimes the time resolution is missing, default as 1 day
|
|
258
263
|
// Please refer to https://www.mapserver.org/ogc/wms_time.html#specifying-time-extents
|
|
264
|
+
_.set(timeDimension, 'period', 'P1D')
|
|
259
265
|
const timeRange = _.get(timeDimension, 'times')
|
|
260
|
-
|
|
266
|
+
const timeRangeComponents = (typeof timeRange === 'string' ? timeRange.split('/') : [])
|
|
267
|
+
if (timeRangeComponents.length === 2) {
|
|
261
268
|
_.set(timeDimension, 'times', `${timeRange}/P1D`)
|
|
269
|
+
} else if (timeRangeComponents.length === 3) {
|
|
270
|
+
_.set(timeDimension, 'period', timeRangeComponents[2])
|
|
262
271
|
}
|
|
272
|
+
// Used to format time accordingly
|
|
273
|
+
const periodAsDuration = moment.duration(_.get(timeDimension, 'period'))
|
|
263
274
|
// As we'd like to control time on a per-layer basis create a specific time dimension object
|
|
264
275
|
layer = this.createLeafletLayer({
|
|
265
276
|
type: 'timeDimension.layer.wms',
|
|
266
277
|
source: layer,
|
|
267
278
|
timeDimension: L.timeDimension(timeDimension),
|
|
268
|
-
currentTime: Time.getCurrentTime()
|
|
279
|
+
currentTime: Time.getCurrentTime().toDate().getTime()
|
|
269
280
|
})
|
|
270
281
|
// This allow the layer to conform our internal time interface
|
|
271
|
-
layer.setCurrentTime = (datetime) => { layer._timeDimension.setCurrentTime(datetime) }
|
|
282
|
+
layer.setCurrentTime = (datetime) => { layer._timeDimension.setCurrentTime(datetime.toDate().getTime()) }
|
|
283
|
+
// Default implementation always generate ISO datetime that might break some servers with eg day period only
|
|
284
|
+
layer._createLayerForTime = (time) => {
|
|
285
|
+
// Remove some internals to avoid polluting request
|
|
286
|
+
const wmsParams = _.omit(layer._baseLayer.options, ['timeDimension', 'isVisible', 'type'])
|
|
287
|
+
// Format time according to period
|
|
288
|
+
if (periodAsDuration.years() > 0) wmsParams.time = moment.utc(time).format('YYYY').toISOString()
|
|
289
|
+
else if (periodAsDuration.months() > 0) wmsParams.time = moment.utc(time).format('YYYY-MM')
|
|
290
|
+
else if (periodAsDuration.days() > 0) wmsParams.time = moment.utc(time).format('YYYY-MM-DD')
|
|
291
|
+
else wmsParams.time = moment.utc(time).toISOString()
|
|
292
|
+
return new layer._baseLayer.constructor(layer._baseLayer.getURL(), wmsParams)
|
|
293
|
+
}
|
|
272
294
|
}
|
|
273
295
|
return layer
|
|
274
296
|
},
|
|
@@ -289,11 +311,12 @@ export const baseMap = {
|
|
|
289
311
|
},
|
|
290
312
|
updateLayerDisabled (layer) {
|
|
291
313
|
const wasDisabled = layer.isDisabled
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
314
|
+
const isDisabled = this.isLayerDisabled(layer)
|
|
315
|
+
// Test if state changed
|
|
316
|
+
if (wasDisabled === isDisabled) return
|
|
317
|
+
layer.isDisabled = isDisabled
|
|
318
|
+
if (wasDisabled) this.onLayerEnabled(layer)
|
|
319
|
+
else this.onLayerDisabled(layer)
|
|
297
320
|
},
|
|
298
321
|
onLayerEnabled (layer) {
|
|
299
322
|
this.$emit('layer-enabled', layer)
|
|
@@ -267,9 +267,13 @@ export const geojsonLayers = {
|
|
|
267
267
|
leafletOptions.panes = [pane]
|
|
268
268
|
leafletOptions.pane = options.name
|
|
269
269
|
leafletOptions.shadowPane = options.name
|
|
270
|
-
// Make pane available to
|
|
271
|
-
|
|
272
|
-
|
|
270
|
+
// Make pane available to styles as well as eg shape markers are created from here
|
|
271
|
+
for (const type in ['point', 'line', 'polygon']) {
|
|
272
|
+
if (_.has(leafletOptions, `style.${type}`)) {
|
|
273
|
+
_.set(leafletOptions, `style.${type}.pane`, options.name)
|
|
274
|
+
_.set(leafletOptions, `style.${type}.shadowPane`, options.name)
|
|
275
|
+
}
|
|
276
|
+
}
|
|
273
277
|
}
|
|
274
278
|
// If not explicitely disable use defaults for clustering
|
|
275
279
|
if (!_.has(leafletOptions, 'cluster') && _.get(this, 'activityOptions.engine.cluster')) {
|
|
@@ -239,12 +239,16 @@ export const activity = {
|
|
|
239
239
|
// Check if the activity is using context restoration
|
|
240
240
|
const hasContext = (typeof this.restoreContext === 'function')
|
|
241
241
|
// Retrieve the forecast models
|
|
242
|
-
|
|
242
|
+
const weacastEnabled = _.get(config, 'weacast.enabled', true)
|
|
243
|
+
if (weacastEnabled && this.setupWeacast) {
|
|
243
244
|
try {
|
|
244
245
|
await this.setupWeacast()
|
|
245
246
|
} catch (error) {
|
|
246
247
|
logger.error(`[KDK] ${error}`)
|
|
247
248
|
}
|
|
249
|
+
} else {
|
|
250
|
+
if (weacastEnabled) logger.warn('[KDK] Weacast setup function is missing')
|
|
251
|
+
else logger.debug('[KDK] disabling Weacast')
|
|
248
252
|
}
|
|
249
253
|
// Retrieve the layers
|
|
250
254
|
try {
|
package/map/client/planets.js
CHANGED
|
@@ -33,6 +33,10 @@ export const Planets = {
|
|
|
33
33
|
client.get('storage').removeItem(options.gatewayJwt)
|
|
34
34
|
})
|
|
35
35
|
const accessToken = await client.get('storage').getItem(options.apiJwt)
|
|
36
|
+
if (!accessToken) {
|
|
37
|
+
logger.error(new Error(`You must set planet ${name} token first`))
|
|
38
|
+
return
|
|
39
|
+
}
|
|
36
40
|
await client.authenticate({
|
|
37
41
|
strategy: 'jwt',
|
|
38
42
|
accessToken
|
|
@@ -46,6 +50,10 @@ export const Planets = {
|
|
|
46
50
|
delete this.planets[name]
|
|
47
51
|
},
|
|
48
52
|
|
|
53
|
+
isConnected (name) {
|
|
54
|
+
return !_.isNil(this.planets[name])
|
|
55
|
+
},
|
|
56
|
+
|
|
49
57
|
get (name) {
|
|
50
58
|
if (!this.planets[name]) logger.error(new Error(`You must connect to planet ${name} first`))
|
|
51
59
|
else return this.planets[name]
|
|
@@ -131,6 +131,23 @@ export async function getCategories (options = {}) {
|
|
|
131
131
|
return categories
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
+
export async function getSublegends (options = {}) {
|
|
135
|
+
_.defaults(options, {
|
|
136
|
+
query: {},
|
|
137
|
+
context: '',
|
|
138
|
+
planetApi: api
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
let sublegends = []
|
|
142
|
+
const catalogService = options.planetApi.getService('catalog', options.context)
|
|
143
|
+
if (catalogService) {
|
|
144
|
+
const response = await catalogService.find({ query: Object.assign({ type: 'Sublegend' }, options.query) })
|
|
145
|
+
_.forEach(response.data, processTranslations)
|
|
146
|
+
sublegends = sublegends.concat(response.data)
|
|
147
|
+
}
|
|
148
|
+
return sublegends
|
|
149
|
+
}
|
|
150
|
+
|
|
134
151
|
export async function getViews (options = {}) {
|
|
135
152
|
_.defaults(options, {
|
|
136
153
|
query: {},
|
|
@@ -138,7 +138,8 @@ export async function saveGeoJsonLayer (layer, geoJson, chunkSize = 5000) {
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
export async function saveLayer (layer) {
|
|
141
|
-
await api.getService('catalog').create(_.omit(layer, InternalLayerProperties))
|
|
141
|
+
layer = await api.getService('catalog').create(_.omit(layer, InternalLayerProperties))
|
|
142
|
+
return layer
|
|
142
143
|
}
|
|
143
144
|
|
|
144
145
|
export async function removeLayer (layer) {
|
|
@@ -44,31 +44,3 @@ export function generatePropertiesSchema (geoJson, name) {
|
|
|
44
44
|
})
|
|
45
45
|
return schema
|
|
46
46
|
}
|
|
47
|
-
|
|
48
|
-
export function updatePropertiesSchema (schema) {
|
|
49
|
-
const props = schema.properties
|
|
50
|
-
if (!props) return
|
|
51
|
-
|
|
52
|
-
const bestGuesses = {
|
|
53
|
-
undefined: 'form/KTextField',
|
|
54
|
-
object: 'form/KTextField',
|
|
55
|
-
string: 'form/KTextField',
|
|
56
|
-
number: 'form/KNumberField',
|
|
57
|
-
boolean: 'form/KToggleField'
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Loop over declared props and add best guesses to field components based on property type
|
|
61
|
-
for (const prop in props) {
|
|
62
|
-
const propEntry = props[prop]
|
|
63
|
-
// Field already here, skip entry
|
|
64
|
-
if (propEntry.field && propEntry.field.component) continue
|
|
65
|
-
|
|
66
|
-
propEntry.field = {
|
|
67
|
-
component: bestGuesses[propEntry.type],
|
|
68
|
-
label: prop,
|
|
69
|
-
helper: propEntry.description
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return schema
|
|
74
|
-
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import _ from 'lodash'
|
|
2
|
+
import { getCssVar } from 'quasar'
|
|
2
3
|
import { utils as kdkCoreUtils } from '../../../core/client/index.js'
|
|
3
4
|
|
|
4
5
|
export const IconStyleToSimpleStyle = {
|
|
@@ -149,6 +150,17 @@ export function convertStyle (style, mapping, asNumber = []) {
|
|
|
149
150
|
return convertedStyle
|
|
150
151
|
}
|
|
151
152
|
|
|
153
|
+
export function convertSimpleStyleColors (style) {
|
|
154
|
+
// Convert from quasar color palette to actual color
|
|
155
|
+
_.forOwn(style, (value, key) => {
|
|
156
|
+
if (['stroke', 'fill', 'marker-color'].includes(key)) {
|
|
157
|
+
const color = getCssVar(value)
|
|
158
|
+
if (color) _.set(style, key, color)
|
|
159
|
+
}
|
|
160
|
+
})
|
|
161
|
+
return style
|
|
162
|
+
}
|
|
163
|
+
|
|
152
164
|
export function convertPointStyleToSimpleStyle (style) {
|
|
153
165
|
return style ? Object.assign(convertStyle(style.icon, IconStyleToSimpleStyle, SimpleStyleNumbers), convertStyle(style, PointStyleToSimpleStyle, SimpleStyleNumbers)) : {}
|
|
154
166
|
}
|
package/map/common/wms-utils.js
CHANGED
|
@@ -96,15 +96,20 @@ export async function discover (url, searchParams = {}, caps = null) {
|
|
|
96
96
|
// check for time dimension
|
|
97
97
|
for (const dimension of _.get(layer, 'Dimension', [])) {
|
|
98
98
|
if (_.get(dimension, '$.name', '').toLowerCase() === 'time') {
|
|
99
|
-
_.
|
|
99
|
+
const timeRange = _.get(dimension, '_')
|
|
100
|
+
// If time range is not given in dimension it should be in extent
|
|
101
|
+
if (timeRange) _.set(obj, 'timeDimension.times', timeRange.trim())
|
|
102
|
+
else if (!_.has(obj, 'timeDimension')) _.set(obj, 'timeDimension', {})
|
|
100
103
|
}
|
|
101
104
|
}
|
|
102
105
|
// check for time range
|
|
103
106
|
if (obj.timeDimension) {
|
|
104
107
|
for (const extent of _.get(layer, 'Extent', [])) {
|
|
105
108
|
if (_.get(extent, '$.name', '').toLowerCase() === 'time') {
|
|
106
|
-
const timeRange = _.get(extent, '_'
|
|
107
|
-
|
|
109
|
+
const timeRange = _.get(extent, '_')
|
|
110
|
+
// If time range is not given in extent it should be in dimension
|
|
111
|
+
if (timeRange) _.set(obj, 'timeDimension.times', timeRange.trim())
|
|
112
|
+
else if (!_.has(obj, 'timeDimension')) _.set(obj, 'timeDimension', {})
|
|
108
113
|
}
|
|
109
114
|
}
|
|
110
115
|
}
|
package/package.json
CHANGED
|
@@ -119,7 +119,7 @@ export async function dropFile (page, filePath, wait = 2000) {
|
|
|
119
119
|
const loaderSelector = '#dropFileInput'
|
|
120
120
|
const loader = await page.$(loaderSelector)
|
|
121
121
|
await loader.uploadFile(filePath)
|
|
122
|
-
await page.waitForNetworkIdle()
|
|
122
|
+
await page.waitForNetworkIdle()
|
|
123
123
|
await page.waitForTimeout(wait)
|
|
124
124
|
}
|
|
125
125
|
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{"level":"info","message":"This is a log test"}
|
|
2
|
-
{"level":"error","message":"error: api/tags - Method: create: You are not allowed to access service tags"}
|
|
3
|
-
{"level":"error","message":"error: api/users - Method: create: The provided password does not comply to the password policy"}
|
|
4
|
-
{"level":"error","message":"error: api/users - Method: create: The provided password does not comply to the password policy"}
|
|
5
|
-
{"level":"error","message":"error: api/authorisations - Method: create: You are not allowed to change authorisation on resource"}
|
|
6
|
-
{"level":"error","message":"error: api/authorisations - Method: remove: You are not allowed to change authorisation on subject(s)"}
|
|
7
|
-
{"level":"info","message":"This is a log test"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{"level":"error","message":"error: api/account - Method: create: The provided password does not comply to the password policy"}
|
|
2
|
-
{"level":"error","message":"error: api/account - Method: create: The provided password does not comply to the password policy"}
|
|
3
|
-
{"level":"error","message":"error: api/account - Method: create: The provided password does not comply to the password policy"}
|
|
4
|
-
{"level":"error","message":"error: api/account - Method: create: The provided password does not comply to the password policy"}
|
|
5
|
-
{"level":"error","message":"error: api/account - Method: create: The provided password does not comply to the password policy"}
|
|
6
|
-
{"level":"error","message":"error: api/account - Method: create: The provided password does not comply to the password policy"}
|
|
7
|
-
{"level":"error","message":"error: api/account - Method: create: The provided password does not comply to the password policy"}
|
|
8
|
-
{"level":"error","message":"error: api/account - Method: create: The provided password does not comply to the password policy"}
|
|
9
|
-
{"level":"error","message":"error: api/account - Method: create: The provided password does not comply to the password policy"}
|
|
10
|
-
{"level":"error","message":"error: api/account - Method: create: The provided password does not comply to the password policy"}
|
|
11
|
-
{"level":"error","message":"error: api/account - Method: create: The provided password does not comply to the password policy"}
|
|
12
|
-
{"level":"error","message":"error: api/account - Method: create: The provided password does not comply to the password policy"}
|
|
13
|
-
{"level":"error","message":"error: api/account - Method: create: The provided password does not comply to the password policy"}
|
|
14
|
-
{"level":"error","message":"error: api/account - Method: create: The provided password does not comply to the password policy"}
|