@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.
- 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 +16 -22
- 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 +91 -23
- package/core/client/i18n/core_fr.json +92 -23
- 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/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 +12 -9
- 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-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-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,25 +1,75 @@
|
|
|
1
1
|
import Cesium from 'cesium/Source/Cesium.js'
|
|
2
2
|
import _ from 'lodash'
|
|
3
|
+
import logger from 'loglevel'
|
|
3
4
|
import sift from 'sift'
|
|
4
5
|
import { Time } from '../../../../core/client/time.js'
|
|
5
|
-
import { fetchGeoJson, getFeatureId } from '../../utils.js'
|
|
6
|
+
import { fetchGeoJson, getFeatureId, processFeatures, getFeatureStyleType, isInMemoryLayer } from '../../utils.js'
|
|
7
|
+
import { convertSimpleStyleToPointStyle, convertSimpleStyleToLineStyle, convertSimpleStyleToPolygonStyle } from '../../utils/utils.style.js'
|
|
8
|
+
import { convertToCesiumFromSimpleStyle, getPointSimpleStyle, getLineSimpleStyle, getPolygonSimpleStyle } from '../../cesium/utils/utils.style.js'
|
|
9
|
+
|
|
10
|
+
function getWallEntityId (id) {
|
|
11
|
+
return id + '-wall'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function updateGeoJsonEntity(source, destination) {
|
|
15
|
+
destination.position = source.position
|
|
16
|
+
destination.orientation = source.orientation
|
|
17
|
+
destination.properties = source.properties
|
|
18
|
+
destination.description = source.description
|
|
19
|
+
// Points
|
|
20
|
+
if (source.billboard) destination.billboard = source.billboard
|
|
21
|
+
// Lines
|
|
22
|
+
if (source.polyline) destination.polyline = source.polyline
|
|
23
|
+
// Polygons
|
|
24
|
+
if (source.polygon) destination.polygon = source.polygon
|
|
25
|
+
}
|
|
6
26
|
|
|
7
27
|
export const geojsonLayers = {
|
|
8
28
|
methods: {
|
|
9
|
-
|
|
10
|
-
let { stroke, strokeWidth, fill } =
|
|
29
|
+
convertFromSimpleStyleOrDefaults (properties) {
|
|
30
|
+
let { stroke, strokeWidth, fill } = convertToCesiumFromSimpleStyle(properties)
|
|
11
31
|
if (!stroke) stroke = Cesium.GeoJsonDataSource.stroke
|
|
12
32
|
if (!strokeWidth) strokeWidth = Cesium.GeoJsonDataSource.strokeWidth
|
|
13
33
|
if (!fill) fill = Cesium.GeoJsonDataSource.fill
|
|
14
34
|
return { stroke, strokeWidth, fill }
|
|
15
35
|
},
|
|
16
|
-
async loadGeoJson (dataSource, geoJson,
|
|
17
|
-
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
36
|
+
async loadGeoJson (dataSource, geoJson, options, updateOptions = {}) {
|
|
37
|
+
const cesiumOptions = options.cesium
|
|
38
|
+
// Remove mode
|
|
39
|
+
if (_.get(updateOptions, 'remove', false)) {
|
|
40
|
+
let features = (geoJson.type === 'FeatureCollection' ? geoJson.features : [geoJson])
|
|
41
|
+
features.forEach(feature => {
|
|
42
|
+
const id = getFeatureId(feature, options)
|
|
43
|
+
const wallId = getWallEntityId(id)
|
|
44
|
+
if (dataSource.entities.getById(id)) dataSource.entities.removeById(id)
|
|
45
|
+
// Take care that in case of a wall entity we add it in addition to the original line
|
|
46
|
+
if (dataSource.entities.getById(wallId)) dataSource.entities.removeById(wallId)
|
|
47
|
+
})
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
// We use a separated source in order to load data otherwise Cesium will replace previous ones, causing flickering
|
|
51
|
+
const loadingDataSource = new Cesium.GeoJsonDataSource()
|
|
52
|
+
loadingDataSource.notFromDrop = true
|
|
53
|
+
await loadingDataSource.load(geoJson, cesiumOptions)
|
|
54
|
+
// Now we process loaded entities to merge with existing ones if any or add new ones
|
|
55
|
+
let entities = loadingDataSource.entities.values
|
|
56
|
+
entities.forEach(entity => {
|
|
57
|
+
const previousEntity = dataSource.entities.getById(entity.id)
|
|
58
|
+
if (previousEntity) updateGeoJsonEntity(entity, previousEntity)
|
|
59
|
+
else dataSource.entities.add(entity)
|
|
60
|
+
})
|
|
61
|
+
// Remove any entity not existing anymore
|
|
62
|
+
if (_.get(updateOptions, 'removeMissing', cesiumOptions.removeMissing)) {
|
|
63
|
+
dataSource.entities.values.forEach(entity => {
|
|
64
|
+
const id = entity.id
|
|
65
|
+
const wallId = getWallEntityId(id)
|
|
66
|
+
if (!loadingDataSource.entities.getById(id)) dataSource.entities.removeById(id)
|
|
67
|
+
// Take care that in case of a wall entity we add it in addition to the original line
|
|
68
|
+
if (dataSource.entities.getById(wallId)) dataSource.entities.removeById(wallId)
|
|
69
|
+
})
|
|
70
|
+
}
|
|
21
71
|
// Process specific entities
|
|
22
|
-
|
|
72
|
+
entities = dataSource.entities.values
|
|
23
73
|
const entitiesToAdd = []
|
|
24
74
|
const entitiesToRemove = []
|
|
25
75
|
for (let i = 0; i < entities.length; i++) {
|
|
@@ -29,7 +79,7 @@ export const geojsonLayers = {
|
|
|
29
79
|
const radius = _.get(properties, 'radius')
|
|
30
80
|
const geodesic = _.get(properties, 'geodesic')
|
|
31
81
|
if (radius && geodesic) {
|
|
32
|
-
const { stroke, strokeWidth, fill } = this.
|
|
82
|
+
const { stroke, strokeWidth, fill } = this.convertFromSimpleStyleOrDefaults(properties)
|
|
33
83
|
// This one will replace the original point
|
|
34
84
|
entitiesToAdd.push({
|
|
35
85
|
id: entity.id,
|
|
@@ -51,13 +101,14 @@ export const geojsonLayers = {
|
|
|
51
101
|
// Walls
|
|
52
102
|
const wall = _.get(properties, 'wall')
|
|
53
103
|
if (wall && entity.polyline) {
|
|
54
|
-
const { stroke, strokeWidth, fill } = this.
|
|
104
|
+
const { stroke, strokeWidth, fill } = this.convertFromSimpleStyleOrDefaults(properties)
|
|
55
105
|
// Simply push the entity, other options like font will be set using styling options
|
|
56
106
|
// This one will come in addition to the original line
|
|
107
|
+
const wallId = getWallEntityId(entity.id)
|
|
57
108
|
entitiesToAdd.push({
|
|
58
|
-
id:
|
|
109
|
+
id: wallId,
|
|
59
110
|
parent: entity,
|
|
60
|
-
name: entity.name,
|
|
111
|
+
name: entity.name ? entity.name : wallId,
|
|
61
112
|
description: entity.description.getValue(0),
|
|
62
113
|
properties: entity.properties.getValue(0),
|
|
63
114
|
wall: {
|
|
@@ -72,13 +123,13 @@ export const geojsonLayers = {
|
|
|
72
123
|
// Labels
|
|
73
124
|
const text = _.get(properties, 'icon-text')
|
|
74
125
|
if (text) {
|
|
75
|
-
const { stroke, strokeWidth, fill } = this.
|
|
126
|
+
const { stroke, strokeWidth, fill } = this.convertFromSimpleStyleOrDefaults(properties)
|
|
76
127
|
// Simply push the entity, other options like font will be set using styling options
|
|
77
128
|
// This one will replace the original point
|
|
78
129
|
entitiesToAdd.push({
|
|
79
130
|
id: entity.id,
|
|
80
131
|
position: entity.position.getValue(0),
|
|
81
|
-
name: entity.name,
|
|
132
|
+
name: entity.name ? entity.name : entity.id,
|
|
82
133
|
description: entity.description.getValue(0),
|
|
83
134
|
properties: entity.properties.getValue(0),
|
|
84
135
|
label: {
|
|
@@ -94,52 +145,46 @@ export const geojsonLayers = {
|
|
|
94
145
|
entitiesToRemove.forEach(entity => dataSource.entities.remove(entity))
|
|
95
146
|
entitiesToAdd.forEach(entity => dataSource.entities.add(entity))
|
|
96
147
|
},
|
|
97
|
-
async updateGeoJsonData (dataSource, options, geoJson) {
|
|
148
|
+
async updateGeoJsonData (dataSource, options, geoJson, updateOptions = {}) {
|
|
149
|
+
// As we have async operations during the whole whole loading process avoid reentrance
|
|
150
|
+
// otherwise we might have interleaved calls leading to doublon entities being created
|
|
151
|
+
//if (dataSource.updatingGeoJsonData) return
|
|
152
|
+
//dataSource.updatingGeoJsonData = true
|
|
98
153
|
const cesiumOptions = options.cesium
|
|
99
154
|
const source = _.get(cesiumOptions, 'source')
|
|
100
155
|
const sourceTemplate = _.get(cesiumOptions, 'sourceTemplate')
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
probe.properties = measure.properties
|
|
117
|
-
probe.description = measure.description
|
|
156
|
+
try {
|
|
157
|
+
if (geoJson) {
|
|
158
|
+
if (options.processor) processFeatures(geoJson, options.processor)
|
|
159
|
+
await this.loadGeoJson(dataSource, geoJson, options, updateOptions)
|
|
160
|
+
} else if (options.probeService) {
|
|
161
|
+
await this.loadGeoJson(dataSource, this.getProbeFeatures(options), options, updateOptions)
|
|
162
|
+
await this.loadGeoJson(dataSource, this.getFeatures(options), options, updateOptions)
|
|
163
|
+
} else if (options.service) { // Check for feature service layers only, in this case update in place
|
|
164
|
+
// If no probe reference, nothing to be initialized
|
|
165
|
+
await this.loadGeoJson(dataSource, this.getFeatures(options), options, updateOptions)
|
|
166
|
+
} else if (sourceTemplate) {
|
|
167
|
+
const sourceToFetch = dataSource.sourceCompiler({ time: Time.getCurrentTime() })
|
|
168
|
+
if (!dataSource.lastFetchedSource || (dataSource.lastFetchedSource !== sourceToFetch)) {
|
|
169
|
+
dataSource.lastFetchedSource = sourceToFetch
|
|
170
|
+
await this.loadGeoJson(dataSource, fetchGeoJson(sourceToFetch, options), options, updateOptions)
|
|
118
171
|
}
|
|
172
|
+
} else if (!_.isNil(source)) {
|
|
173
|
+
// Assume source is an URL returning GeoJson
|
|
174
|
+
await this.loadGeoJson(dataSource, fetchGeoJson(source, options), options, updateOptions)
|
|
119
175
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
await this.loadGeoJson(dataSource, geoJson, cesiumOptions)
|
|
125
|
-
} else if (sourceTemplate) {
|
|
126
|
-
const sourceToFetch = dataSource.sourceCompiler({ time: Time.getCurrentTime() })
|
|
127
|
-
if (!dataSource.lastFetchedSource || (dataSource.lastFetchedSource !== sourceToFetch)) {
|
|
128
|
-
dataSource.lastFetchedSource = sourceToFetch
|
|
129
|
-
await this.loadGeoJson(dataSource, fetchGeoJson(sourceToFetch, options), cesiumOptions)
|
|
130
|
-
}
|
|
131
|
-
} else if (!_.isNil(source)) {
|
|
132
|
-
// Assume source is an URL returning GeoJson
|
|
133
|
-
await this.loadGeoJson(dataSource, fetchGeoJson(source, options), cesiumOptions)
|
|
176
|
+
this.applyStyle(dataSource.entities, options)
|
|
177
|
+
if (typeof this.applyTooltips === 'function') this.applyTooltips(dataSource.entities, options)
|
|
178
|
+
} catch (error) {
|
|
179
|
+
logger.error(error)
|
|
134
180
|
}
|
|
135
|
-
|
|
136
|
-
if (typeof this.applyTooltips === 'function') this.applyTooltips(dataSource.entities, options)
|
|
181
|
+
//delete dataSource.updatingGeoJsonData
|
|
137
182
|
},
|
|
138
183
|
async createCesiumRealtimeGeoJsonLayer (dataSource, options) {
|
|
139
184
|
const cesiumOptions = options.cesium
|
|
140
185
|
// Add update capabilities
|
|
141
|
-
dataSource.updateGeoJson = async (geoJson) => {
|
|
142
|
-
await this.updateGeoJsonData(dataSource, options, geoJson)
|
|
186
|
+
dataSource.updateGeoJson = async (geoJson, updateOptions) => {
|
|
187
|
+
await this.updateGeoJsonData(dataSource, options, geoJson, updateOptions)
|
|
143
188
|
}
|
|
144
189
|
// Add source compiler if required
|
|
145
190
|
if (_.has(cesiumOptions, 'sourceTemplate')) {
|
|
@@ -150,22 +195,34 @@ export const geojsonLayers = {
|
|
|
150
195
|
const cesiumOptions = options.cesium
|
|
151
196
|
// Check for valid type
|
|
152
197
|
if (cesiumOptions.type !== 'geoJson') return
|
|
153
|
-
|
|
198
|
+
const engine = _.get(this, 'activityOptions.engine')
|
|
154
199
|
options.processor = (feature) => {
|
|
200
|
+
// Cesium expect id to be in a 'id' property
|
|
155
201
|
feature.id = getFeatureId(feature, options)
|
|
202
|
+
// We cannot access data outside the properties object of a feature in Cesium
|
|
203
|
+
// As a consequence we copy back any style information inside
|
|
204
|
+
const styleType = getFeatureStyleType(feature)
|
|
205
|
+
// We need to convert to simple-style spec as cesium manages this only
|
|
206
|
+
let simpleStyle
|
|
207
|
+
if (styleType === 'point') simpleStyle = getPointSimpleStyle(feature, options, engine)
|
|
208
|
+
else if (styleType === 'line') simpleStyle = getLineSimpleStyle(feature, options, engine)
|
|
209
|
+
else simpleStyle = getPolygonSimpleStyle(feature, options, engine)
|
|
210
|
+
if (!feature.properties) feature.properties = simpleStyle
|
|
211
|
+
else Object.assign(feature.properties, simpleStyle)
|
|
156
212
|
}
|
|
157
213
|
// For activities
|
|
158
214
|
if (_.has(this, 'activityOptions.engine.cluster')) {
|
|
159
215
|
if (cesiumOptions.cluster) Object.assign(cesiumOptions.cluster, _.get(this, 'activityOptions.engine.cluster'))
|
|
160
216
|
else cesiumOptions.cluster = Object.assign({}, _.get(this, 'activityOptions.engine.cluster'))
|
|
161
217
|
}
|
|
162
|
-
// Merge generic GeoJson options and layer options
|
|
163
|
-
const geoJsonOptions = this.getGeoJsonOptions(options)
|
|
164
|
-
Object.keys(geoJsonOptions).forEach(key => {
|
|
165
|
-
// If layer provided do not override
|
|
166
|
-
if (!_.has(cesiumOptions, key)) _.set(cesiumOptions, key, geoJsonOptions[key])
|
|
167
|
-
})
|
|
168
218
|
// Optimize templating by creating compilers up-front
|
|
219
|
+
const layerStyleTemplate = _.get(cesiumOptions, 'template')
|
|
220
|
+
if (layerStyleTemplate) {
|
|
221
|
+
// We allow to template style properties according to feature, because it can be slow you have to specify a subset of properties
|
|
222
|
+
cesiumOptions.template = layerStyleTemplate.map(property => ({
|
|
223
|
+
property, compiler: _.template(_.get(cesiumOptions, property))
|
|
224
|
+
}))
|
|
225
|
+
}
|
|
169
226
|
const entityStyleTemplate = _.get(cesiumOptions, 'entityStyle.template')
|
|
170
227
|
if (entityStyleTemplate) {
|
|
171
228
|
// We allow to template style properties according to feature, because it can be slow you have to specify a subset of properties
|
|
@@ -181,7 +238,16 @@ export const geojsonLayers = {
|
|
|
181
238
|
if (tooltipTemplate) {
|
|
182
239
|
cesiumOptions.tooltip.compiler = _.template(tooltipTemplate)
|
|
183
240
|
}
|
|
184
|
-
|
|
241
|
+
// Convert and store the style
|
|
242
|
+
if (cesiumOptions.style) {
|
|
243
|
+
cesiumOptions.layerPointStyle = _.get(cesiumOptions.style, 'point')
|
|
244
|
+
cesiumOptions.layerLineStyle = _.get(cesiumOptions.style, 'line')
|
|
245
|
+
cesiumOptions.layerPolygonStyle = _.get(cesiumOptions.style, 'polygon')
|
|
246
|
+
} else {
|
|
247
|
+
cesiumOptions.layerPointStyle = convertSimpleStyleToPointStyle(cesiumOptions)
|
|
248
|
+
cesiumOptions.layerLineStyle = convertSimpleStyleToLineStyle(cesiumOptions)
|
|
249
|
+
cesiumOptions.layerPolygonStyle = convertSimpleStyleToPolygonStyle(cesiumOptions)
|
|
250
|
+
}
|
|
185
251
|
// Perform required conversion from JSON to Cesium objects
|
|
186
252
|
// If templating occurs we need to wait until it is performed to convert to Cesium objects
|
|
187
253
|
if (cesiumOptions.entityStyle && !entityStyleTemplate) cesiumOptions.entityStyle = this.convertToCesiumObjects(cesiumOptions.entityStyle)
|
|
@@ -236,17 +302,17 @@ export const geojsonLayers = {
|
|
|
236
302
|
getGeoJsonOptions (options) {
|
|
237
303
|
return _.get(this, 'activityOptions.engine.featureStyle', {})
|
|
238
304
|
},
|
|
239
|
-
async updateLayer (name, geoJson) {
|
|
305
|
+
async updateLayer (name, geoJson, updateOptions = {}) {
|
|
240
306
|
// Retrieve the layer
|
|
241
307
|
const layer = this.getCesiumLayerByName(name)
|
|
242
308
|
if (!layer) return // Cannot update invisible layer
|
|
243
|
-
if (typeof layer.updateGeoJson === 'function') layer.updateGeoJson(geoJson)
|
|
309
|
+
if (typeof layer.updateGeoJson === 'function') layer.updateGeoJson(geoJson, updateOptions)
|
|
244
310
|
|
|
245
311
|
// We keep geojson data for in memory layer in a cache since
|
|
246
312
|
// these layers will be destroyed when hidden. We need to be able to restore
|
|
247
313
|
// them when they get shown again
|
|
248
314
|
const baseLayer = this.getLayerByName(name)
|
|
249
|
-
if (
|
|
315
|
+
if (isInMemoryLayer(baseLayer)) {
|
|
250
316
|
this.geojsonCache[name] = geoJson
|
|
251
317
|
}
|
|
252
318
|
},
|
|
@@ -274,7 +340,7 @@ export const geojsonLayers = {
|
|
|
274
340
|
// Check if we have cached geojson data for this layer
|
|
275
341
|
const cachedGeojson = this.geojsonCache[layer.name]
|
|
276
342
|
if (cachedGeojson) {
|
|
277
|
-
if (
|
|
343
|
+
if (isInMemoryLayer(layer)) {
|
|
278
344
|
// Restore geojson data for in-memory layers that was hidden
|
|
279
345
|
this.updateLayer(layer.name, cachedGeojson)
|
|
280
346
|
} else {
|
|
@@ -292,15 +358,12 @@ export const geojsonLayers = {
|
|
|
292
358
|
},
|
|
293
359
|
created () {
|
|
294
360
|
this.registerCesiumConstructor(this.createCesiumGeoJsonLayer)
|
|
295
|
-
// Perform required conversion from JSON to Cesium objects
|
|
296
|
-
if (_.has(this, 'activityOptions.engine.featureStyle')) {
|
|
297
|
-
Object.assign(Cesium.GeoJsonDataSource,
|
|
298
|
-
this.convertFromSimpleStyleSpec(_.get(this, 'activityOptions.engine.featureStyle'), 'update-in-place'))
|
|
299
|
-
}
|
|
300
361
|
this.$events.on('time-current-time-changed', this.onCurrentTimeChangedGeoJsonLayers)
|
|
301
362
|
this.$engineEvents.on('layer-shown', this.onLayerShownGeoJsonLayers)
|
|
302
363
|
this.$engineEvents.on('layer-removed', this.onLayerRemovedGeoJsonLayers)
|
|
303
|
-
|
|
364
|
+
// Map of currently updated layers to avoid reentrance with real-time events as
|
|
365
|
+
// we are not able to perform in place update and required to pull the data
|
|
366
|
+
this.updatingGeoJsonData = {}
|
|
304
367
|
// Cache where we'll store geojson data for in memory layers we'll hide
|
|
305
368
|
this.geojsonCache = {}
|
|
306
369
|
},
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import _ from 'lodash'
|
|
2
|
+
import moment from 'moment'
|
|
2
3
|
import { Time, Units } from '../../../../core/client/index.js'
|
|
3
4
|
import { getTextTable } from '../../utils.globe.js'
|
|
4
5
|
|
|
@@ -23,7 +24,7 @@ export const popup = {
|
|
|
23
24
|
if (popupStyle.template) {
|
|
24
25
|
const compiler = popupStyle.compiler
|
|
25
26
|
// FIXME: the whole feature is lost by Cesium so that top-level properties have disappeared
|
|
26
|
-
text = compiler({ feature: { properties }, properties, $t: this.$t, Units, Time })
|
|
27
|
+
text = compiler({ feature: { properties }, properties, $t: this.$t, Units, Time, moment })
|
|
27
28
|
} else if (popupStyle.pick) {
|
|
28
29
|
properties = _.pick(properties, popupStyle.pick)
|
|
29
30
|
} else if (popupStyle.omit) {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import Cesium from 'cesium/Source/Cesium.js'
|
|
2
2
|
import _ from 'lodash'
|
|
3
3
|
import chroma from 'chroma-js'
|
|
4
|
-
import
|
|
4
|
+
import moment from 'moment'
|
|
5
|
+
import { Time, Units } from '../../../../core/client/index.js'
|
|
6
|
+
import { convertToCesiumFromSimpleStyle, convertToCesiumObjects, CesiumEntityTypes } from '../../utils.globe.js'
|
|
5
7
|
|
|
6
8
|
export const style = {
|
|
7
9
|
methods: {
|
|
@@ -35,8 +37,8 @@ export const style = {
|
|
|
35
37
|
})
|
|
36
38
|
},
|
|
37
39
|
// Alias to ease development
|
|
38
|
-
|
|
39
|
-
return
|
|
40
|
+
convertFromSimpleStyle (style, inPlace) {
|
|
41
|
+
return convertToCesiumFromSimpleStyle(style, inPlace)
|
|
40
42
|
},
|
|
41
43
|
// Alias to ease development
|
|
42
44
|
convertToCesiumObjects (style) {
|
|
@@ -53,7 +55,7 @@ export const style = {
|
|
|
53
55
|
const entityStyle = _.cloneDeep(cesiumOptions.entityStyle)
|
|
54
56
|
entityStyleTemplate.forEach(entry => {
|
|
55
57
|
// Perform templating, set using simple spec mapping first then raw if property not found
|
|
56
|
-
let value = entry.compiler({ properties, chroma })
|
|
58
|
+
let value = entry.compiler({ properties, chroma, moment, Units, Time })
|
|
57
59
|
const property = entry.property
|
|
58
60
|
// Handle specific case of orientation
|
|
59
61
|
if ((property === 'orientation') && entity.position) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import _ from 'lodash'
|
|
2
|
+
import moment from 'moment'
|
|
2
3
|
import { Time, Units } from '../../../../core/client/index.js'
|
|
3
4
|
|
|
4
5
|
export const tooltip = {
|
|
@@ -36,7 +37,7 @@ export const tooltip = {
|
|
|
36
37
|
} else if (tooltipStyle.template) {
|
|
37
38
|
const compiler = tooltipStyle.compiler
|
|
38
39
|
// FIXME: the whole feature is lost by Cesium so that top-level properties have disappeared
|
|
39
|
-
text = compiler({ feature: { properties }, properties, $t: this.$t, Units, Time })
|
|
40
|
+
text = compiler({ feature: { properties }, properties, $t: this.$t, Units, Time, moment })
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
43
|
if (text) {
|
|
@@ -67,8 +68,12 @@ export const tooltip = {
|
|
|
67
68
|
}
|
|
68
69
|
},
|
|
69
70
|
onTooltip (options, event) {
|
|
70
|
-
|
|
71
|
-
|
|
71
|
+
if (options) {
|
|
72
|
+
const cesiumOptions = options.cesium || options
|
|
73
|
+
const tooltipStyle = cesiumOptions.tooltip
|
|
74
|
+
// Nothing to do in this case
|
|
75
|
+
if (_.get(tooltipStyle, 'options.permanent')) return
|
|
76
|
+
}
|
|
72
77
|
// FIXME: show/hide tooltip
|
|
73
78
|
const entity = event.target
|
|
74
79
|
if (this.overEntity) {
|
|
@@ -5,8 +5,6 @@ import L from 'leaflet'
|
|
|
5
5
|
import Emitter from 'tiny-emitter'
|
|
6
6
|
import 'leaflet/dist/leaflet.css'
|
|
7
7
|
// This ensure we have all required plugins
|
|
8
|
-
import 'leaflet-fa-markers/L.Icon.FontAwesome.css'
|
|
9
|
-
import 'leaflet-fa-markers/L.Icon.FontAwesome.js'
|
|
10
8
|
import 'leaflet-fullscreen'
|
|
11
9
|
import 'leaflet-fullscreen/dist/leaflet.fullscreen.css'
|
|
12
10
|
import 'leaflet.markercluster/dist/MarkerCluster.css'
|
|
@@ -16,6 +14,8 @@ import '@kalisio/leaflet.donutcluster/src/Leaflet.DonutCluster.css'
|
|
|
16
14
|
import '@kalisio/leaflet.donutcluster'
|
|
17
15
|
import 'leaflet.vectorgrid/dist/Leaflet.VectorGrid.bundled.js'
|
|
18
16
|
import 'leaflet.geodesic'
|
|
17
|
+
import '@kalisio/leaflet-graphicscale'
|
|
18
|
+
import '@kalisio/leaflet-graphicscale/dist/Leaflet.GraphicScale.min.css'
|
|
19
19
|
import 'leaflet.locatecontrol'
|
|
20
20
|
import 'leaflet.locatecontrol/dist/L.Control.Locate.css'
|
|
21
21
|
import iso8601 from 'iso8601-js-period' // Required by leaflet.timedimension
|
|
@@ -46,10 +46,6 @@ L.Icon.Default.mergeOptions({
|
|
|
46
46
|
// Do not create geoman structs everywhere
|
|
47
47
|
L.PM.setOptIn(true)
|
|
48
48
|
|
|
49
|
-
// FontAwesome markers do not register a createShadow() function
|
|
50
|
-
// so that they are added two times to the map
|
|
51
|
-
L.Icon.FontAwesome.prototype.createShadow = function () { return null }
|
|
52
|
-
|
|
53
49
|
export const baseMap = {
|
|
54
50
|
emits: [
|
|
55
51
|
'map-ready',
|
|
@@ -91,17 +87,23 @@ export const baseMap = {
|
|
|
91
87
|
this.map.pm.setLang(getAppLocale())
|
|
92
88
|
}
|
|
93
89
|
bindLeafletEvents(this.map, LeafletEvents.Map, this, viewerOptions)
|
|
94
|
-
|
|
95
|
-
if (
|
|
90
|
+
const scale = _.get(viewerOptions, 'scale', true)
|
|
91
|
+
if (scale) this.setupScaleControl(scale)
|
|
92
|
+
const geolocate = _.get(viewerOptions, 'geolocate', true)
|
|
93
|
+
if (geolocate) this.setupGeolocateControl(geolocate)
|
|
96
94
|
this.onMapReady()
|
|
97
95
|
},
|
|
98
96
|
onMapReady () {
|
|
99
97
|
this.$emit('map-ready', 'leaflet')
|
|
100
98
|
this.$engineEvents.emit('map-ready', 'leaflet')
|
|
101
99
|
},
|
|
102
|
-
setupScaleControl () {
|
|
103
|
-
// Add a scale control
|
|
104
|
-
|
|
100
|
+
setupScaleControl (options) {
|
|
101
|
+
// Add a basic or enhanced scale control
|
|
102
|
+
if (typeof options === 'object') {
|
|
103
|
+
this.scaleControl = new L.control.graphicScale(options)
|
|
104
|
+
} else {
|
|
105
|
+
this.scaleControl = new L.control.scale() // eslint-disable-line
|
|
106
|
+
}
|
|
105
107
|
this.scaleControl.addTo(this.map)
|
|
106
108
|
},
|
|
107
109
|
setupGeolocateControl () {
|
|
@@ -2,7 +2,10 @@ import _ from 'lodash'
|
|
|
2
2
|
import L from 'leaflet'
|
|
3
3
|
import { getType, getGeom } from '@turf/invariant'
|
|
4
4
|
import { Dialog, uid } from 'quasar'
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
bindLeafletEvents, unbindLeafletEvents,
|
|
7
|
+
getDefaultPointStyle, getDefaultLineStyle, getDefaultPolygonStyle, createMarkerFromPointStyle
|
|
8
|
+
} from '../../utils.map.js'
|
|
6
9
|
|
|
7
10
|
// Events we listen while layer is in edition mode
|
|
8
11
|
const mapEditEvents = ['pm:create']
|
|
@@ -68,12 +71,19 @@ export const editLayers = {
|
|
|
68
71
|
onEachFeature,
|
|
69
72
|
// Use default styling when editing as dynamic styling can conflict
|
|
70
73
|
style: (feature) => {
|
|
71
|
-
|
|
72
|
-
_.get(this, 'activityOptions.engine
|
|
74
|
+
if (['LineString', 'MultiLineString'].includes(feature.geometry.type)) {
|
|
75
|
+
return getDefaultLineStyle(feature, null, _.get(this, 'activityOptions.engine'), 'style.edition.line')
|
|
76
|
+
}
|
|
77
|
+
if (['Polygon', 'MultiPolygon'].includes(feature.geometry.type)) {
|
|
78
|
+
return getDefaultPolygonStyle(feature, null, _.get(this, 'activityOptions.engine'), 'style.edition.polygon')
|
|
79
|
+
} else {
|
|
80
|
+
logger.warn(`[KDK] the geometry of type of ${feature.geometry.type} is not supported`)
|
|
81
|
+
}
|
|
73
82
|
},
|
|
74
83
|
pointToLayer: (feature, latlng) => {
|
|
75
|
-
|
|
76
|
-
|
|
84
|
+
const style = getDefaultPointStyle(feature, null, _.get(this, 'activityOptions.engine'), 'style.edition.point')
|
|
85
|
+
style.options = { pmIgnore: false } // Allow geoman edition
|
|
86
|
+
return createMarkerFromPointStyle(latlng, style)
|
|
77
87
|
}
|
|
78
88
|
}
|
|
79
89
|
},
|
|
@@ -479,15 +489,5 @@ export const editLayers = {
|
|
|
479
489
|
},
|
|
480
490
|
created () {
|
|
481
491
|
this.pendingOperations = []
|
|
482
|
-
},
|
|
483
|
-
// Need to be done after created as the activity mixin initializes options in it
|
|
484
|
-
beforeMount () {
|
|
485
|
-
// Perform required conversion for default feature styling
|
|
486
|
-
if (_.has(this, 'activityOptions.engine.editFeatureStyle')) {
|
|
487
|
-
this.convertFromSimpleStyleSpec(_.get(this, 'activityOptions.engine.editFeatureStyle'), 'update-in-place')
|
|
488
|
-
}
|
|
489
|
-
if (_.has(this, 'activityOptions.engine.editPointStyle')) {
|
|
490
|
-
this.convertFromSimpleStyleSpec(_.get(this, 'activityOptions.engine.editPointStyle'), 'update-in-place')
|
|
491
|
-
}
|
|
492
492
|
}
|
|
493
493
|
}
|
|
@@ -45,8 +45,10 @@ export const forecastLayers = {
|
|
|
45
45
|
const leafletOptions = options.leaflet || options
|
|
46
46
|
// Check for valid types
|
|
47
47
|
if (!leafletOptions.type.startsWith('weacast')) return
|
|
48
|
+
// Check API to be used in case the layer is coming from a remote "planet"
|
|
49
|
+
const weacastApi = (typeof options.getPlanetApi === 'function' ? options.getPlanetApi() : this.getWeacastApi())
|
|
48
50
|
// We need to add Weacast API object as argument before creating the layer
|
|
49
|
-
leafletOptions.source =
|
|
51
|
+
leafletOptions.source = weacastApi
|
|
50
52
|
// Copy as well color map options
|
|
51
53
|
const colorMap = _.get(options, 'variables[0].chromajs')
|
|
52
54
|
if (colorMap) Object.assign(leafletOptions, colorMap)
|