@kalisio/kdk 2.5.3 → 2.6.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/.github/workflows/main.yaml +35 -6
- package/client.globe.js +8 -0
- package/client.js +8 -0
- package/client.map.js +8 -0
- package/core/api/hooks/hooks.push.js +3 -2
- package/core/api/hooks/hooks.tags.js +56 -0
- package/core/api/models/tags.model.mongodb.js +8 -0
- package/core/api/services/index.js +33 -2
- package/core/api/services/tags/tags.hooks.js +47 -0
- package/core/client/api.js +5 -5
- package/core/client/components/KActivity.vue +3 -2
- package/core/client/components/KChip.vue +2 -2
- package/core/client/components/KEditor.vue +3 -1
- package/core/client/components/KFollower.vue +4 -4
- package/core/client/components/KStore.vue +1 -1
- package/core/client/components/KTab.vue +20 -7
- package/core/client/components/account/KProfile.vue +9 -25
- package/core/client/components/action/KAction.vue +10 -10
- package/core/client/components/action/KToggleFullscreenAction.vue +2 -11
- package/core/client/components/app/KHome.vue +3 -2
- package/core/client/components/collection/KFilter.vue +5 -4
- package/core/client/components/collection/KGrid.vue +5 -1
- package/core/client/components/collection/KItemsFilter.vue +47 -0
- package/core/client/components/collection/KItemsSorter.vue +42 -0
- package/core/client/components/collection/KScrollDown.vue +2 -2
- package/core/client/components/collection/KSearchFilterControl.vue +3 -2
- package/core/client/components/collection/KSorter.vue +33 -37
- package/core/client/components/collection/KTagsFilterControl.vue +14 -40
- package/core/client/components/collection/KTagsFilterView.vue +10 -45
- package/core/client/components/collection/KTimeFilterControl.vue +6 -7
- package/core/client/components/collection/KTimeFilterView.vue +13 -22
- package/core/client/components/collection/KTimeLine.vue +18 -9
- package/core/client/components/form/KColorField.vue +13 -6
- package/core/client/components/form/KColorScaleField.vue +7 -12
- package/core/client/components/form/KFileField.vue +118 -89
- package/core/client/components/form/KForm.vue +30 -18
- package/core/client/components/form/KIconField.vue +4 -1
- package/core/client/components/form/KNumberField.vue +9 -2
- package/core/client/components/form/KSelectField.vue +1 -4
- package/core/client/components/form/KTagField.vue +229 -0
- package/core/client/components/form/KTextField.vue +4 -0
- package/core/client/components/form/KTextareaField.vue +3 -1
- package/core/client/components/input/KShapePicker.vue +3 -3
- package/core/client/components/layout/KFab.vue +32 -20
- package/core/client/components/layout/KPage.vue +11 -6
- package/core/client/components/layout/KWindow.vue +5 -0
- package/core/client/components/media/index.js +2 -6
- package/core/client/components/menu/KMenu.vue +12 -10
- package/core/client/components/menu/KSubMenu.vue +12 -12
- package/core/client/components/messages/KMessageCard.vue +13 -12
- package/core/client/components/messages/KMessageComposer.vue +13 -9
- package/core/client/components/messages/KMessagesTimeLine.vue +16 -8
- package/core/client/components/tags/KTagFilter.vue +99 -0
- package/core/client/components/tags/KTagItem.vue +65 -0
- package/core/client/components/tags/KTagManager.vue +198 -0
- package/core/client/components/tags/KTagSelection.vue +82 -0
- package/core/client/components/time/KDate.vue +3 -17
- package/core/client/components/time/KDateTime.vue +1 -1
- package/core/client/components/time/KTime.vue +0 -4
- package/core/client/composables/collection-filter.js +41 -2
- package/core/client/composables/collection.js +3 -3
- package/core/client/composables/index.js +1 -0
- package/core/client/composables/pwa.js +13 -0
- package/core/client/composables/session.js +7 -8
- package/core/client/composables/user.js +36 -0
- package/core/client/directives/index.js +1 -0
- package/core/client/directives/v-drop-file.js +174 -0
- package/core/client/document.js +2 -1
- package/core/client/exporter.js +17 -3
- package/core/client/i18n/core_en.json +34 -7
- package/core/client/i18n/core_fr.json +36 -9
- package/core/client/i18n.js +26 -11
- package/core/client/layout.js +5 -5
- package/core/client/mixins/mixin.base-activity.js +8 -5
- package/core/client/mixins/mixin.base-editor.js +2 -1
- package/core/client/mixins/mixin.base-field.js +3 -2
- package/core/client/mixins/mixin.base-item.js +12 -10
- package/core/client/mixins/mixin.service.js +3 -1
- package/core/client/platform.js +0 -3
- package/core/client/readers/reader.json.js +2 -2
- package/core/client/utils/index.js +2 -0
- package/core/client/utils/utils.collection.js +6 -6
- package/core/client/utils/utils.colors.js +46 -19
- package/core/client/utils/utils.files.js +19 -0
- package/core/client/utils/utils.locale.js +13 -17
- package/core/client/utils/utils.services.js +27 -0
- package/core/client/utils/utils.shapes.js +2 -2
- package/core/client/utils/utils.tags.js +17 -0
- package/core/client/utils/utils.tours.js +31 -0
- package/core/common/permissions.js +3 -0
- package/core/common/schemas/tags.update.json +35 -0
- package/core/common/schemas/users.update-profile.json +1 -1
- package/core/common/utils.js +5 -5
- package/extras/configs/panes.top.js +11 -0
- package/extras/configs/stickies.js +1 -1
- package/extras/configs/widgets.left.js +13 -1
- package/extras/libs/jsts.min.js +8 -0
- package/{test/client/core/account.js → extras/tests/core/account.mjs} +4 -4
- package/extras/tests/core/api.mjs +114 -0
- package/{test/client/core/collection.js → extras/tests/core/collection.mjs} +8 -8
- package/{test/client/core/dialogs.js → extras/tests/core/dialogs.mjs} +1 -1
- package/extras/tests/core/index.mjs +9 -0
- package/{test/client/core/layout.js → extras/tests/core/layout.mjs} +7 -3
- package/{test/client/core/runner.js → extras/tests/core/runner.mjs} +3 -3
- package/{test/client/core/screens.js → extras/tests/core/screens.mjs} +1 -1
- package/{test/client/core/utils.js → extras/tests/core/utils.mjs} +79 -26
- package/extras/tests/index.mjs +4 -0
- package/{test/client/map/api.js → extras/tests/map/api.mjs} +1 -1
- package/{test/client/map/catalog.js → extras/tests/map/catalog.mjs} +18 -18
- package/{test/client/map/controls.js → extras/tests/map/controls.mjs} +3 -3
- package/extras/tests/map/index.mjs +5 -0
- package/{test/client/map/time.js → extras/tests/map/time.mjs} +3 -3
- package/{test/client/map/utils.js → extras/tests/map/utils.mjs} +6 -5
- package/extras/tours/fab.js +36 -0
- package/extras/tours/layout.js +49 -0
- package/extras/tours/pane.left.js +78 -0
- package/extras/tours/pane.right.js +145 -0
- package/extras/tours/pane.top.js +239 -0
- package/map/api/config/layers.cjs +28 -13
- package/map/api/hooks/hooks.query.js +12 -7
- package/map/api/models/catalog.model.mongodb.js +17 -6
- package/map/api/services/catalog/catalog.hooks.js +1 -1
- package/map/api/services/index.js +18 -1
- package/map/client/cesium/utils/utils.cesium.js +25 -65
- package/map/client/cesium/utils/utils.features.js +1 -0
- package/map/client/cesium/utils/utils.geojson.js +1 -0
- package/map/client/cesium/utils/utils.style.js +7 -6
- package/map/client/components/KFeatureEditor.vue +3 -3
- package/map/client/components/KFeaturesChart.vue +4 -4
- package/map/client/components/KFeaturesFilterEditor.vue +19 -13
- package/map/client/components/KFeaturesFilterManager.vue +7 -4
- package/map/client/components/KFeaturesTable.vue +2 -2
- package/map/client/components/KLayerEditor.vue +6 -6
- package/map/client/components/KMeasureTool.vue +2 -1
- package/map/client/components/catalog/KBaseLayersSelector.vue +1 -1
- package/map/client/components/catalog/KCategoryItem.vue +15 -1
- package/map/client/components/catalog/KConnectLayer.vue +2 -2
- package/map/client/components/catalog/KCreateView.vue +3 -2
- package/map/client/components/catalog/KFilteredLayerItem.vue +26 -6
- package/map/client/components/catalog/KImportLayer.vue +6 -3
- package/map/client/components/catalog/KLayerCategories.vue +6 -6
- package/map/client/components/catalog/KLayerItem.vue +12 -2
- package/map/client/components/catalog/KLayersList.vue +180 -0
- package/map/client/components/catalog/KLayersPanel.vue +146 -36
- package/map/client/components/catalog/KLayersSelector.vue +96 -48
- package/map/client/components/catalog/KProjectEditor.vue +0 -9
- package/map/client/components/catalog/KProjectSelector.vue +3 -2
- package/map/client/components/catalog/KProjectsPanel.vue +23 -8
- package/map/client/components/catalog/KViewsPanel.vue +18 -8
- package/map/client/components/catalog/KWeatherLayersSelector.vue +3 -3
- package/map/client/components/form/KDirectionField.vue +3 -6
- package/map/client/components/form/KLayerCategoryField.vue +2 -2
- package/map/client/components/form/KOwsServiceField.vue +25 -24
- package/map/client/components/form/KSelectLayersField.vue +4 -4
- package/map/client/components/form/KSelectViewsField.vue +4 -4
- package/map/client/components/legend/KLayerLegend.vue +11 -2
- package/map/client/components/legend/KLegend.vue +44 -51
- package/map/client/components/location/KLocationCardSection.vue +6 -7
- package/map/client/components/location/KLocationMap.vue +23 -13
- package/map/client/components/stickies/KPosition.vue +5 -0
- package/map/client/components/styles/KLayerStyleAction.vue +59 -12
- package/map/client/components/styles/KStyleEditor.vue +71 -8
- package/map/client/components/styles/KStyleEditorSection.vue +82 -33
- package/map/client/components/styles/KStyleManager.vue +119 -59
- package/map/client/components/styles/KStylePreview.vue +9 -25
- package/map/client/components/styles/KStylePreviewItem.vue +22 -1
- package/map/client/components/tools/KSearchTool.vue +1 -1
- package/map/client/components/widget/KElevationProfile.vue +20 -17
- package/map/client/components/widget/KInformationBox.vue +5 -5
- package/map/client/components/widget/KMapillaryViewer.vue +2 -1
- package/map/client/components/widget/KTimeSeries.vue +11 -9
- package/map/client/globe.js +2 -0
- package/map/client/i18n/map_en.json +29 -7
- package/map/client/i18n/map_fr.json +29 -7
- package/map/client/leaflet/GradientPath.js +61 -24
- package/map/client/leaflet/ShapeMarker.js +12 -5
- package/map/client/leaflet/TiledMeshLayer.js +3 -3
- package/map/client/leaflet/utils/utils.geojson.js +66 -8
- package/map/client/leaflet/utils/utils.style.js +14 -15
- package/map/client/mixins/globe/mixin.base-globe.js +181 -34
- package/map/client/mixins/globe/mixin.file-layers.js +3 -0
- package/map/client/mixins/globe/mixin.geojson-layers.js +179 -31
- package/map/client/mixins/globe/mixin.opendap-layers.js +2 -1
- package/map/client/mixins/globe/mixin.style.js +23 -1
- package/map/client/mixins/globe/mixin.tooltip.js +14 -2
- package/map/client/mixins/map/mixin.base-map.js +146 -58
- package/map/client/mixins/map/mixin.edit-layers.js +18 -15
- package/map/client/mixins/map/mixin.geojson-layers.js +181 -106
- package/map/client/mixins/map/mixin.heatmap-layers.js +3 -2
- package/map/client/mixins/map/mixin.map-activity.js +6 -1
- package/map/client/mixins/map/mixin.mapillary-layers.js +2 -1
- package/map/client/mixins/map/mixin.pmtiles-layers.js +3 -3
- package/map/client/mixins/map/mixin.tiled-mesh-layers.js +3 -2
- package/map/client/mixins/map/mixin.tiled-wind-layers.js +3 -2
- package/map/client/mixins/mixin.activity.js +197 -51
- package/map/client/mixins/mixin.context.js +11 -11
- package/map/client/mixins/mixin.feature-service.js +11 -9
- package/map/client/mixins/mixin.weacast.js +5 -3
- package/map/client/readers/reader.geojson.js +3 -1
- package/map/client/utils/utils.capture.js +3 -3
- package/map/client/utils/utils.catalog.js +9 -5
- package/map/client/utils/utils.features.js +120 -54
- package/map/client/utils/utils.js +25 -10
- package/map/client/utils/utils.layers.js +148 -24
- package/map/client/utils/utils.location.js +26 -9
- package/map/client/utils/utils.schema.js +2 -1
- package/map/client/utils/utils.style.js +53 -9
- package/map/common/geotiff-grid-source.js +1 -3
- package/map/common/opendap-utils.js +0 -1
- package/map/common/tms-utils.js +0 -1
- package/map/common/wcs-utils.js +0 -1
- package/map/common/wfs-utils.js +0 -1
- package/map/common/wms-utils.js +7 -1
- package/map/common/wmts-utils.js +0 -1
- package/package.json +12 -12
- package/scripts/init_runner.sh +3 -3
- package/scripts/kash/CHANGELOG.md +27 -0
- package/scripts/kash/kash.sh +556 -237
- package/scripts/kash/scripts/run_tests.sh +44 -5
- package/scripts/setup_workspace.sh +23 -13
- package/test/api/core/config/default.cjs +2 -1
- package/test/api/core/tags.test.js +62 -0
- package/test/api/map/config/default.cjs +2 -1
- package/test/api/map/config/layers.json +9 -0
- package/test/api/map/data/openradiation.json +13811 -0
- package/test/api/map/grid-sources.test.js +1 -3
- package/test/api/map/index.test.js +60 -1
- package/test/api/map/style.test.js +30 -1
- package/test.api.js +1 -1
- package/vite/App.vue +18 -0
- package/vite/AppWithGlobe.vue +84 -0
- package/vite/GlobeActivity.vue +58 -0
- package/vite/MapActivity.vue +63 -0
- package/vite/MapActivityWithGlobe.vue +63 -0
- package/vite/README.md +169 -0
- package/vite/config.js +221 -0
- package/vite/index_with_globe.html +50 -0
- package/vite/index_with_map.html +50 -0
- package/vite/package.json +173 -0
- package/vite/quasar.variables.scss +17 -0
- package/vite/vite.config.js +166 -0
- package/vite/yarn.lock +11641 -0
- package/core/client/components/media/KImageViewer.vue +0 -68
- package/core/client/components/media/KMarkdownViewer.vue +0 -55
- package/core/client/components/media/KMediaBrowser.vue +0 -301
- package/coverage/base.css +0 -224
- package/coverage/block-navigation.js +0 -87
- package/coverage/core/api/application.js.html +0 -1870
- package/coverage/core/api/authentication.js.html +0 -874
- package/coverage/core/api/db.js.html +0 -793
- package/coverage/core/api/hooks/hooks.authentication.js.html +0 -139
- package/coverage/core/api/hooks/hooks.authorisations.js.html +0 -958
- package/coverage/core/api/hooks/hooks.groups.js.html +0 -229
- package/coverage/core/api/hooks/hooks.logger.js.html +0 -163
- package/coverage/core/api/hooks/hooks.model.js.html +0 -967
- package/coverage/core/api/hooks/hooks.organisations.js.html +0 -541
- package/coverage/core/api/hooks/hooks.push.js.html +0 -265
- package/coverage/core/api/hooks/hooks.query.js.html +0 -862
- package/coverage/core/api/hooks/hooks.schemas.js.html +0 -298
- package/coverage/core/api/hooks/hooks.service.js.html +0 -319
- package/coverage/core/api/hooks/hooks.storage.js.html +0 -193
- package/coverage/core/api/hooks/hooks.users.js.html +0 -595
- package/coverage/core/api/hooks/index.html +0 -266
- package/coverage/core/api/hooks/index.js.html +0 -115
- package/coverage/core/api/index.html +0 -176
- package/coverage/core/api/index.js.html +0 -148
- package/coverage/core/api/marshall.js.html +0 -448
- package/coverage/core/api/models/groups.model.mongodb.js.html +0 -109
- package/coverage/core/api/models/index.html +0 -131
- package/coverage/core/api/models/messages.model.mongodb.js.html +0 -121
- package/coverage/core/api/models/organisations.model.mongodb.js.html +0 -94
- package/coverage/core/api/models/tags.model.mongodb.js.html +0 -115
- package/coverage/core/api/models/users.model.mongodb.js.html +0 -115
- package/coverage/core/api/services/account/account.hooks.js.html +0 -208
- package/coverage/core/api/services/account/account.service.js.html +0 -436
- package/coverage/core/api/services/account/index.html +0 -131
- package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +0 -184
- package/coverage/core/api/services/authorisations/authorisations.service.js.html +0 -520
- package/coverage/core/api/services/authorisations/index.html +0 -131
- package/coverage/core/api/services/databases/databases.hooks.js.html +0 -193
- package/coverage/core/api/services/databases/databases.service.js.html +0 -100
- package/coverage/core/api/services/databases/index.html +0 -131
- package/coverage/core/api/services/groups/groups.hooks.js.html +0 -178
- package/coverage/core/api/services/groups/index.html +0 -116
- package/coverage/core/api/services/import-export/import-export.hooks.js.html +0 -184
- package/coverage/core/api/services/import-export/import-export.service.js.html +0 -118
- package/coverage/core/api/services/import-export/index.html +0 -131
- package/coverage/core/api/services/index.html +0 -116
- package/coverage/core/api/services/index.js.html +0 -532
- package/coverage/core/api/services/mailer/index.html +0 -131
- package/coverage/core/api/services/mailer/mailer.hooks.js.html +0 -190
- package/coverage/core/api/services/mailer/mailer.service.js.html +0 -118
- package/coverage/core/api/services/messages/index.html +0 -116
- package/coverage/core/api/services/messages/messages.hooks.js.html +0 -202
- package/coverage/core/api/services/organisations/index.html +0 -131
- package/coverage/core/api/services/organisations/organisations.hooks.js.html +0 -178
- package/coverage/core/api/services/organisations/organisations.service.js.html +0 -343
- package/coverage/core/api/services/push/index.html +0 -131
- package/coverage/core/api/services/push/push.hooks.js.html +0 -190
- package/coverage/core/api/services/push/push.service.js.html +0 -121
- package/coverage/core/api/services/storage/index.html +0 -131
- package/coverage/core/api/services/storage/storage.hooks.js.html +0 -190
- package/coverage/core/api/services/storage/storage.service.js.html +0 -172
- package/coverage/core/api/services/tags/index.html +0 -116
- package/coverage/core/api/services/tags/tags.hooks.js.html +0 -178
- package/coverage/core/api/services/users/index.html +0 -131
- package/coverage/core/api/services/users/users.hooks.js.html +0 -310
- package/coverage/core/api/services/users/users.service.js.html +0 -100
- package/coverage/core/api/utils.js.html +0 -118
- package/coverage/core/common/errors.js.html +0 -88
- package/coverage/core/common/index.html +0 -191
- package/coverage/core/common/index.js.html +0 -115
- package/coverage/core/common/permissions.js.html +0 -733
- package/coverage/core/common/schema.js.html +0 -190
- package/coverage/core/common/utils.js.html +0 -226
- package/coverage/core/common/utils.offline.js.html +0 -199
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +0 -476
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/core/api/application.js.html +0 -1870
- package/coverage/lcov-report/core/api/authentication.js.html +0 -874
- package/coverage/lcov-report/core/api/db.js.html +0 -793
- package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +0 -139
- package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +0 -958
- package/coverage/lcov-report/core/api/hooks/hooks.groups.js.html +0 -229
- package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +0 -163
- package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +0 -967
- package/coverage/lcov-report/core/api/hooks/hooks.organisations.js.html +0 -541
- package/coverage/lcov-report/core/api/hooks/hooks.push.js.html +0 -265
- package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +0 -862
- package/coverage/lcov-report/core/api/hooks/hooks.schemas.js.html +0 -298
- package/coverage/lcov-report/core/api/hooks/hooks.service.js.html +0 -319
- package/coverage/lcov-report/core/api/hooks/hooks.storage.js.html +0 -193
- package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +0 -595
- package/coverage/lcov-report/core/api/hooks/index.html +0 -266
- package/coverage/lcov-report/core/api/hooks/index.js.html +0 -115
- package/coverage/lcov-report/core/api/index.html +0 -176
- package/coverage/lcov-report/core/api/index.js.html +0 -148
- package/coverage/lcov-report/core/api/marshall.js.html +0 -448
- package/coverage/lcov-report/core/api/models/groups.model.mongodb.js.html +0 -109
- package/coverage/lcov-report/core/api/models/index.html +0 -131
- package/coverage/lcov-report/core/api/models/messages.model.mongodb.js.html +0 -121
- package/coverage/lcov-report/core/api/models/organisations.model.mongodb.js.html +0 -94
- package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +0 -115
- package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +0 -115
- package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +0 -208
- package/coverage/lcov-report/core/api/services/account/account.service.js.html +0 -436
- package/coverage/lcov-report/core/api/services/account/index.html +0 -131
- package/coverage/lcov-report/core/api/services/authorisations/authorisations.hooks.js.html +0 -184
- package/coverage/lcov-report/core/api/services/authorisations/authorisations.service.js.html +0 -520
- package/coverage/lcov-report/core/api/services/authorisations/index.html +0 -131
- package/coverage/lcov-report/core/api/services/databases/databases.hooks.js.html +0 -193
- package/coverage/lcov-report/core/api/services/databases/databases.service.js.html +0 -100
- package/coverage/lcov-report/core/api/services/databases/index.html +0 -131
- package/coverage/lcov-report/core/api/services/groups/groups.hooks.js.html +0 -178
- package/coverage/lcov-report/core/api/services/groups/index.html +0 -116
- package/coverage/lcov-report/core/api/services/import-export/import-export.hooks.js.html +0 -184
- package/coverage/lcov-report/core/api/services/import-export/import-export.service.js.html +0 -118
- package/coverage/lcov-report/core/api/services/import-export/index.html +0 -131
- package/coverage/lcov-report/core/api/services/index.html +0 -116
- package/coverage/lcov-report/core/api/services/index.js.html +0 -532
- package/coverage/lcov-report/core/api/services/mailer/index.html +0 -131
- package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +0 -190
- package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +0 -118
- package/coverage/lcov-report/core/api/services/messages/index.html +0 -116
- package/coverage/lcov-report/core/api/services/messages/messages.hooks.js.html +0 -202
- package/coverage/lcov-report/core/api/services/organisations/index.html +0 -131
- package/coverage/lcov-report/core/api/services/organisations/organisations.hooks.js.html +0 -178
- package/coverage/lcov-report/core/api/services/organisations/organisations.service.js.html +0 -343
- package/coverage/lcov-report/core/api/services/push/index.html +0 -131
- package/coverage/lcov-report/core/api/services/push/push.hooks.js.html +0 -190
- package/coverage/lcov-report/core/api/services/push/push.service.js.html +0 -121
- package/coverage/lcov-report/core/api/services/storage/index.html +0 -131
- package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +0 -190
- package/coverage/lcov-report/core/api/services/storage/storage.service.js.html +0 -172
- package/coverage/lcov-report/core/api/services/tags/index.html +0 -116
- package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +0 -178
- package/coverage/lcov-report/core/api/services/users/index.html +0 -131
- package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +0 -310
- package/coverage/lcov-report/core/api/services/users/users.service.js.html +0 -100
- package/coverage/lcov-report/core/api/utils.js.html +0 -118
- package/coverage/lcov-report/core/common/errors.js.html +0 -88
- package/coverage/lcov-report/core/common/index.html +0 -191
- package/coverage/lcov-report/core/common/index.js.html +0 -115
- package/coverage/lcov-report/core/common/permissions.js.html +0 -733
- package/coverage/lcov-report/core/common/schema.js.html +0 -190
- package/coverage/lcov-report/core/common/utils.js.html +0 -226
- package/coverage/lcov-report/core/common/utils.offline.js.html +0 -199
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +0 -476
- package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +0 -553
- package/coverage/lcov-report/map/api/hooks/hooks.features.js.html +0 -397
- package/coverage/lcov-report/map/api/hooks/hooks.query.js.html +0 -1294
- package/coverage/lcov-report/map/api/hooks/index.html +0 -161
- package/coverage/lcov-report/map/api/hooks/index.js.html +0 -94
- package/coverage/lcov-report/map/api/index.html +0 -131
- package/coverage/lcov-report/map/api/index.js.html +0 -139
- package/coverage/lcov-report/map/api/marshall.js.html +0 -178
- package/coverage/lcov-report/map/api/models/alerts.model.mongodb.js.html +0 -106
- package/coverage/lcov-report/map/api/models/catalog.model.mongodb.js.html +0 -169
- package/coverage/lcov-report/map/api/models/features.model.mongodb.js.html +0 -196
- package/coverage/lcov-report/map/api/models/index.html +0 -176
- package/coverage/lcov-report/map/api/models/projects.model.mongodb.js.html +0 -109
- package/coverage/lcov-report/map/api/models/styles.model.mongodb.js.html +0 -112
- package/coverage/lcov-report/map/api/services/alerts/alerts.hooks.js.html +0 -274
- package/coverage/lcov-report/map/api/services/alerts/alerts.service.js.html +0 -610
- package/coverage/lcov-report/map/api/services/alerts/index.html +0 -131
- package/coverage/lcov-report/map/api/services/catalog/catalog.hooks.js.html +0 -328
- package/coverage/lcov-report/map/api/services/catalog/index.html +0 -116
- package/coverage/lcov-report/map/api/services/daptiles/daptiles.service.js.html +0 -1510
- package/coverage/lcov-report/map/api/services/daptiles/index.html +0 -116
- package/coverage/lcov-report/map/api/services/features/features.hooks.js.html +0 -310
- package/coverage/lcov-report/map/api/services/features/features.service.js.html +0 -544
- package/coverage/lcov-report/map/api/services/features/index.html +0 -131
- package/coverage/lcov-report/map/api/services/index.html +0 -116
- package/coverage/lcov-report/map/api/services/index.js.html +0 -1054
- package/coverage/lcov-report/map/api/services/projects/index.html +0 -116
- package/coverage/lcov-report/map/api/services/projects/projects.hooks.js.html +0 -439
- package/coverage/lcov-report/map/api/services/styles/index.html +0 -116
- package/coverage/lcov-report/map/api/services/styles/styles.hooks.js.html +0 -196
- package/coverage/lcov-report/map/common/dynamic-grid-source.js.html +0 -466
- package/coverage/lcov-report/map/common/errors.js.html +0 -94
- package/coverage/lcov-report/map/common/geotiff-grid-source.js.html +0 -544
- package/coverage/lcov-report/map/common/grid.js.html +0 -1612
- package/coverage/lcov-report/map/common/index.html +0 -371
- package/coverage/lcov-report/map/common/index.js.html +0 -172
- package/coverage/lcov-report/map/common/meteo-model-grid-source.js.html +0 -556
- package/coverage/lcov-report/map/common/moment-utils.js.html +0 -157
- package/coverage/lcov-report/map/common/opendap-grid-source.js.html +0 -868
- package/coverage/lcov-report/map/common/opendap-utils.js.html +0 -826
- package/coverage/lcov-report/map/common/permissions.js.html +0 -130
- package/coverage/lcov-report/map/common/time-based-grid-source.js.html +0 -418
- package/coverage/lcov-report/map/common/tms-utils.js.html +0 -274
- package/coverage/lcov-report/map/common/wcs-grid-source.js.html +0 -364
- package/coverage/lcov-report/map/common/wcs-utils.js.html +0 -586
- package/coverage/lcov-report/map/common/weacast-grid-source.js.html +0 -1033
- package/coverage/lcov-report/map/common/wfs-utils.js.html +0 -574
- package/coverage/lcov-report/map/common/wms-utils.js.html +0 -451
- package/coverage/lcov-report/map/common/wmts-utils.js.html +0 -547
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -196
- package/coverage/lcov.info +0 -11520
- package/coverage/map/api/hooks/hooks.catalog.js.html +0 -553
- package/coverage/map/api/hooks/hooks.features.js.html +0 -397
- package/coverage/map/api/hooks/hooks.query.js.html +0 -1294
- package/coverage/map/api/hooks/index.html +0 -161
- package/coverage/map/api/hooks/index.js.html +0 -94
- package/coverage/map/api/index.html +0 -131
- package/coverage/map/api/index.js.html +0 -139
- package/coverage/map/api/marshall.js.html +0 -178
- package/coverage/map/api/models/alerts.model.mongodb.js.html +0 -106
- package/coverage/map/api/models/catalog.model.mongodb.js.html +0 -169
- package/coverage/map/api/models/features.model.mongodb.js.html +0 -196
- package/coverage/map/api/models/index.html +0 -176
- package/coverage/map/api/models/projects.model.mongodb.js.html +0 -109
- package/coverage/map/api/models/styles.model.mongodb.js.html +0 -112
- package/coverage/map/api/services/alerts/alerts.hooks.js.html +0 -274
- package/coverage/map/api/services/alerts/alerts.service.js.html +0 -610
- package/coverage/map/api/services/alerts/index.html +0 -131
- package/coverage/map/api/services/catalog/catalog.hooks.js.html +0 -328
- package/coverage/map/api/services/catalog/index.html +0 -116
- package/coverage/map/api/services/daptiles/daptiles.service.js.html +0 -1510
- package/coverage/map/api/services/daptiles/index.html +0 -116
- package/coverage/map/api/services/features/features.hooks.js.html +0 -310
- package/coverage/map/api/services/features/features.service.js.html +0 -544
- package/coverage/map/api/services/features/index.html +0 -131
- package/coverage/map/api/services/index.html +0 -116
- package/coverage/map/api/services/index.js.html +0 -1054
- package/coverage/map/api/services/projects/index.html +0 -116
- package/coverage/map/api/services/projects/projects.hooks.js.html +0 -439
- package/coverage/map/api/services/styles/index.html +0 -116
- package/coverage/map/api/services/styles/styles.hooks.js.html +0 -196
- package/coverage/map/common/dynamic-grid-source.js.html +0 -466
- package/coverage/map/common/errors.js.html +0 -94
- package/coverage/map/common/geotiff-grid-source.js.html +0 -544
- package/coverage/map/common/grid.js.html +0 -1612
- package/coverage/map/common/index.html +0 -371
- package/coverage/map/common/index.js.html +0 -172
- package/coverage/map/common/meteo-model-grid-source.js.html +0 -556
- package/coverage/map/common/moment-utils.js.html +0 -157
- package/coverage/map/common/opendap-grid-source.js.html +0 -868
- package/coverage/map/common/opendap-utils.js.html +0 -826
- package/coverage/map/common/permissions.js.html +0 -130
- package/coverage/map/common/time-based-grid-source.js.html +0 -418
- package/coverage/map/common/tms-utils.js.html +0 -274
- package/coverage/map/common/wcs-grid-source.js.html +0 -364
- package/coverage/map/common/wcs-utils.js.html +0 -586
- package/coverage/map/common/weacast-grid-source.js.html +0 -1033
- package/coverage/map/common/wfs-utils.js.html +0 -574
- package/coverage/map/common/wms-utils.js.html +0 -451
- package/coverage/map/common/wmts-utils.js.html +0 -547
- package/coverage/prettify.css +0 -1
- package/coverage/prettify.js +0 -2
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +0 -196
- package/coverage/tmp/coverage-151198-1753351220086-0.json +0 -1
- package/coverage/tmp/coverage-151210-1753351220070-0.json +0 -1
- package/coverage/tmp/coverage-151221-1753351129816-0.json +0 -1
- package/coverage/tmp/coverage-151233-1753351129803-0.json +0 -1
- package/coverage/tmp/coverage-151240-1753351129770-0.json +0 -1
- package/coverage/tmp/coverage-151307-1753351220058-0.json +0 -1
- package/coverage/tmp/coverage-151319-1753351220044-0.json +0 -1
- package/coverage/tmp/coverage-151326-1753351220010-0.json +0 -1
- package/extras/tours/core/account-profile.js +0 -32
- package/extras/tours/core/account.js +0 -143
- package/extras/tours/core/add-member.js +0 -75
- package/extras/tours/core/add-tag.js +0 -13
- package/extras/tours/core/create-group.js +0 -19
- package/extras/tours/core/create-organisation.js +0 -19
- package/extras/tours/core/create-tag.js +0 -26
- package/extras/tours/core/edit-member-role.js +0 -13
- package/extras/tours/core/groups.js +0 -65
- package/extras/tours/core/join-group.js +0 -13
- package/extras/tours/core/login.js +0 -41
- package/extras/tours/core/members.js +0 -108
- package/extras/tours/core/register.js +0 -61
- package/extras/tours/core/send-reset-password.js +0 -14
- package/extras/tours/core/tags.js +0 -65
- package/extras/tours/map/catalog-panel.js +0 -112
- package/extras/tours/map/fab.js +0 -26
- package/extras/tours/map/navigation-bar.js +0 -187
- package/extras/tours/map/side-nav.js +0 -36
- package/test/api/core/test-log-2025-02-05.log +0 -23
- package/test/api/core/test-log-2025-05-21.log +0 -15
- package/test/api/core/test-log-2025-06-25.log +0 -9
- package/test/api/core/test-log-2025-07-24.log +0 -44
- package/test/api/map/test-log-2025-05-27.log +0 -13
- package/test/api/map/test-log-2025-06-23.log +0 -7
- package/test/api/map/test-log-2025-07-24.log +0 -11
- package/test/client/core/api.js +0 -361
- package/test/client/core/index.js +0 -9
- package/test/client/index.js +0 -4
- package/test/client/map/index.js +0 -5
- package/test.client.js +0 -1
- /package/{test/client/core/time.js → extras/tests/core/time.mjs} +0 -0
- /package/extras/tours/{map/add-layer.js → add-layer.js} +0 -0
- /package/extras/tours/{map/catalog-categories.js → catalog-categories.js} +0 -0
- /package/extras/tours/{map/connect-layer.js → connect-layer.js} +0 -0
- /package/extras/tours/{map/create-layer.js → create-layer.js} +0 -0
- /package/extras/tours/{map/create-view.js → create-view.js} +0 -0
- /package/extras/tours/{map/import-layer.js → import-layer.js} +0 -0
- /package/extras/tours/{map/timeline.js → pane.bottom.js} +0 -0
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import _ from 'lodash'
|
|
2
2
|
import logger from 'loglevel'
|
|
3
3
|
import moment from 'moment'
|
|
4
|
+
import jsts from 'jsts'
|
|
4
5
|
import { getType, getGeom } from '@turf/invariant'
|
|
6
|
+
import { lineString } from '@turf/helpers'
|
|
5
7
|
import explode from '@turf/explode'
|
|
6
8
|
import kinks from '@turf/kinks'
|
|
7
9
|
import clean from '@turf/clean-coords'
|
|
@@ -10,13 +12,17 @@ import rhumbDistance from '@turf/rhumb-distance'
|
|
|
10
12
|
import rotate from '@turf/transform-rotate'
|
|
11
13
|
import scale from '@turf/transform-scale'
|
|
12
14
|
import translate from '@turf/transform-translate'
|
|
15
|
+
import bbox from "@turf/bbox"
|
|
16
|
+
import convex from '@turf/convex'
|
|
13
17
|
import { api, Time } from '../../../core/client/index.js'
|
|
14
18
|
import { listenToServiceEvents, unlistenToServiceEvents } from '../../../core/client/utils/index.js'
|
|
19
|
+
import { getStyleType } from './utils.style.js'
|
|
15
20
|
import { isInMemoryLayer, isFeatureLayer } from './utils.layers.js'
|
|
21
|
+
import { getGeoJsonFeatures } from '../utils.map.js'
|
|
16
22
|
import chroma from 'chroma-js'
|
|
17
23
|
|
|
18
|
-
export function processFeatures(geoJson, processor) {
|
|
19
|
-
const features = (geoJson
|
|
24
|
+
export function processFeatures (geoJson, processor) {
|
|
25
|
+
const features = getGeoJsonFeatures(geoJson)
|
|
20
26
|
if (typeof processor === 'function') {
|
|
21
27
|
features.forEach(feature => processor(feature))
|
|
22
28
|
} else if (typeof processor === 'string') {
|
|
@@ -25,8 +31,8 @@ export function processFeatures(geoJson, processor) {
|
|
|
25
31
|
}
|
|
26
32
|
}
|
|
27
33
|
|
|
28
|
-
export function transformFeatures(geoJson, transform) {
|
|
29
|
-
const features = (geoJson
|
|
34
|
+
export function transformFeatures (geoJson, transform) {
|
|
35
|
+
const features = getGeoJsonFeatures(geoJson)
|
|
30
36
|
features.forEach(feature => {
|
|
31
37
|
const scaling = _.get(transform, 'scale')
|
|
32
38
|
const rotation = _.get(transform, 'rotate')
|
|
@@ -54,18 +60,40 @@ export function transformFeatures(geoJson, transform) {
|
|
|
54
60
|
})
|
|
55
61
|
}
|
|
56
62
|
|
|
57
|
-
export
|
|
58
|
-
|
|
63
|
+
export function computeBoundingBox (geoJson, padding = 0) {
|
|
64
|
+
if (!geoJson) return
|
|
65
|
+
const box = bbox(geoJson)
|
|
66
|
+
if (!_.every(box, _.isFinite)) return null
|
|
67
|
+
if (!padding) return box
|
|
68
|
+
// compute padding
|
|
69
|
+
const padX = (box[2] - box[0]) * padding
|
|
70
|
+
const padY = (box[3] - box[1]) * padding
|
|
71
|
+
return [box[0] - padX, box[1] - padY, box[2] + padX, box[3] + padY]
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function computeConvexHull (geoJson) {
|
|
75
|
+
if (!geoJson) return
|
|
76
|
+
const points = explode(geoJson)
|
|
77
|
+
const count = _.size(points.features)
|
|
78
|
+
if (count === 0) return null
|
|
79
|
+
if (count === 1) return points.features[0]
|
|
80
|
+
if (count === 2) return lineString(points.features.map(point => point.geometry.coordinates))
|
|
81
|
+
const hull = convex(points)
|
|
82
|
+
// specific case if points are colinear
|
|
83
|
+
if (!hull) return lineString(points.features.map(point => point.geometry.coordinates))
|
|
84
|
+
return hull
|
|
85
|
+
}
|
|
59
86
|
|
|
87
|
+
export async function buildGradientPath (geoJson, options) {
|
|
88
|
+
const variable = options.build.variable
|
|
60
89
|
// Check if the GeoJSON is a FeatureCollection
|
|
61
90
|
if (!geoJson || geoJson.type !== 'FeatureCollection') {
|
|
62
|
-
|
|
91
|
+
logger.warn('[KDK] Invalid GeoJSON, a FeatureCollection is required to build a gradient path')
|
|
63
92
|
return
|
|
64
93
|
}
|
|
65
|
-
|
|
66
94
|
// Check chromajs has required infos
|
|
67
95
|
if (!variable.chromajs.colors) {
|
|
68
|
-
|
|
96
|
+
logger.warn(`[KDK] Invalid chromajs on variable ${variable.name}, missing colors.`)
|
|
69
97
|
return
|
|
70
98
|
}
|
|
71
99
|
let scale
|
|
@@ -75,30 +103,25 @@ export async function buildGradientPath(geoJson, options) {
|
|
|
75
103
|
scale = chroma.scale(variable.chromajs.colors).classes(variable.chromajs.classes)
|
|
76
104
|
}
|
|
77
105
|
if (!scale) {
|
|
78
|
-
|
|
106
|
+
logger.warn(`[KDK] Invalid chromajs on variable ${variable.name}, missing domain or classes.`)
|
|
79
107
|
return
|
|
80
108
|
}
|
|
81
|
-
|
|
82
109
|
geoJson.features = geoJson.features.map((feature) => {
|
|
83
110
|
const geometries = feature.geometry.geometries.map(g => g.coordinates)
|
|
84
111
|
const values = feature.properties[variable.name]
|
|
85
|
-
|
|
112
|
+
const gradient = values.map(value => scale(value).hex())
|
|
86
113
|
// Check if the feature has at least two geometries and they are different
|
|
87
|
-
if (geometries.length < 2
|
|
88
|
-
|
|
89
|
-
// convert it to a point
|
|
114
|
+
if (geometries.length < 2) {
|
|
115
|
+
// Make it a line
|
|
90
116
|
return {
|
|
91
117
|
type: 'Feature',
|
|
92
118
|
geometry: {
|
|
93
|
-
type: '
|
|
94
|
-
coordinates: geometries[0],
|
|
119
|
+
type: 'LineString',
|
|
120
|
+
coordinates: [ geometries[0], geometries[0] ]
|
|
95
121
|
},
|
|
96
|
-
properties: feature.properties,
|
|
122
|
+
properties: Object.assign({ gradient: [ gradient[0], gradient[0] ] }, _.omit(feature.properties, variable.name), variable.gradientPath.properties)
|
|
97
123
|
}
|
|
98
124
|
}
|
|
99
|
-
|
|
100
|
-
const gradient = values.map(value => scale(value).hex())
|
|
101
|
-
|
|
102
125
|
return {
|
|
103
126
|
type: 'Feature',
|
|
104
127
|
geometry: {
|
|
@@ -108,11 +131,10 @@ export async function buildGradientPath(geoJson, options) {
|
|
|
108
131
|
properties: Object.assign({ gradient }, _.omit(feature.properties, variable.name), variable.gradientPath.properties)
|
|
109
132
|
}
|
|
110
133
|
})
|
|
111
|
-
|
|
112
134
|
geoJson.total = geoJson.features.length
|
|
113
135
|
}
|
|
114
136
|
|
|
115
|
-
async function checkBuildInstructions(options) {
|
|
137
|
+
async function checkBuildInstructions (options) {
|
|
116
138
|
const knownInstructions = ['gradientPath']
|
|
117
139
|
if (!options.variables) return
|
|
118
140
|
|
|
@@ -125,7 +147,7 @@ async function checkBuildInstructions(options) {
|
|
|
125
147
|
}
|
|
126
148
|
}
|
|
127
149
|
|
|
128
|
-
export async function getBaseQueryForFeatures(options) {
|
|
150
|
+
export async function getBaseQueryForFeatures (options) {
|
|
129
151
|
// Any base query to process ?
|
|
130
152
|
const baseQuery = {}
|
|
131
153
|
if (options.baseQuery) {
|
|
@@ -141,7 +163,7 @@ export async function getBaseQueryForFeatures(options) {
|
|
|
141
163
|
return baseQuery
|
|
142
164
|
}
|
|
143
165
|
|
|
144
|
-
export async function getFilterQueryForFeatures(options) {
|
|
166
|
+
export async function getFilterQueryForFeatures (options) {
|
|
145
167
|
// Any filter query to process ?
|
|
146
168
|
const filterQuery = {}
|
|
147
169
|
if (options.filterQuery) {
|
|
@@ -173,7 +195,7 @@ export async function getFilterQueryForFeatures(options) {
|
|
|
173
195
|
return filterQuery
|
|
174
196
|
}
|
|
175
197
|
|
|
176
|
-
export async function getSortQueryForFeatures(options) {
|
|
198
|
+
export async function getSortQueryForFeatures (options) {
|
|
177
199
|
// Any sort query to process ?
|
|
178
200
|
const sortQuery = {}
|
|
179
201
|
if (options.sortQuery) {
|
|
@@ -187,12 +209,12 @@ export async function getSortQueryForFeatures(options) {
|
|
|
187
209
|
return { $sort: sortQuery }
|
|
188
210
|
}
|
|
189
211
|
|
|
190
|
-
export function getFeaturesUpdateInterval(options) {
|
|
212
|
+
export function getFeaturesUpdateInterval (options) {
|
|
191
213
|
const interval = _.get(options, 'every')
|
|
192
214
|
return (interval ? moment.duration(interval) : null)
|
|
193
215
|
}
|
|
194
216
|
|
|
195
|
-
export function getFeaturesQueryInterval(options) {
|
|
217
|
+
export function getFeaturesQueryInterval (options) {
|
|
196
218
|
const interval = getFeaturesUpdateInterval(options)
|
|
197
219
|
let queryInterval = _.get(options, 'queryFrom')
|
|
198
220
|
// If query interval not given use 2 x refresh interval as default value
|
|
@@ -214,7 +236,7 @@ export function shouldSkipFeaturesUpdate(lastUpdateTime, options, interval) {
|
|
|
214
236
|
return (Math.abs(elapsed.asMilliseconds()) < interval.asMilliseconds())
|
|
215
237
|
}
|
|
216
238
|
|
|
217
|
-
export async function getProbeFeatures(options) {
|
|
239
|
+
export async function getProbeFeatures (options) {
|
|
218
240
|
// Any base/filter/sort query to process ?
|
|
219
241
|
const query = await getBaseQueryForFeatures(options)
|
|
220
242
|
const filterQuery = await getFilterQueryForFeatures(options)
|
|
@@ -228,7 +250,7 @@ export async function getProbeFeatures(options) {
|
|
|
228
250
|
return response
|
|
229
251
|
}
|
|
230
252
|
|
|
231
|
-
export async function getFeaturesQuery(options, queryInterval, queryLevel) {
|
|
253
|
+
export async function getFeaturesQuery (options, queryInterval, queryLevel) {
|
|
232
254
|
// If not given try to compute query interval from options
|
|
233
255
|
if (!queryInterval) {
|
|
234
256
|
queryInterval = getFeaturesQueryInterval(options)
|
|
@@ -306,7 +328,7 @@ export async function getFeaturesQuery(options, queryInterval, queryLevel) {
|
|
|
306
328
|
return query
|
|
307
329
|
}
|
|
308
330
|
|
|
309
|
-
export function isFeatureInQueryInterval(feature, options) {
|
|
331
|
+
export function isFeatureInQueryInterval (feature, options) {
|
|
310
332
|
// We assume this is not a time-varying layer
|
|
311
333
|
if (!feature.time) return true
|
|
312
334
|
const queryInterval = getFeaturesQueryInterval(options)
|
|
@@ -324,7 +346,7 @@ export function isFeatureInQueryInterval(feature, options) {
|
|
|
324
346
|
return time.isSameOrAfter(gte) && time.isSameOrBefore(lte)
|
|
325
347
|
}
|
|
326
348
|
|
|
327
|
-
export async function getFeaturesFromQuery(options, query) {
|
|
349
|
+
export async function getFeaturesFromQuery (options, query) {
|
|
328
350
|
// Check API to be used in case the layer is coming from a remote "planet"
|
|
329
351
|
const planetApi = (typeof options.getPlanetApi === 'function' ? options.getPlanetApi() : api)
|
|
330
352
|
const response = await planetApi.getService(options.service).find(Object.assign({ query }, options.baseParams))
|
|
@@ -342,7 +364,7 @@ export async function getFeaturesFromQuery(options, query) {
|
|
|
342
364
|
return response
|
|
343
365
|
}
|
|
344
366
|
|
|
345
|
-
export function getMeasureForFeatureBaseQuery(layer, feature) {
|
|
367
|
+
export function getMeasureForFeatureBaseQuery (layer, feature) {
|
|
346
368
|
// We might have a different ID to identify measures related to a timeseries (what is called a chronicle)
|
|
347
369
|
// than measures displayed on a map. For instance mobile measures might appear at different locations,
|
|
348
370
|
// but when selecting one we would like to display the timeseries related to all locations.
|
|
@@ -356,7 +378,7 @@ export function getMeasureForFeatureBaseQuery(layer, feature) {
|
|
|
356
378
|
return query
|
|
357
379
|
}
|
|
358
380
|
|
|
359
|
-
export async function getMeasureForFeatureQuery(layer, feature, startTime, endTime, level) {
|
|
381
|
+
export async function getMeasureForFeatureQuery (layer, feature, startTime, endTime, level) {
|
|
360
382
|
const query = await getFeaturesQuery(_.merge({
|
|
361
383
|
baseQuery: getMeasureForFeatureBaseQuery(layer, feature)
|
|
362
384
|
}, layer), {
|
|
@@ -366,12 +388,12 @@ export async function getMeasureForFeatureQuery(layer, feature, startTime, endTi
|
|
|
366
388
|
return query
|
|
367
389
|
}
|
|
368
390
|
|
|
369
|
-
export async function getMeasureForFeatureFromQuery(layer, feature, query) {
|
|
391
|
+
export async function getMeasureForFeatureFromQuery (layer, feature, query) {
|
|
370
392
|
const result = await getFeaturesFromQuery(layer, query)
|
|
371
393
|
return _.get(result, 'features[0]')
|
|
372
394
|
}
|
|
373
395
|
|
|
374
|
-
export async function getMeasureForFeature(layer, feature, startTime, endTime, level) {
|
|
396
|
+
export async function getMeasureForFeature (layer, feature, startTime, endTime, level) {
|
|
375
397
|
let probedLocation
|
|
376
398
|
try {
|
|
377
399
|
const query = await getMeasureForFeatureQuery(layer, feature, startTime, endTime, level)
|
|
@@ -382,11 +404,59 @@ export async function getMeasureForFeature(layer, feature, startTime, endTime, l
|
|
|
382
404
|
return probedLocation
|
|
383
405
|
}
|
|
384
406
|
|
|
385
|
-
|
|
407
|
+
const JstsErrorI18nKeys = [
|
|
408
|
+
'GEOMETRY_ERROR',
|
|
409
|
+
'GEOMETRY_REPEATED_POINT',
|
|
410
|
+
'GEOMETRY_HOLE_OUTSIDE_SHELL',
|
|
411
|
+
'GEOMETRY_NESTED_HOLES',
|
|
412
|
+
'GEOMETRY_DISCONNECTED_INTERIOR',
|
|
413
|
+
'GEOMETRY_SELF_INTERSECTION',
|
|
414
|
+
'GEOMETRY_RING_SELF_INTERSECTION',
|
|
415
|
+
'GEOMETRY_NESTED_SHELLS',
|
|
416
|
+
'GEOMETRY_DUPLICATE_RINGS',
|
|
417
|
+
'GEOMETRY_TOO_FEW_POINTS',
|
|
418
|
+
'GEOMETRY_INVALID_COORDINATES',
|
|
419
|
+
'GEOMETRY_RING_NOT_CLOSED'
|
|
420
|
+
]
|
|
421
|
+
|
|
422
|
+
export function cleanFeatures (geoJson, precision = 1e-9) {
|
|
423
|
+
let errors = []
|
|
424
|
+
const geometryTypes = new Set()
|
|
425
|
+
if (geoJson.type === 'Feature') {
|
|
426
|
+
const geometryType = _.get(geoJson, 'geometry.type')
|
|
427
|
+
if (!geometryType) {
|
|
428
|
+
logger.warn('[KDK] feature has undefined geometry')
|
|
429
|
+
return
|
|
430
|
+
}
|
|
431
|
+
geometryTypes.add(geometryType)
|
|
432
|
+
if (geometryType === 'Polygon' || geometryType === 'MultiPolygon') {
|
|
433
|
+
const reader = new jsts.io.GeoJSONReader()
|
|
434
|
+
const writer = new jsts.io.GeoJSONWriter()
|
|
435
|
+
const geometry = reader.read(geoJson.geometry)
|
|
436
|
+
const validator = new jsts.operation.valid.IsValidOp(geometry)
|
|
437
|
+
if (!validator.isValid()) {
|
|
438
|
+
errors.push({ error: 'errors.' + JstsErrorI18nKeys[validator.getValidationError()._errorType], identifier: _.get(geoJson, 'properties.id', _.get(geoJson, 'properties.name', _.get(geoJson, 'properties.label'))) })
|
|
439
|
+
const correctedGeometry = geometry.buffer(precision).buffer(-precision)
|
|
440
|
+
geoJson.geometry = writer.write(correctedGeometry)
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
} else {
|
|
444
|
+
_.forEach(geoJson.features, feature => {
|
|
445
|
+
const { errors: errs, geometryTypes: types } = cleanFeatures(feature)
|
|
446
|
+
if (errs) errors = _.concat(errors, errs)
|
|
447
|
+
if (types) {
|
|
448
|
+
_.forEach(types, type => geometryTypes.add(type))
|
|
449
|
+
}
|
|
450
|
+
})
|
|
451
|
+
}
|
|
452
|
+
return { errors, geometryTypes: Array.from(geometryTypes) }
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
export function checkFeatures (geoJson, options = {
|
|
386
456
|
kinks: true,
|
|
387
457
|
redundantCoordinates: true
|
|
388
458
|
}) {
|
|
389
|
-
const features = (geoJson
|
|
459
|
+
const features = getGeoJsonFeatures(geoJson)
|
|
390
460
|
// Removes redundant coordinates
|
|
391
461
|
if (options.redundantCoordinates) {
|
|
392
462
|
features.forEach(feature => clean(feature, { mutate: true }))
|
|
@@ -407,9 +477,9 @@ export function checkFeatures(geoJson, options = {
|
|
|
407
477
|
return { kinks: kinksFeatures }
|
|
408
478
|
}
|
|
409
479
|
|
|
410
|
-
export async function createFeatures(geoJson, layer, chunkSize = 5000, processCallback) {
|
|
480
|
+
export async function createFeatures (geoJson, layer, chunkSize = 5000, processCallback) {
|
|
411
481
|
if (!layer) return
|
|
412
|
-
const features = (geoJson
|
|
482
|
+
const features = getGeoJsonFeatures(geoJson)
|
|
413
483
|
features.forEach(feature => {
|
|
414
484
|
// Remove any temporary ID as we will use the one from MongoDB
|
|
415
485
|
delete feature._id
|
|
@@ -457,8 +527,8 @@ export async function createFeatures(geoJson, layer, chunkSize = 5000, processCa
|
|
|
457
527
|
}
|
|
458
528
|
}
|
|
459
529
|
|
|
460
|
-
export async function editFeaturesGeometry(geoJson, layer) {
|
|
461
|
-
const features = (geoJson
|
|
530
|
+
export async function editFeaturesGeometry (geoJson, layer) {
|
|
531
|
+
const features = getGeoJsonFeatures(geoJson)
|
|
462
532
|
const updatedFeatures = []
|
|
463
533
|
for (let i = 0; i < features.length; i++) {
|
|
464
534
|
const feature = features[i]
|
|
@@ -470,8 +540,8 @@ export async function editFeaturesGeometry(geoJson, layer) {
|
|
|
470
540
|
return (geoJson.type === 'FeatureCollection' ? Object.assign(geoJson, { features: updatedFeatures }) : updatedFeatures)
|
|
471
541
|
}
|
|
472
542
|
|
|
473
|
-
export async function editFeaturesProperties(geoJson, layer) {
|
|
474
|
-
const features = (geoJson
|
|
543
|
+
export async function editFeaturesProperties (geoJson, layer) {
|
|
544
|
+
const features = getGeoJsonFeatures(geoJson)
|
|
475
545
|
const updatedFeatures = []
|
|
476
546
|
for (let i = 0; i < features.length; i++) {
|
|
477
547
|
const feature = features[i]
|
|
@@ -483,8 +553,8 @@ export async function editFeaturesProperties(geoJson, layer) {
|
|
|
483
553
|
return (geoJson.type === 'FeatureCollection' ? Object.assign(geoJson, { features: updatedFeatures }) : updatedFeatures)
|
|
484
554
|
}
|
|
485
555
|
|
|
486
|
-
export async function editFeaturesStyle(geoJson, layer) {
|
|
487
|
-
const features = (geoJson
|
|
556
|
+
export async function editFeaturesStyle (geoJson, layer) {
|
|
557
|
+
const features = getGeoJsonFeatures(geoJson)
|
|
488
558
|
const updatedFeatures = []
|
|
489
559
|
for (let i = 0; i < features.length; i++) {
|
|
490
560
|
const feature = features[i]
|
|
@@ -496,12 +566,12 @@ export async function editFeaturesStyle(geoJson, layer) {
|
|
|
496
566
|
return (geoJson.type === 'FeatureCollection' ? Object.assign(geoJson, { features: updatedFeatures }) : updatedFeatures)
|
|
497
567
|
}
|
|
498
568
|
|
|
499
|
-
export async function removeFeatures(geoJson, layer) {
|
|
569
|
+
export async function removeFeatures (geoJson, layer) {
|
|
500
570
|
// Remove all features of a given layer
|
|
501
571
|
if (!geoJson) {
|
|
502
572
|
await api.getService(layer.service).remove(null, { query: { layer: layer._id } })
|
|
503
573
|
} else {
|
|
504
|
-
const features = (geoJson
|
|
574
|
+
const features = getGeoJsonFeatures(geoJson)
|
|
505
575
|
for (let i = 0; i < features.length; i++) {
|
|
506
576
|
const feature = features[i]
|
|
507
577
|
if (feature._id) await api.getService(layer.service).remove(feature._id)
|
|
@@ -509,7 +579,7 @@ export async function removeFeatures(geoJson, layer) {
|
|
|
509
579
|
}
|
|
510
580
|
}
|
|
511
581
|
|
|
512
|
-
export async function fetchGeoJson(dataSource, options = {}) {
|
|
582
|
+
export async function fetchGeoJson (dataSource, options = {}) {
|
|
513
583
|
const response = await fetch(dataSource)
|
|
514
584
|
if (response.status !== 200) {
|
|
515
585
|
throw new Error(`Impossible to fetch ${dataSource}: ` + response.status)
|
|
@@ -526,11 +596,7 @@ export function getFeatureStyleType (feature) {
|
|
|
526
596
|
logger.warn('[KDK] feature has undefined geometry')
|
|
527
597
|
return
|
|
528
598
|
}
|
|
529
|
-
|
|
530
|
-
if (['LineString', 'MultiLineString'].includes(geometryType)) return 'line'
|
|
531
|
-
if (['Polygon', 'MultiPolygon'].includes(geometryType)) return 'polygon'
|
|
532
|
-
logger.warn(`[KDK] unsupported geometry of type of ${geometryType}`)
|
|
533
|
-
return
|
|
599
|
+
return getStyleType(geometryType)
|
|
534
600
|
}
|
|
535
601
|
|
|
536
602
|
// Bind listeners to layer service events and store it in the returned object
|
|
@@ -2,18 +2,29 @@ import _ from 'lodash'
|
|
|
2
2
|
import formatcoords from 'formatcoords'
|
|
3
3
|
|
|
4
4
|
// Find the nearest time of a given one in a given moment time list
|
|
5
|
-
|
|
5
|
+
// if the time list is already sorted in ascending order use the last argument to speed up search
|
|
6
|
+
export function getNearestTime (time, times, sorted = false) {
|
|
6
7
|
// Look for the nearest time
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (diff < minDiff) {
|
|
12
|
-
minDiff = diff
|
|
13
|
-
timeIndex = index
|
|
8
|
+
if (sorted) {
|
|
9
|
+
let timeIndex = 0
|
|
10
|
+
for (; timeIndex < times.length; timeIndex++) {
|
|
11
|
+
if (time.valueOf() < times[timeIndex].valueOf()) break
|
|
14
12
|
}
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
// We've found the first index greater than the time so return the previous
|
|
14
|
+
if (timeIndex > 0) timeIndex--
|
|
15
|
+
return { index: timeIndex, difference: Math.abs(time.diff(times[timeIndex])) }
|
|
16
|
+
} else {
|
|
17
|
+
let timeIndex = -1
|
|
18
|
+
let minDiff = Infinity
|
|
19
|
+
times.forEach((currentTime, index) => {
|
|
20
|
+
const diff = Math.abs(time.diff(currentTime))
|
|
21
|
+
if (diff < minDiff) {
|
|
22
|
+
minDiff = diff
|
|
23
|
+
timeIndex = index
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
return { index: timeIndex, difference: minDiff }
|
|
27
|
+
}
|
|
17
28
|
}
|
|
18
29
|
|
|
19
30
|
// Find the minimum or maximum time interval in a given moment time list
|
|
@@ -64,3 +75,7 @@ export function coordinatesToGeoJSON (lat, lon, format, options) {
|
|
|
64
75
|
}
|
|
65
76
|
}
|
|
66
77
|
}
|
|
78
|
+
|
|
79
|
+
export function getGeoJsonFeatures (geoJson) {
|
|
80
|
+
return (Array.isArray(geoJson) ? geoJson : (geoJson.type === 'FeatureCollection' ? geoJson.features : [geoJson]))
|
|
81
|
+
}
|
|
@@ -4,14 +4,14 @@ import { Notify, Loading, uid } from 'quasar'
|
|
|
4
4
|
import explode from '@turf/explode'
|
|
5
5
|
import SphericalMercator from '@mapbox/sphericalmercator'
|
|
6
6
|
import { i18n, api, LocalCache, utils as kCoreUtils, hooks as kCoreHooks } from '../../../core/client/index.js'
|
|
7
|
-
import {
|
|
7
|
+
import { cleanFeatures, createFeatures, removeFeatures } from './utils.features.js'
|
|
8
8
|
import { PMTiles, findTile, zxyToTileId } from 'pmtiles'
|
|
9
9
|
import { sourcesToViews } from 'protomaps-leaflet'
|
|
10
10
|
import * as kMapHooks from '../hooks/index.js'
|
|
11
|
-
import { generatePropertiesSchema } from '../utils.map.js'
|
|
12
|
-
import { generateStyleTemplates, filterQueryToConditions, getDefaultStyleFromTemplates } from './utils.style.js'
|
|
11
|
+
import { generatePropertiesSchema, getGeoJsonFeatures } from '../utils.map.js'
|
|
12
|
+
import { generateStyleTemplates, filterQueryToConditions, getDefaultStyleFromTemplates, DefaultStyle, getStyleType } from './utils.style.js'
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
const InternalLayerProperties = ['actions', 'label', 'isVisible', 'isDisabled']
|
|
15
15
|
|
|
16
16
|
export function isInMemoryLayer (layer) {
|
|
17
17
|
return layer._id === undefined
|
|
@@ -330,6 +330,10 @@ export function isLayerDataEditable (layer) {
|
|
|
330
330
|
return _.get(layer, 'isDataEditable', isUserLayer(layer) && isFeatureLayer(layer))
|
|
331
331
|
}
|
|
332
332
|
|
|
333
|
+
export function isLayerFilterEditable (layer) {
|
|
334
|
+
return _.get(layer, 'isFilterEditable', isUserLayer(layer) && isFeatureLayer(layer))
|
|
335
|
+
}
|
|
336
|
+
|
|
333
337
|
export function isTerrainLayer (layer) {
|
|
334
338
|
if (layer.type === 'TerrainLayer') return true
|
|
335
339
|
const cesiumOptions = layer.cesium || layer
|
|
@@ -349,7 +353,7 @@ async function parseFiltersFromLayer (layer) {
|
|
|
349
353
|
if (!filter.style) continue
|
|
350
354
|
styles.push({
|
|
351
355
|
conditions: filterQueryToConditions(filter.active),
|
|
352
|
-
values: await styleService.get(filter.style)
|
|
356
|
+
values: _.isObject(filter.style) ? filter.style : await styleService.get(filter.style)
|
|
353
357
|
})
|
|
354
358
|
}
|
|
355
359
|
return styles
|
|
@@ -368,19 +372,27 @@ async function generateStyleFromFilters (layer, defaultStyle) {
|
|
|
368
372
|
return result
|
|
369
373
|
}
|
|
370
374
|
|
|
371
|
-
export async function editLayerStyle (layer, style) {
|
|
375
|
+
export async function editLayerStyle (layer, style, ignoreFeatureStyle = false) {
|
|
372
376
|
style = _.pick(style, ['point', 'line', 'polygon'])
|
|
373
377
|
if (layer._id) {
|
|
374
378
|
// Need to regenerate templates to update default style in them
|
|
375
379
|
const result = await generateStyleFromFilters(layer, style)
|
|
376
380
|
if (result) {
|
|
381
|
+
// Update legend
|
|
382
|
+
Object.assign(result, await getLegendForLayer(Object.assign({}, layer, result)))
|
|
383
|
+
if (ignoreFeatureStyle) result.ignoreFeatureStyle = true
|
|
377
384
|
await api.getService('catalog').patch(layer._id, result)
|
|
378
385
|
} else {
|
|
379
|
-
await
|
|
386
|
+
const legend = await getLegendForLayer(Object.assign({}, layer, { 'cesium.style': style, 'leaflet.style': style }))
|
|
387
|
+
const patch = Object.assign({}, { 'cesium.style': style, 'leaflet.style': style }, legend)
|
|
388
|
+
if (ignoreFeatureStyle) patch.ignoreFeatureStyle = true
|
|
389
|
+
await api.getService('catalog').patch(layer._id, patch)
|
|
380
390
|
}
|
|
381
391
|
} else {
|
|
382
392
|
_.set(layer, 'cesium.style', style)
|
|
383
393
|
_.set(layer, 'leaflet.style', style)
|
|
394
|
+
Object.assign(layer, await getLegendForLayer(layer))
|
|
395
|
+
if (ignoreFeatureStyle) layer.ignoreFeatureStyle = true
|
|
384
396
|
}
|
|
385
397
|
return layer
|
|
386
398
|
}
|
|
@@ -394,6 +406,106 @@ export async function updateLayerWithFiltersStyle (layer) {
|
|
|
394
406
|
await api.getService('catalog').patch(layer._id, style)
|
|
395
407
|
}
|
|
396
408
|
|
|
409
|
+
export async function editFilterStyle (layer, filter, engineStyle, style, ignoreFeatureStyle = false) {
|
|
410
|
+
if (!layer._id) return
|
|
411
|
+
const layerDefaultStyle = getDefaultStyleFromTemplates(_.get(layer, 'leaflet.style', {}))
|
|
412
|
+
|
|
413
|
+
const filters = await parseFiltersFromLayer(layer)
|
|
414
|
+
const targetFilterCondition = filterQueryToConditions(filter.active)
|
|
415
|
+
// Update filter style
|
|
416
|
+
_.forEach(filters, f => {
|
|
417
|
+
if (_.isEqual(f.conditions, targetFilterCondition)) {
|
|
418
|
+
f.values = style
|
|
419
|
+
}
|
|
420
|
+
})
|
|
421
|
+
|
|
422
|
+
// Generate new templates
|
|
423
|
+
const templates = generateStyleTemplates(_.merge({}, DefaultStyle, engineStyle, layerDefaultStyle), filters)
|
|
424
|
+
const layerFilters = _.cloneDeep(_.get(layer, 'filters', []))
|
|
425
|
+
// Update filters in layer
|
|
426
|
+
_.forEach(layerFilters, f => {
|
|
427
|
+
if (_.isEqual(f.label, filter.label) && _.isEqual(f.active, filter.active)) {
|
|
428
|
+
f.style = style._id
|
|
429
|
+
}
|
|
430
|
+
})
|
|
431
|
+
|
|
432
|
+
// Patch layer with new templates and filters
|
|
433
|
+
const patch = Object.assign(
|
|
434
|
+
{},
|
|
435
|
+
_.mapKeys(templates, (value, key) => `leaflet.${key}`),
|
|
436
|
+
_.mapKeys(templates, (value, key) => `cesium.${key}`),
|
|
437
|
+
{ filters: layerFilters }
|
|
438
|
+
)
|
|
439
|
+
if (ignoreFeatureStyle) patch.ignoreFeatureStyle = true
|
|
440
|
+
// Update legend
|
|
441
|
+
Object.assign(patch, await getLegendForLayer(Object.assign({}, layer, { filters: layerFilters })))
|
|
442
|
+
await api.getService('catalog').patch(layer._id, patch)
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
async function getLayerFiltersWithStyle (layer) {
|
|
446
|
+
const filters = _.get(layer, 'filters', [])
|
|
447
|
+
if (!filters.length) return []
|
|
448
|
+
const styleService = api.getService('styles')
|
|
449
|
+
const filtersWithStyle = []
|
|
450
|
+
for (const filter of filters) {
|
|
451
|
+
const filterWithStyle = _.cloneDeep(filter)
|
|
452
|
+
if (filter.style) {
|
|
453
|
+
filterWithStyle.linkedStyle = _.isObject(filter.style) ? filter.style : await styleService.get(filter.style)
|
|
454
|
+
}
|
|
455
|
+
filtersWithStyle.push(filterWithStyle)
|
|
456
|
+
}
|
|
457
|
+
return filtersWithStyle
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Return generic legend or filters for a layer without mutating it
|
|
461
|
+
export async function getLegendForLayer (layer) {
|
|
462
|
+
const generateLegendFromStyle = (root, style, layerGeometryTypes) => {
|
|
463
|
+
const layerStyleTypes = _.uniq(_.map(layerGeometryTypes, type => getStyleType(type)))
|
|
464
|
+
const shapes = { point: 'circle', line: 'polyline', polygon: 'rect' }
|
|
465
|
+
const symbols = []
|
|
466
|
+
_.forIn(shapes, (shape, type) => {
|
|
467
|
+
const isInLayerGeometryTypes = (layerStyleTypes.length === 0) || (layerStyleTypes.includes(type))
|
|
468
|
+
if (style[type] && isInLayerGeometryTypes) {
|
|
469
|
+
symbols.push({
|
|
470
|
+
symbol: { 'media/KShape': { options: _.merge({ shape }, _.omit(style[type], ['size'])) } },
|
|
471
|
+
label: _.get(root, 'label', _.get(root, 'name'))
|
|
472
|
+
})
|
|
473
|
+
}
|
|
474
|
+
})
|
|
475
|
+
return {
|
|
476
|
+
type: 'symbols',
|
|
477
|
+
content: {
|
|
478
|
+
symbols
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
if (_.has(layer, 'filters') && !_.isEmpty(layer.filters)) {
|
|
484
|
+
const filtersWithStyle = await getLayerFiltersWithStyle(layer)
|
|
485
|
+
let hasFilterWithStyle = false
|
|
486
|
+
_.forEach(filtersWithStyle, filter => {
|
|
487
|
+
if (!_.has(filter, 'linkedStyle')) return
|
|
488
|
+
hasFilterWithStyle = true
|
|
489
|
+
|
|
490
|
+
const filterLegend = generateLegendFromStyle(filter, filter.linkedStyle, _.get(layer, 'geometryTypes', []))
|
|
491
|
+
filter.legend = filterLegend
|
|
492
|
+
})
|
|
493
|
+
const legend = {
|
|
494
|
+
legend: { type: 'symbols', label: _.get(layer, 'label', _.get(layer, 'name')), content: {} },
|
|
495
|
+
filters: _.map(filtersWithStyle, filter => _.omit(filter, 'linkedStyle'))
|
|
496
|
+
}
|
|
497
|
+
// For now, only filter with style are displayed in the legend
|
|
498
|
+
// If no filter has style, we want to remove the legend
|
|
499
|
+
if (!hasFilterWithStyle) return { $unset: { legend: '' } }
|
|
500
|
+
return legend
|
|
501
|
+
} else {
|
|
502
|
+
const layerStyle = getDefaultStyleFromTemplates(_.get(layer, 'leaflet.style', {}))
|
|
503
|
+
const legend = generateLegendFromStyle(layer, layerStyle, _.get(layer, 'geometryTypes', []))
|
|
504
|
+
legend.label = _.get(layer, 'label', _.get(layer, 'name'))
|
|
505
|
+
return { legend }
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
397
509
|
export function generateLayerDefinition (layerSpec, geoJson) {
|
|
398
510
|
// Check wether the geoJson content is a valid geoJson
|
|
399
511
|
if (geoJson.type !== 'FeatureCollection' && geoJson.type !== 'Feature') {
|
|
@@ -446,18 +558,35 @@ export function generateLayerDefinition (layerSpec, geoJson) {
|
|
|
446
558
|
|
|
447
559
|
export async function saveGeoJsonLayer (layer, geoJson, chunkSize = 5000) {
|
|
448
560
|
// Check for invalid features first
|
|
449
|
-
const
|
|
450
|
-
|
|
561
|
+
const { errors } = cleanFeatures(geoJson)
|
|
562
|
+
|
|
563
|
+
if (errors.length > 0) {
|
|
564
|
+
const errorsByKeys = {}
|
|
565
|
+
_.forEach(errors, error => {
|
|
566
|
+
if (!_.has(errorsByKeys, error.error)) errorsByKeys[error.error] = { count: 0, features: [] }
|
|
567
|
+
errorsByKeys[error.error].count++
|
|
568
|
+
if (error.identifier) errorsByKeys[error.error].features.push(error.identifier)
|
|
569
|
+
})
|
|
570
|
+
const errorsList = _.map(errors, error => {
|
|
571
|
+
const hasIdentifiedFeatures = errorsByKeys[error.error].features.length
|
|
572
|
+
const errorString = [
|
|
573
|
+
'<li>',
|
|
574
|
+
i18n.t(error.error, { total: errorsByKeys[error.error].count }),
|
|
575
|
+
hasIdentifiedFeatures ? i18n.t('utils.layers.INVALID_FEATURES_LIST_FEATURES') : '',
|
|
576
|
+
'</li>'
|
|
577
|
+
].join('')
|
|
578
|
+
const sublist = _.map(errorsByKeys[error.error].features, featureIdentifier => {
|
|
579
|
+
return '<li class="q-ml-lg">' + featureIdentifier + '</li>'
|
|
580
|
+
}).join('')
|
|
581
|
+
return errorString + sublist
|
|
582
|
+
}).join('')
|
|
583
|
+
|
|
451
584
|
const result = await kCoreUtils.dialog({
|
|
452
|
-
title: i18n.t('utils.layers.INVALID_FEATURES_DIALOG_TITLE', { total:
|
|
453
|
-
message:
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
items: [
|
|
458
|
-
{ label: i18n.t('utils.layers.DOWNLOAD_INVALID_FEATURES_LABEL'), value: 'download' }
|
|
459
|
-
]
|
|
460
|
-
},
|
|
585
|
+
title: i18n.t('utils.layers.INVALID_FEATURES_DIALOG_TITLE', { total: errors.length }),
|
|
586
|
+
message: [
|
|
587
|
+
i18n.t('utils.layers.INVALID_FEATURES_DIALOG_MESSAGE', { total: errors.length }),
|
|
588
|
+
i18n.t('utils.layers.INVALID_FEATURES_LIST_ERRORS', { errors: errorsList })
|
|
589
|
+
].join(''),
|
|
461
590
|
html: true,
|
|
462
591
|
ok: {
|
|
463
592
|
label: i18n.t('OK'),
|
|
@@ -469,17 +598,12 @@ export async function saveGeoJsonLayer (layer, geoJson, chunkSize = 5000) {
|
|
|
469
598
|
}
|
|
470
599
|
})
|
|
471
600
|
if (!result.ok) return
|
|
472
|
-
// Export invalid features if required
|
|
473
|
-
if (_.get(result, 'data', []).includes('download')) {
|
|
474
|
-
kCoreUtils.downloadAsBlob(JSON.stringify({ type: 'FeatureCollection', features: check.kinks }),
|
|
475
|
-
i18n.t('utils.layers.INVALID_FEATURES_FILE'), 'application/json;charset=utf-8;')
|
|
476
|
-
}
|
|
477
601
|
}
|
|
478
602
|
// Change data source from in-memory to features service
|
|
479
603
|
_.set(layer, 'service', 'features')
|
|
480
604
|
if (_.has(layer, 'leaflet')) _.set(layer, 'leaflet.source', '/api/features')
|
|
481
605
|
if (_.has(layer, 'cesium')) _.set(layer, 'cesium.source', '/api/features')
|
|
482
|
-
const features = (geoJson
|
|
606
|
+
const features = getGeoJsonFeatures(geoJson)
|
|
483
607
|
// If too much data use tiling
|
|
484
608
|
// The threshold is based on the number of points and not features.
|
|
485
609
|
// Indeed otherwise the complexity will be different depending on the geometry type
|