umap-project 2.7.2__py3-none-any.whl → 2.8.0__py3-none-any.whl
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.
- umap/__init__.py +1 -1
- umap/forms.py +4 -14
- umap/locale/am_ET/LC_MESSAGES/django.mo +0 -0
- umap/locale/am_ET/LC_MESSAGES/django.po +278 -151
- umap/locale/ar/LC_MESSAGES/django.mo +0 -0
- umap/locale/ar/LC_MESSAGES/django.po +335 -141
- umap/locale/bg/LC_MESSAGES/django.mo +0 -0
- umap/locale/bg/LC_MESSAGES/django.po +279 -152
- umap/locale/br/LC_MESSAGES/django.mo +0 -0
- umap/locale/br/LC_MESSAGES/django.po +95 -79
- umap/locale/ca/LC_MESSAGES/django.mo +0 -0
- umap/locale/ca/LC_MESSAGES/django.po +85 -68
- umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- umap/locale/cs_CZ/LC_MESSAGES/django.po +78 -66
- umap/locale/da/LC_MESSAGES/django.mo +0 -0
- umap/locale/da/LC_MESSAGES/django.po +280 -153
- umap/locale/de/LC_MESSAGES/django.mo +0 -0
- umap/locale/de/LC_MESSAGES/django.po +80 -64
- umap/locale/el/LC_MESSAGES/django.mo +0 -0
- umap/locale/el/LC_MESSAGES/django.po +82 -66
- umap/locale/en/LC_MESSAGES/django.po +73 -61
- umap/locale/es/LC_MESSAGES/django.mo +0 -0
- umap/locale/es/LC_MESSAGES/django.po +75 -63
- umap/locale/et/LC_MESSAGES/django.mo +0 -0
- umap/locale/et/LC_MESSAGES/django.po +280 -153
- umap/locale/eu/LC_MESSAGES/django.mo +0 -0
- umap/locale/eu/LC_MESSAGES/django.po +82 -66
- umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
- umap/locale/fa_IR/LC_MESSAGES/django.po +80 -64
- umap/locale/fi/LC_MESSAGES/django.mo +0 -0
- umap/locale/fi/LC_MESSAGES/django.po +278 -151
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +75 -63
- umap/locale/gl/LC_MESSAGES/django.mo +0 -0
- umap/locale/gl/LC_MESSAGES/django.po +280 -153
- umap/locale/he/LC_MESSAGES/django.mo +0 -0
- umap/locale/he/LC_MESSAGES/django.po +281 -154
- umap/locale/hu/LC_MESSAGES/django.mo +0 -0
- umap/locale/hu/LC_MESSAGES/django.po +80 -64
- umap/locale/is/LC_MESSAGES/django.mo +0 -0
- umap/locale/is/LC_MESSAGES/django.po +280 -153
- umap/locale/it/LC_MESSAGES/django.mo +0 -0
- umap/locale/it/LC_MESSAGES/django.po +82 -66
- umap/locale/ja/LC_MESSAGES/django.mo +0 -0
- umap/locale/ja/LC_MESSAGES/django.po +280 -153
- umap/locale/ko/LC_MESSAGES/django.mo +0 -0
- umap/locale/ko/LC_MESSAGES/django.po +280 -153
- umap/locale/lt/LC_MESSAGES/django.mo +0 -0
- umap/locale/lt/LC_MESSAGES/django.po +280 -153
- umap/locale/ms/LC_MESSAGES/django.mo +0 -0
- umap/locale/ms/LC_MESSAGES/django.po +82 -66
- umap/locale/nl/LC_MESSAGES/django.mo +0 -0
- umap/locale/nl/LC_MESSAGES/django.po +280 -153
- umap/locale/pl/LC_MESSAGES/django.mo +0 -0
- umap/locale/pl/LC_MESSAGES/django.po +82 -66
- umap/locale/pt/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt/LC_MESSAGES/django.po +75 -63
- umap/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt_BR/LC_MESSAGES/django.po +280 -153
- umap/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt_PT/LC_MESSAGES/django.po +280 -153
- umap/locale/ru/LC_MESSAGES/django.mo +0 -0
- umap/locale/ru/LC_MESSAGES/django.po +280 -153
- umap/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
- umap/locale/sk_SK/LC_MESSAGES/django.po +280 -153
- umap/locale/sl/LC_MESSAGES/django.mo +0 -0
- umap/locale/sl/LC_MESSAGES/django.po +280 -153
- umap/locale/sr/LC_MESSAGES/django.mo +0 -0
- umap/locale/sr/LC_MESSAGES/django.po +280 -153
- umap/locale/sv/LC_MESSAGES/django.mo +0 -0
- umap/locale/sv/LC_MESSAGES/django.po +81 -65
- umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
- umap/locale/th_TH/LC_MESSAGES/django.po +257 -185
- umap/locale/tr/LC_MESSAGES/django.mo +0 -0
- umap/locale/tr/LC_MESSAGES/django.po +280 -153
- umap/locale/uk_UA/LC_MESSAGES/django.mo +0 -0
- umap/locale/uk_UA/LC_MESSAGES/django.po +280 -153
- umap/locale/vi/LC_MESSAGES/django.mo +0 -0
- umap/locale/vi/LC_MESSAGES/django.po +278 -151
- umap/locale/zh/LC_MESSAGES/django.mo +0 -0
- umap/locale/zh/LC_MESSAGES/django.po +278 -151
- umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
- umap/locale/zh_TW/LC_MESSAGES/django.po +97 -81
- umap/management/commands/empty_trash.py +35 -0
- umap/management/commands/migrate_to_S3.py +29 -0
- umap/migrations/0023_alter_datalayer_uuid.py +19 -0
- umap/migrations/0024_alter_map_share_status.py +30 -0
- umap/migrations/0025_alter_datalayer_geojson.py +24 -0
- umap/models.py +68 -116
- umap/settings/base.py +23 -3
- umap/settings/local_s3.py +45 -0
- umap/static/umap/base.css +3 -603
- umap/static/umap/content.css +5 -3
- umap/static/umap/css/bar.css +202 -0
- umap/static/umap/css/form.css +620 -0
- umap/static/umap/css/icon.css +21 -1
- umap/static/umap/css/popup.css +125 -0
- umap/static/umap/img/16-white.svg +16 -4
- umap/static/umap/img/16.svg +1 -1
- umap/static/umap/img/source/16-white.svg +46 -45
- umap/static/umap/img/source/16.svg +1 -753
- umap/static/umap/js/components/fragment.js +3 -1
- umap/static/umap/js/modules/browser.js +20 -19
- umap/static/umap/js/modules/caption.js +21 -22
- umap/static/umap/js/modules/data/features.js +120 -78
- umap/static/umap/js/modules/data/layer.js +195 -153
- umap/static/umap/js/modules/facets.js +9 -9
- umap/static/umap/js/modules/formatter.js +5 -5
- umap/static/umap/js/modules/global.js +4 -52
- umap/static/umap/js/modules/help.js +18 -21
- umap/static/umap/js/modules/importer.js +133 -56
- umap/static/umap/js/modules/importers/cadastrefr.js +4 -0
- umap/static/umap/js/modules/importers/geodatamine.js +3 -3
- umap/static/umap/js/modules/importers/overpass.js +5 -0
- umap/static/umap/js/modules/permissions.js +85 -87
- umap/static/umap/js/modules/rendering/icon.js +2 -1
- umap/static/umap/js/modules/rendering/layers/base.js +15 -15
- umap/static/umap/js/modules/rendering/layers/classified.js +1 -1
- umap/static/umap/js/modules/rendering/layers/cluster.js +1 -1
- umap/static/umap/js/modules/rendering/layers/heat.js +1 -1
- umap/static/umap/js/modules/rendering/map.js +390 -0
- umap/static/umap/js/modules/rendering/popup.js +19 -19
- umap/static/umap/js/modules/rendering/template.js +88 -21
- umap/static/umap/js/modules/rendering/ui.js +63 -14
- umap/static/umap/js/modules/request.js +2 -2
- umap/static/umap/js/modules/rules.js +22 -25
- umap/static/umap/js/modules/saving.js +47 -0
- umap/static/umap/js/modules/schema.js +6 -0
- umap/static/umap/js/modules/share.js +21 -24
- umap/static/umap/js/modules/slideshow.js +24 -20
- umap/static/umap/js/modules/sync/updaters.js +7 -9
- umap/static/umap/js/modules/tableeditor.js +20 -19
- umap/static/umap/js/modules/ui/bar.js +196 -0
- umap/static/umap/js/modules/ui/dialog.js +6 -1
- umap/static/umap/js/modules/ui/panel.js +10 -9
- umap/static/umap/js/modules/umap.js +1691 -0
- umap/static/umap/js/modules/urls.js +2 -2
- umap/static/umap/js/modules/utils.js +22 -6
- umap/static/umap/js/umap.controls.js +81 -305
- umap/static/umap/js/umap.core.js +29 -50
- umap/static/umap/js/umap.forms.js +78 -27
- umap/static/umap/keycloak.png +0 -0
- umap/static/umap/locale/am_ET.js +26 -10
- umap/static/umap/locale/am_ET.json +26 -10
- umap/static/umap/locale/ar.js +26 -10
- umap/static/umap/locale/ar.json +26 -10
- umap/static/umap/locale/ast.js +26 -10
- umap/static/umap/locale/ast.json +26 -10
- umap/static/umap/locale/bg.js +26 -10
- umap/static/umap/locale/bg.json +26 -10
- umap/static/umap/locale/br.js +27 -20
- umap/static/umap/locale/br.json +27 -20
- umap/static/umap/locale/ca.js +32 -29
- umap/static/umap/locale/ca.json +32 -29
- umap/static/umap/locale/cs_CZ.js +24 -17
- umap/static/umap/locale/cs_CZ.json +24 -17
- umap/static/umap/locale/da.js +26 -10
- umap/static/umap/locale/da.json +26 -10
- umap/static/umap/locale/de.js +21 -14
- umap/static/umap/locale/de.json +21 -14
- umap/static/umap/locale/el.js +28 -12
- umap/static/umap/locale/el.json +28 -12
- umap/static/umap/locale/en.js +14 -9
- umap/static/umap/locale/en.json +14 -9
- umap/static/umap/locale/en_US.json +26 -10
- umap/static/umap/locale/es.js +16 -13
- umap/static/umap/locale/es.json +16 -13
- umap/static/umap/locale/et.js +26 -10
- umap/static/umap/locale/et.json +26 -10
- umap/static/umap/locale/eu.js +16 -9
- umap/static/umap/locale/eu.json +16 -9
- umap/static/umap/locale/fa_IR.js +16 -9
- umap/static/umap/locale/fa_IR.json +16 -9
- umap/static/umap/locale/fi.js +26 -10
- umap/static/umap/locale/fi.json +26 -10
- umap/static/umap/locale/fr.js +14 -9
- umap/static/umap/locale/fr.json +14 -9
- umap/static/umap/locale/gl.js +26 -10
- umap/static/umap/locale/gl.json +26 -10
- umap/static/umap/locale/he.js +26 -10
- umap/static/umap/locale/he.json +26 -10
- umap/static/umap/locale/hr.js +26 -10
- umap/static/umap/locale/hr.json +26 -10
- umap/static/umap/locale/hu.js +16 -9
- umap/static/umap/locale/hu.json +16 -9
- umap/static/umap/locale/id.js +26 -10
- umap/static/umap/locale/id.json +26 -10
- umap/static/umap/locale/is.js +26 -10
- umap/static/umap/locale/is.json +26 -10
- umap/static/umap/locale/it.js +26 -10
- umap/static/umap/locale/it.json +26 -10
- umap/static/umap/locale/ja.js +26 -10
- umap/static/umap/locale/ja.json +26 -10
- umap/static/umap/locale/ko.js +26 -10
- umap/static/umap/locale/ko.json +26 -10
- umap/static/umap/locale/lt.js +26 -10
- umap/static/umap/locale/lt.json +26 -10
- umap/static/umap/locale/ms.js +28 -12
- umap/static/umap/locale/ms.json +28 -12
- umap/static/umap/locale/nl.js +28 -12
- umap/static/umap/locale/nl.json +28 -12
- umap/static/umap/locale/no.js +26 -10
- umap/static/umap/locale/no.json +26 -10
- umap/static/umap/locale/pl.js +28 -12
- umap/static/umap/locale/pl.json +28 -12
- umap/static/umap/locale/pl_PL.json +26 -10
- umap/static/umap/locale/pt.js +16 -9
- umap/static/umap/locale/pt.json +16 -9
- umap/static/umap/locale/pt_BR.js +26 -10
- umap/static/umap/locale/pt_BR.json +26 -10
- umap/static/umap/locale/pt_PT.js +16 -9
- umap/static/umap/locale/pt_PT.json +16 -9
- umap/static/umap/locale/ro.js +26 -10
- umap/static/umap/locale/ro.json +26 -10
- umap/static/umap/locale/ru.js +26 -10
- umap/static/umap/locale/ru.json +26 -10
- umap/static/umap/locale/si.js +7 -7
- umap/static/umap/locale/si.json +7 -7
- umap/static/umap/locale/sk_SK.js +26 -10
- umap/static/umap/locale/sk_SK.json +26 -10
- umap/static/umap/locale/sl.js +26 -10
- umap/static/umap/locale/sl.json +26 -10
- umap/static/umap/locale/sr.js +26 -10
- umap/static/umap/locale/sr.json +26 -10
- umap/static/umap/locale/sv.js +27 -11
- umap/static/umap/locale/sv.json +27 -11
- umap/static/umap/locale/th_TH.js +28 -12
- umap/static/umap/locale/th_TH.json +28 -12
- umap/static/umap/locale/tr.js +26 -10
- umap/static/umap/locale/tr.json +26 -10
- umap/static/umap/locale/uk_UA.js +26 -10
- umap/static/umap/locale/uk_UA.json +26 -10
- umap/static/umap/locale/vi.js +26 -10
- umap/static/umap/locale/vi.json +26 -10
- umap/static/umap/locale/vi_VN.json +26 -10
- umap/static/umap/locale/zh.js +26 -10
- umap/static/umap/locale/zh.json +26 -10
- umap/static/umap/locale/zh_CN.json +26 -10
- umap/static/umap/locale/zh_TW.Big5.json +26 -10
- umap/static/umap/locale/zh_TW.js +34 -27
- umap/static/umap/locale/zh_TW.json +34 -27
- umap/static/umap/map.css +39 -530
- umap/static/umap/unittests/URLs.js +15 -15
- umap/static/umap/unittests/utils.js +23 -1
- umap/static/umap/vars.css +2 -1
- umap/static/umap/vendors/formbuilder/Leaflet.FormBuilder.js +5 -1
- umap/storage/__init__.py +3 -0
- umap/storage/fs.py +101 -0
- umap/storage/s3.py +61 -0
- umap/templates/base.html +2 -0
- umap/templates/registration/login.html +7 -6
- umap/templates/umap/components/alerts/alert.html +4 -0
- umap/templates/umap/css.html +6 -0
- umap/templates/umap/js.html +3 -2
- umap/templates/umap/map_init.html +6 -5
- umap/templates/umap/user_dashboard.html +20 -19
- umap/tests/base.py +11 -1
- umap/tests/fixtures/empty_tile.png +0 -0
- umap/tests/fixtures/test_upload_simple_marker.json +19 -0
- umap/tests/integration/conftest.py +4 -1
- umap/tests/integration/test_anonymous_owned_map.py +18 -10
- umap/tests/integration/test_browser.py +16 -1
- umap/tests/integration/test_dashboard.py +1 -1
- umap/tests/integration/test_edit_datalayer.py +29 -7
- umap/tests/integration/test_import.py +28 -4
- umap/tests/integration/test_optimistic_merge.py +31 -8
- umap/tests/integration/test_owned_map.py +22 -16
- umap/tests/integration/test_popup.py +44 -0
- umap/tests/integration/test_save.py +35 -0
- umap/tests/integration/test_view_marker.py +12 -0
- umap/tests/integration/test_view_polyline.py +257 -0
- umap/tests/integration/test_websocket_sync.py +81 -9
- umap/tests/test_dashboard.py +82 -0
- umap/tests/test_datalayer.py +6 -7
- umap/tests/test_datalayer_s3.py +135 -0
- umap/tests/test_datalayer_views.py +28 -10
- umap/tests/test_empty_trash.py +34 -0
- umap/tests/test_map.py +12 -3
- umap/tests/test_map_views.py +69 -37
- umap/tests/test_statics.py +1 -1
- umap/tests/test_team_views.py +35 -1
- umap/tests/test_views.py +31 -52
- umap/urls.py +3 -3
- umap/views.py +126 -90
- {umap_project-2.7.2.dist-info → umap_project-2.8.0.dist-info}/METADATA +16 -14
- {umap_project-2.7.2.dist-info → umap_project-2.8.0.dist-info}/RECORD +290 -269
- {umap_project-2.7.2.dist-info → umap_project-2.8.0.dist-info}/WHEEL +1 -1
- umap/management/commands/purge_purgatory.py +0 -28
- umap/static/umap/js/umap.js +0 -1903
- umap/tests/test_purge_purgatory.py +0 -25
- /umap/{storage.py → storage/staticfiles.py} +0 -0
- {umap_project-2.7.2.dist-info → umap_project-2.8.0.dist-info}/entry_points.txt +0 -0
- {umap_project-2.7.2.dist-info → umap_project-2.8.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -20,6 +20,8 @@ import { translate } from '../i18n.js'
|
|
|
20
20
|
import { DataLayerPermissions } from '../permissions.js'
|
|
21
21
|
import { Point, LineString, Polygon } from './features.js'
|
|
22
22
|
import TableEditor from '../tableeditor.js'
|
|
23
|
+
import { ServerStored } from '../saving.js'
|
|
24
|
+
import * as Schema from '../schema.js'
|
|
23
25
|
|
|
24
26
|
export const LAYER_TYPES = [
|
|
25
27
|
DefaultLayer,
|
|
@@ -35,10 +37,11 @@ const LAYER_MAP = LAYER_TYPES.reduce((acc, klass) => {
|
|
|
35
37
|
return acc
|
|
36
38
|
}, {})
|
|
37
39
|
|
|
38
|
-
export class DataLayer {
|
|
39
|
-
constructor(
|
|
40
|
-
|
|
41
|
-
this.
|
|
40
|
+
export class DataLayer extends ServerStored {
|
|
41
|
+
constructor(umap, leafletMap, data = {}) {
|
|
42
|
+
super()
|
|
43
|
+
this._umap = umap
|
|
44
|
+
this.sync = umap.sync_engine.proxy(this)
|
|
42
45
|
this._index = Array()
|
|
43
46
|
this._features = {}
|
|
44
47
|
this._geojson = null
|
|
@@ -46,8 +49,9 @@ export class DataLayer {
|
|
|
46
49
|
this._loaded = false // Are layer metadata loaded
|
|
47
50
|
this._dataloaded = false // Are layer data loaded
|
|
48
51
|
|
|
49
|
-
this.
|
|
50
|
-
this.
|
|
52
|
+
this._leafletMap = leafletMap
|
|
53
|
+
this.parentPane = this._leafletMap.getPane('overlayPane')
|
|
54
|
+
this.pane = this._leafletMap.createPane(`datalayer${stamp(this)}`, this.parentPane)
|
|
51
55
|
this.pane.dataset.id = stamp(this)
|
|
52
56
|
// FIXME: should be on layer
|
|
53
57
|
this.renderer = L.svg({ pane: this.pane })
|
|
@@ -58,9 +62,12 @@ export class DataLayer {
|
|
|
58
62
|
editMode: 'advanced',
|
|
59
63
|
}
|
|
60
64
|
|
|
61
|
-
this._isDirty = false
|
|
62
65
|
this._isDeleted = false
|
|
63
|
-
this.
|
|
66
|
+
this._referenceVersion = data._referenceVersion
|
|
67
|
+
// Do not save it later.
|
|
68
|
+
delete data._referenceVersion
|
|
69
|
+
data.id = data.id || crypto.randomUUID()
|
|
70
|
+
|
|
64
71
|
this.setOptions(data)
|
|
65
72
|
|
|
66
73
|
if (!Utils.isObject(this.options.remoteData)) {
|
|
@@ -77,8 +84,9 @@ export class DataLayer {
|
|
|
77
84
|
}
|
|
78
85
|
this.backupOptions()
|
|
79
86
|
this.connectToMap()
|
|
80
|
-
this.permissions = new DataLayerPermissions(this)
|
|
81
|
-
|
|
87
|
+
this.permissions = new DataLayerPermissions(this._umap, this)
|
|
88
|
+
|
|
89
|
+
if (!this.createdOnServer) {
|
|
82
90
|
if (this.showAtLoad()) this.show()
|
|
83
91
|
this.isDirty = true
|
|
84
92
|
}
|
|
@@ -89,23 +97,24 @@ export class DataLayer {
|
|
|
89
97
|
if (this.isVisible()) this.propagateShow()
|
|
90
98
|
}
|
|
91
99
|
|
|
92
|
-
|
|
93
|
-
this.
|
|
100
|
+
get id() {
|
|
101
|
+
return this.options.id
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
get createdOnServer() {
|
|
105
|
+
return Boolean(this._referenceVersion)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
onDirty(status) {
|
|
94
109
|
if (status) {
|
|
95
|
-
this.map.isDirty = true
|
|
96
110
|
// A layer can be made dirty by indirect action (like dragging layers)
|
|
97
111
|
// we need to have it loaded before saving it.
|
|
98
112
|
if (!this.isLoaded()) this.fetchData()
|
|
99
113
|
} else {
|
|
100
|
-
this.map.checkDirty()
|
|
101
114
|
this.isDeleted = false
|
|
102
115
|
}
|
|
103
116
|
}
|
|
104
117
|
|
|
105
|
-
get isDirty() {
|
|
106
|
-
return this._isDirty
|
|
107
|
-
}
|
|
108
|
-
|
|
109
118
|
set isDeleted(status) {
|
|
110
119
|
this._isDeleted = status
|
|
111
120
|
if (status) this.isDirty = status
|
|
@@ -122,9 +131,7 @@ export class DataLayer {
|
|
|
122
131
|
getSyncMetadata() {
|
|
123
132
|
return {
|
|
124
133
|
subject: 'datalayer',
|
|
125
|
-
metadata: {
|
|
126
|
-
id: this.umap_id || null,
|
|
127
|
-
},
|
|
134
|
+
metadata: { id: this.id },
|
|
128
135
|
}
|
|
129
136
|
}
|
|
130
137
|
|
|
@@ -134,7 +141,7 @@ export class DataLayer {
|
|
|
134
141
|
for (const impact of impacts) {
|
|
135
142
|
switch (impact) {
|
|
136
143
|
case 'ui':
|
|
137
|
-
this.
|
|
144
|
+
this._umap.onDataLayersChanged()
|
|
138
145
|
break
|
|
139
146
|
case 'data':
|
|
140
147
|
if (fields.includes('options.type')) {
|
|
@@ -159,9 +166,9 @@ export class DataLayer {
|
|
|
159
166
|
}
|
|
160
167
|
|
|
161
168
|
autoLoaded() {
|
|
162
|
-
if (!this.
|
|
163
|
-
const datalayerIds = this.
|
|
164
|
-
let loadMe = datalayerIds.includes(this.
|
|
169
|
+
if (!this._umap.datalayersFromQueryString) return this.options.displayOnLoad
|
|
170
|
+
const datalayerIds = this._umap.datalayersFromQueryString
|
|
171
|
+
let loadMe = datalayerIds.includes(this.id.toString())
|
|
165
172
|
if (this.options.old_id) {
|
|
166
173
|
loadMe = loadMe || datalayerIds.includes(this.options.old_id.toString())
|
|
167
174
|
}
|
|
@@ -198,7 +205,7 @@ export class DataLayer {
|
|
|
198
205
|
const visible = this.isVisible()
|
|
199
206
|
if (this.layer) this.layer.clearLayers()
|
|
200
207
|
// delete this.layer?
|
|
201
|
-
if (visible) this.
|
|
208
|
+
if (visible) this._leafletMap.removeLayer(this.layer)
|
|
202
209
|
const Class = LAYER_MAP[this.options.type] || DefaultLayer
|
|
203
210
|
this.layer = new Class(this)
|
|
204
211
|
// Rendering layer changed, so let's force reset the feature rendering too.
|
|
@@ -216,13 +223,13 @@ export class DataLayer {
|
|
|
216
223
|
}
|
|
217
224
|
|
|
218
225
|
async fetchData() {
|
|
219
|
-
if (!this.
|
|
226
|
+
if (!this.createdOnServer) return
|
|
220
227
|
if (this._loading) return
|
|
221
228
|
this._loading = true
|
|
222
|
-
const [geojson, response, error] = await this.
|
|
229
|
+
const [geojson, response, error] = await this._umap.server.get(this._dataUrl())
|
|
223
230
|
if (!error) {
|
|
224
|
-
this.
|
|
225
|
-
// FIXME: for now
|
|
231
|
+
this.setReferenceVersion({ response, sync: false })
|
|
232
|
+
// FIXME: for now the _umap_options property is set dynamically from backend
|
|
226
233
|
// And thus it's not in the geojson file in the server
|
|
227
234
|
// So do not let all options to be reset
|
|
228
235
|
// Fix is a proper migration so all datalayers settings are
|
|
@@ -240,15 +247,16 @@ export class DataLayer {
|
|
|
240
247
|
|
|
241
248
|
dataChanged() {
|
|
242
249
|
if (!this.hasDataLoaded()) return
|
|
243
|
-
this.
|
|
250
|
+
this._umap.onDataLayersChanged()
|
|
244
251
|
this.layer.dataChanged()
|
|
245
252
|
}
|
|
246
253
|
|
|
247
254
|
fromGeoJSON(geojson, sync = true) {
|
|
248
|
-
this.addData(geojson, sync)
|
|
255
|
+
const features = this.addData(geojson, sync)
|
|
249
256
|
this._geojson = geojson
|
|
250
257
|
this.onDataLoaded()
|
|
251
258
|
this.dataChanged()
|
|
259
|
+
return features
|
|
252
260
|
}
|
|
253
261
|
|
|
254
262
|
onDataLoaded() {
|
|
@@ -258,6 +266,7 @@ export class DataLayer {
|
|
|
258
266
|
|
|
259
267
|
async fromUmapGeoJSON(geojson) {
|
|
260
268
|
if (geojson._storage) geojson._umap_options = geojson._storage // Retrocompat
|
|
269
|
+
geojson._umap_options.id = this.id
|
|
261
270
|
if (geojson._umap_options) this.setOptions(geojson._umap_options)
|
|
262
271
|
if (this.isRemoteLayer()) await this.fetchRemoteData()
|
|
263
272
|
else this.fromGeoJSON(geojson, false)
|
|
@@ -281,14 +290,14 @@ export class DataLayer {
|
|
|
281
290
|
|
|
282
291
|
reindex() {
|
|
283
292
|
const features = Object.values(this._features)
|
|
284
|
-
|
|
293
|
+
this.sortFeatures(features)
|
|
285
294
|
this._index = features.map((feature) => stamp(feature))
|
|
286
295
|
}
|
|
287
296
|
|
|
288
297
|
showAtZoom() {
|
|
289
298
|
const from = Number.parseInt(this.options.fromZoom, 10)
|
|
290
299
|
const to = Number.parseInt(this.options.toZoom, 10)
|
|
291
|
-
const zoom = this.
|
|
300
|
+
const zoom = this._leafletMap.getZoom()
|
|
292
301
|
return !((!Number.isNaN(from) && zoom < from) || (!Number.isNaN(to) && zoom > to))
|
|
293
302
|
}
|
|
294
303
|
|
|
@@ -300,32 +309,27 @@ export class DataLayer {
|
|
|
300
309
|
if (!this.isRemoteLayer()) return
|
|
301
310
|
if (!this.hasDynamicData() && this.hasDataLoaded() && !force) return
|
|
302
311
|
if (!this.isVisible()) return
|
|
303
|
-
let url = this.
|
|
312
|
+
let url = this._umap.renderUrl(this.options.remoteData.url)
|
|
304
313
|
if (this.options.remoteData.proxy) {
|
|
305
|
-
url = this.
|
|
314
|
+
url = this._umap.proxyUrl(url, this.options.remoteData.ttl)
|
|
306
315
|
}
|
|
307
|
-
const response = await this.
|
|
316
|
+
const response = await this._umap.request.get(url)
|
|
308
317
|
if (response?.ok) {
|
|
309
318
|
this.clear()
|
|
310
|
-
this.
|
|
319
|
+
return this._umap.formatter
|
|
311
320
|
.parse(await response.text(), this.options.remoteData.format)
|
|
312
321
|
.then((geojson) => this.fromGeoJSON(geojson))
|
|
313
322
|
}
|
|
314
323
|
}
|
|
315
324
|
|
|
316
325
|
isLoaded() {
|
|
317
|
-
return !this.
|
|
326
|
+
return !this.createdOnServer || this._loaded
|
|
318
327
|
}
|
|
319
328
|
|
|
320
329
|
hasDataLoaded() {
|
|
321
330
|
return this._dataloaded
|
|
322
331
|
}
|
|
323
332
|
|
|
324
|
-
setUmapId(id) {
|
|
325
|
-
// Datalayer is null when listening creation form
|
|
326
|
-
if (!this.umap_id && id) this.umap_id = id
|
|
327
|
-
}
|
|
328
|
-
|
|
329
333
|
backupOptions() {
|
|
330
334
|
this._backupOptions = Utils.CopyJSON(this.options)
|
|
331
335
|
}
|
|
@@ -347,25 +351,23 @@ export class DataLayer {
|
|
|
347
351
|
|
|
348
352
|
connectToMap() {
|
|
349
353
|
const id = stamp(this)
|
|
350
|
-
if (!this.
|
|
351
|
-
this.
|
|
354
|
+
if (!this._umap.datalayers[id]) {
|
|
355
|
+
this._umap.datalayers[id] = this
|
|
352
356
|
}
|
|
353
|
-
if (!this.
|
|
354
|
-
this.
|
|
357
|
+
if (!this._umap.datalayersIndex.includes(this)) {
|
|
358
|
+
this._umap.datalayersIndex.push(this)
|
|
355
359
|
}
|
|
356
|
-
this.
|
|
360
|
+
this._umap.onDataLayersChanged()
|
|
357
361
|
}
|
|
358
362
|
|
|
359
363
|
_dataUrl() {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
pk: this.umap_id,
|
|
364
|
-
map_id: this.map.options.umap_id,
|
|
364
|
+
let url = this._umap.urls.get('datalayer_view', {
|
|
365
|
+
pk: this.id,
|
|
366
|
+
map_id: this._umap.id,
|
|
365
367
|
})
|
|
366
368
|
|
|
367
369
|
// No browser cache for owners/editors.
|
|
368
|
-
if (this.
|
|
370
|
+
if (this._umap.hasEditMode()) url = `${url}?${Date.now()}`
|
|
369
371
|
return url
|
|
370
372
|
}
|
|
371
373
|
|
|
@@ -392,7 +394,7 @@ export class DataLayer {
|
|
|
392
394
|
this._index.push(id)
|
|
393
395
|
this._features[id] = feature
|
|
394
396
|
this.indexProperties(feature)
|
|
395
|
-
this.
|
|
397
|
+
this._umap.featuresIndex[feature.getSlug()] = feature
|
|
396
398
|
this.showFeature(feature)
|
|
397
399
|
this.dataChanged()
|
|
398
400
|
}
|
|
@@ -401,7 +403,7 @@ export class DataLayer {
|
|
|
401
403
|
const id = stamp(feature)
|
|
402
404
|
if (sync !== false) feature.sync.delete()
|
|
403
405
|
this.hideFeature(feature)
|
|
404
|
-
delete this.
|
|
406
|
+
delete this._umap.featuresIndex[feature.getSlug()]
|
|
405
407
|
feature.disconnectFromDataLayer(this)
|
|
406
408
|
this._index.splice(this._index.indexOf(id), 1)
|
|
407
409
|
delete this._features[id]
|
|
@@ -427,6 +429,10 @@ export class DataLayer {
|
|
|
427
429
|
if (idx !== -1) this._propertiesIndex.splice(idx, 1)
|
|
428
430
|
}
|
|
429
431
|
|
|
432
|
+
allProperties() {
|
|
433
|
+
return this._propertiesIndex
|
|
434
|
+
}
|
|
435
|
+
|
|
430
436
|
sortedValues(property) {
|
|
431
437
|
return Object.values(this._features)
|
|
432
438
|
.map((feature) => feature.properties[property])
|
|
@@ -438,13 +444,19 @@ export class DataLayer {
|
|
|
438
444
|
try {
|
|
439
445
|
// Do not fail if remote data is somehow invalid,
|
|
440
446
|
// otherwise the layer becomes uneditable.
|
|
441
|
-
this.makeFeatures(geojson, sync)
|
|
447
|
+
return this.makeFeatures(geojson, sync)
|
|
442
448
|
} catch (err) {
|
|
443
|
-
console.log('Error with DataLayer', this.
|
|
449
|
+
console.log('Error with DataLayer', this.id)
|
|
444
450
|
console.error(err)
|
|
451
|
+
return []
|
|
445
452
|
}
|
|
446
453
|
}
|
|
447
454
|
|
|
455
|
+
sortFeatures(collection) {
|
|
456
|
+
const sortKeys = this._umap.getProperty('sortKey') || U.DEFAULT_LABEL_KEY
|
|
457
|
+
return Utils.sortFeatures(collection, sortKeys, U.lang)
|
|
458
|
+
}
|
|
459
|
+
|
|
448
460
|
makeFeatures(geojson = {}, sync = true) {
|
|
449
461
|
if (geojson.type === 'Feature' || geojson.coordinates) {
|
|
450
462
|
geojson = [geojson]
|
|
@@ -452,10 +464,14 @@ export class DataLayer {
|
|
|
452
464
|
const collection = Array.isArray(geojson)
|
|
453
465
|
? geojson
|
|
454
466
|
: geojson.features || geojson.geometries
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
467
|
+
if (!collection) return
|
|
468
|
+
const features = []
|
|
469
|
+
this.sortFeatures(collection)
|
|
470
|
+
for (const featureJson of collection) {
|
|
471
|
+
const feature = this.makeFeature(featureJson, sync)
|
|
472
|
+
if (feature) features.push(feature)
|
|
458
473
|
}
|
|
474
|
+
return features
|
|
459
475
|
}
|
|
460
476
|
|
|
461
477
|
makeFeature(geojson = {}, sync = true, id = null) {
|
|
@@ -466,15 +482,15 @@ export class DataLayer {
|
|
|
466
482
|
switch (geometry.type) {
|
|
467
483
|
case 'Point':
|
|
468
484
|
// FIXME: deal with MultiPoint
|
|
469
|
-
feature = new Point(this, geojson, id)
|
|
485
|
+
feature = new Point(this._umap, this, geojson, id)
|
|
470
486
|
break
|
|
471
487
|
case 'MultiLineString':
|
|
472
488
|
case 'LineString':
|
|
473
|
-
feature = new LineString(this, geojson, id)
|
|
489
|
+
feature = new LineString(this._umap, this, geojson, id)
|
|
474
490
|
break
|
|
475
491
|
case 'MultiPolygon':
|
|
476
492
|
case 'Polygon':
|
|
477
|
-
feature = new Polygon(this, geojson, id)
|
|
493
|
+
feature = new Polygon(this._umap, this, geojson, id)
|
|
478
494
|
break
|
|
479
495
|
default:
|
|
480
496
|
console.log(geojson)
|
|
@@ -492,57 +508,71 @@ export class DataLayer {
|
|
|
492
508
|
}
|
|
493
509
|
|
|
494
510
|
async importRaw(raw, format) {
|
|
495
|
-
this.
|
|
511
|
+
return this._umap.formatter
|
|
496
512
|
.parse(raw, format)
|
|
497
513
|
.then((geojson) => this.addData(geojson))
|
|
498
|
-
.then(() =>
|
|
499
|
-
|
|
514
|
+
.then((data) => {
|
|
515
|
+
if (data?.length) this.isDirty = true
|
|
516
|
+
return data
|
|
517
|
+
})
|
|
500
518
|
}
|
|
501
519
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
520
|
+
readFile(f) {
|
|
521
|
+
return new Promise((resolve) => {
|
|
522
|
+
const reader = new FileReader()
|
|
523
|
+
reader.onloadend = () => resolve(reader.result)
|
|
524
|
+
reader.readAsText(f)
|
|
525
|
+
})
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
async importFromFiles(files, type) {
|
|
529
|
+
const toLoad = []
|
|
530
|
+
for (const file of files) {
|
|
531
|
+
toLoad.push(this.importFromFile(file, type))
|
|
505
532
|
}
|
|
533
|
+
const features = await Promise.all(toLoad)
|
|
534
|
+
return new Promise((resolve) => {
|
|
535
|
+
resolve([].concat(...features))
|
|
536
|
+
})
|
|
506
537
|
}
|
|
507
538
|
|
|
508
|
-
importFromFile(
|
|
509
|
-
const reader = new FileReader()
|
|
539
|
+
async importFromFile(file, type) {
|
|
510
540
|
type = type || Utils.detectFileType(f)
|
|
511
|
-
|
|
512
|
-
|
|
541
|
+
const raw = await this.readFile(file)
|
|
542
|
+
return this.importRaw(raw, type)
|
|
513
543
|
}
|
|
514
544
|
|
|
515
545
|
async importFromUrl(uri, type) {
|
|
516
|
-
uri = this.
|
|
517
|
-
const response = await this.
|
|
546
|
+
uri = this._umap.renderUrl(uri)
|
|
547
|
+
const response = await this._umap.request.get(uri)
|
|
518
548
|
if (response?.ok) {
|
|
519
|
-
this.importRaw(await response.text(), type)
|
|
549
|
+
return this.importRaw(await response.text(), type)
|
|
520
550
|
}
|
|
521
551
|
}
|
|
522
552
|
|
|
523
553
|
getColor() {
|
|
524
|
-
return this.options.color || this.
|
|
554
|
+
return this.options.color || this._umap.getProperty('color')
|
|
525
555
|
}
|
|
526
556
|
|
|
527
557
|
getDeleteUrl() {
|
|
528
|
-
return
|
|
529
|
-
pk: this.
|
|
530
|
-
map_id: this.
|
|
558
|
+
return this._umap.urls.get('datalayer_delete', {
|
|
559
|
+
pk: this.id,
|
|
560
|
+
map_id: this._umap.id,
|
|
531
561
|
})
|
|
532
562
|
}
|
|
533
563
|
|
|
534
564
|
getVersionsUrl() {
|
|
535
|
-
return
|
|
536
|
-
pk: this.
|
|
537
|
-
map_id: this.
|
|
565
|
+
return this._umap.urls.get('datalayer_versions', {
|
|
566
|
+
pk: this.id,
|
|
567
|
+
map_id: this._umap.id,
|
|
538
568
|
})
|
|
539
569
|
}
|
|
540
570
|
|
|
541
|
-
getVersionUrl(
|
|
542
|
-
return
|
|
543
|
-
pk: this.
|
|
544
|
-
map_id: this.
|
|
545
|
-
|
|
571
|
+
getVersionUrl(ref) {
|
|
572
|
+
return this._umap.urls.get('datalayer_version', {
|
|
573
|
+
pk: this.id,
|
|
574
|
+
map_id: this._umap.id,
|
|
575
|
+
ref: ref,
|
|
546
576
|
})
|
|
547
577
|
}
|
|
548
578
|
|
|
@@ -562,17 +592,17 @@ export class DataLayer {
|
|
|
562
592
|
options.name = translate('Clone of {name}', { name: this.options.name })
|
|
563
593
|
delete options.id
|
|
564
594
|
const geojson = Utils.CopyJSON(this._geojson)
|
|
565
|
-
const datalayer = this.
|
|
595
|
+
const datalayer = this._umap.createDataLayer(options)
|
|
566
596
|
datalayer.fromGeoJSON(geojson)
|
|
567
597
|
return datalayer
|
|
568
598
|
}
|
|
569
599
|
|
|
570
600
|
erase() {
|
|
571
601
|
this.hide()
|
|
572
|
-
this.
|
|
602
|
+
this._umap.datalayersIndex.splice(this.getRank(), 1)
|
|
573
603
|
this.parentPane.removeChild(this.pane)
|
|
574
|
-
this.
|
|
575
|
-
this.layer.onDelete(this.
|
|
604
|
+
this._umap.onDataLayersChanged()
|
|
605
|
+
this.layer.onDelete(this._leafletMap)
|
|
576
606
|
this.propagateDelete()
|
|
577
607
|
this._leaflet_events_bk = this._leaflet_events
|
|
578
608
|
this.clear()
|
|
@@ -581,7 +611,10 @@ export class DataLayer {
|
|
|
581
611
|
}
|
|
582
612
|
|
|
583
613
|
reset() {
|
|
584
|
-
if (!this.
|
|
614
|
+
if (!this.createdOnServer) {
|
|
615
|
+
this.erase()
|
|
616
|
+
return
|
|
617
|
+
}
|
|
585
618
|
|
|
586
619
|
this.resetOptions()
|
|
587
620
|
this.parentPane.appendChild(this.pane)
|
|
@@ -604,7 +637,7 @@ export class DataLayer {
|
|
|
604
637
|
}
|
|
605
638
|
|
|
606
639
|
edit() {
|
|
607
|
-
if (!this.
|
|
640
|
+
if (!this._umap.editEnabled || !this.isLoaded()) {
|
|
608
641
|
return
|
|
609
642
|
}
|
|
610
643
|
const container = DomUtil.create('div', 'umap-layer-properties-container')
|
|
@@ -615,6 +648,7 @@ export class DataLayer {
|
|
|
615
648
|
'options.type',
|
|
616
649
|
{ handler: 'LayerTypeChooser', label: translate('Type of layer') },
|
|
617
650
|
],
|
|
651
|
+
'options.labelKey',
|
|
618
652
|
[
|
|
619
653
|
'options.displayOnLoad',
|
|
620
654
|
{ label: translate('Display on load'), handler: 'Switch' },
|
|
@@ -638,7 +672,7 @@ export class DataLayer {
|
|
|
638
672
|
DomUtil.createTitle(container, translate('Layer properties'), 'icon-layers')
|
|
639
673
|
let builder = new U.FormBuilder(this, metadataFields, {
|
|
640
674
|
callback(e) {
|
|
641
|
-
this.
|
|
675
|
+
this._umap.onDataLayersChanged()
|
|
642
676
|
if (e.helper.field === 'options.type') {
|
|
643
677
|
this.edit()
|
|
644
678
|
}
|
|
@@ -687,7 +721,6 @@ export class DataLayer {
|
|
|
687
721
|
'options.zoomTo',
|
|
688
722
|
'options.fromZoom',
|
|
689
723
|
'options.toZoom',
|
|
690
|
-
'options.labelKey',
|
|
691
724
|
]
|
|
692
725
|
|
|
693
726
|
builder = new U.FormBuilder(this, optionsFields, {
|
|
@@ -749,7 +782,7 @@ export class DataLayer {
|
|
|
749
782
|
},
|
|
750
783
|
],
|
|
751
784
|
]
|
|
752
|
-
if (this.
|
|
785
|
+
if (this._umap.properties.urls.ajax_proxy) {
|
|
753
786
|
remoteDataFields.push([
|
|
754
787
|
'options.remoteData.proxy',
|
|
755
788
|
{
|
|
@@ -775,7 +808,8 @@ export class DataLayer {
|
|
|
775
808
|
this
|
|
776
809
|
)
|
|
777
810
|
|
|
778
|
-
if (this.
|
|
811
|
+
if (this._umap.properties.urls.datalayer_versions)
|
|
812
|
+
this.buildVersionsFieldset(container)
|
|
779
813
|
|
|
780
814
|
const advancedActions = DomUtil.createFieldset(
|
|
781
815
|
container,
|
|
@@ -788,7 +822,7 @@ export class DataLayer {
|
|
|
788
822
|
</button>`)
|
|
789
823
|
deleteButton.addEventListener('click', () => {
|
|
790
824
|
this._delete()
|
|
791
|
-
this.
|
|
825
|
+
this._umap.editPanel.close()
|
|
792
826
|
})
|
|
793
827
|
advancedButtons.appendChild(deleteButton)
|
|
794
828
|
|
|
@@ -811,7 +845,7 @@ export class DataLayer {
|
|
|
811
845
|
},
|
|
812
846
|
this
|
|
813
847
|
)
|
|
814
|
-
if (this.
|
|
848
|
+
if (this.createdOnServer) {
|
|
815
849
|
const filename = `${Utils.slugify(this.options.name)}.geojson`
|
|
816
850
|
const download = Utils.loadTemplate(`
|
|
817
851
|
<a class="button" href="${this._dataUrl()}" download="${filename}">
|
|
@@ -827,9 +861,9 @@ export class DataLayer {
|
|
|
827
861
|
// Fixme: remove me when this is merged and released
|
|
828
862
|
// https://github.com/Leaflet/Leaflet/pull/9052
|
|
829
863
|
DomEvent.disableClickPropagation(backButton)
|
|
830
|
-
DomEvent.on(backButton, 'click', this.
|
|
864
|
+
DomEvent.on(backButton, 'click', this._umap.editDatalayers, this._umap)
|
|
831
865
|
|
|
832
|
-
this.
|
|
866
|
+
this._umap.editPanel.open({
|
|
833
867
|
content: container,
|
|
834
868
|
actions: [backButton],
|
|
835
869
|
})
|
|
@@ -850,28 +884,22 @@ export class DataLayer {
|
|
|
850
884
|
if (this.layer?.defaults?.[option]) {
|
|
851
885
|
return this.layer.defaults[option]
|
|
852
886
|
}
|
|
853
|
-
return this.
|
|
887
|
+
return this._umap.getProperty(option, feature)
|
|
854
888
|
}
|
|
855
889
|
|
|
856
890
|
async buildVersionsFieldset(container) {
|
|
857
891
|
const appendVersion = (data) => {
|
|
858
892
|
const date = new Date(Number.parseInt(data.at, 10))
|
|
859
|
-
const content = `${date.toLocaleString(
|
|
893
|
+
const content = `${date.toLocaleString(U.lang)} (${Number.parseInt(data.size) / 1000}Kb)`
|
|
860
894
|
const el = DomUtil.create('div', 'umap-datalayer-version', versionsContainer)
|
|
861
|
-
const button = DomUtil.createButton(
|
|
862
|
-
'',
|
|
863
|
-
el,
|
|
864
|
-
'',
|
|
865
|
-
() => this.restore(data.name),
|
|
866
|
-
this
|
|
867
|
-
)
|
|
895
|
+
const button = DomUtil.createButton('', el, '', () => this.restore(data.ref))
|
|
868
896
|
button.title = translate('Restore this version')
|
|
869
897
|
DomUtil.add('span', '', el, content)
|
|
870
898
|
}
|
|
871
899
|
|
|
872
900
|
const versionsContainer = DomUtil.createFieldset(container, translate('Versions'), {
|
|
873
901
|
async callback() {
|
|
874
|
-
const [{ versions }, response, error] = await this.
|
|
902
|
+
const [{ versions }, response, error] = await this._umap.server.get(
|
|
875
903
|
this.getVersionsUrl()
|
|
876
904
|
)
|
|
877
905
|
if (!error) versions.forEach(appendVersion)
|
|
@@ -881,11 +909,11 @@ export class DataLayer {
|
|
|
881
909
|
}
|
|
882
910
|
|
|
883
911
|
async restore(version) {
|
|
884
|
-
if (!this.
|
|
885
|
-
this.
|
|
912
|
+
if (!this._umap.editEnabled) return
|
|
913
|
+
this._umap.dialog
|
|
886
914
|
.confirm(translate('Are you sure you want to restore this version?'))
|
|
887
915
|
.then(async () => {
|
|
888
|
-
const [geojson, response, error] = await this.
|
|
916
|
+
const [geojson, response, error] = await this._umap.server.get(
|
|
889
917
|
this.getVersionUrl(version)
|
|
890
918
|
)
|
|
891
919
|
if (!error) {
|
|
@@ -906,13 +934,13 @@ export class DataLayer {
|
|
|
906
934
|
}
|
|
907
935
|
|
|
908
936
|
async show() {
|
|
909
|
-
this.
|
|
937
|
+
this._leafletMap.addLayer(this.layer)
|
|
910
938
|
if (!this.isLoaded()) await this.fetchData()
|
|
911
939
|
this.propagateShow()
|
|
912
940
|
}
|
|
913
941
|
|
|
914
942
|
hide() {
|
|
915
|
-
this.
|
|
943
|
+
this._leafletMap.removeLayer(this.layer)
|
|
916
944
|
this.propagateHide()
|
|
917
945
|
}
|
|
918
946
|
|
|
@@ -924,12 +952,12 @@ export class DataLayer {
|
|
|
924
952
|
else this.hide()
|
|
925
953
|
}
|
|
926
954
|
|
|
927
|
-
zoomTo() {
|
|
955
|
+
zoomTo(bounds) {
|
|
928
956
|
if (!this.isVisible()) return
|
|
929
|
-
|
|
957
|
+
bounds = bounds || this.layer.getBounds()
|
|
930
958
|
if (bounds.isValid()) {
|
|
931
959
|
const options = { maxZoom: this.getOption('zoomTo') }
|
|
932
|
-
this.
|
|
960
|
+
this._leafletMap.fitBounds(bounds, options)
|
|
933
961
|
}
|
|
934
962
|
}
|
|
935
963
|
|
|
@@ -960,7 +988,7 @@ export class DataLayer {
|
|
|
960
988
|
}
|
|
961
989
|
|
|
962
990
|
isVisible() {
|
|
963
|
-
return Boolean(this.layer && this.
|
|
991
|
+
return Boolean(this.layer && this._leafletMap.hasLayer(this.layer))
|
|
964
992
|
}
|
|
965
993
|
|
|
966
994
|
getFeatureByIndex(index) {
|
|
@@ -997,7 +1025,7 @@ export class DataLayer {
|
|
|
997
1025
|
getPreviousBrowsable() {
|
|
998
1026
|
let id = this.getRank()
|
|
999
1027
|
let next
|
|
1000
|
-
const index = this.
|
|
1028
|
+
const index = this._umap.datalayersIndex
|
|
1001
1029
|
while (((id = index[++id] ? id : 0), (next = index[id]))) {
|
|
1002
1030
|
if (next === this || next.canBrowse()) break
|
|
1003
1031
|
}
|
|
@@ -1007,7 +1035,7 @@ export class DataLayer {
|
|
|
1007
1035
|
getNextBrowsable() {
|
|
1008
1036
|
let id = this.getRank()
|
|
1009
1037
|
let prev
|
|
1010
|
-
const index = this.
|
|
1038
|
+
const index = this._umap.datalayersIndex
|
|
1011
1039
|
while (((id = index[--id] ? id : index.length - 1), (prev = index[id]))) {
|
|
1012
1040
|
if (prev === this || prev.canBrowse()) break
|
|
1013
1041
|
}
|
|
@@ -1023,7 +1051,7 @@ export class DataLayer {
|
|
|
1023
1051
|
}
|
|
1024
1052
|
|
|
1025
1053
|
getRank() {
|
|
1026
|
-
return this.
|
|
1054
|
+
return this._umap.datalayersIndex.indexOf(this)
|
|
1027
1055
|
}
|
|
1028
1056
|
|
|
1029
1057
|
isReadOnly() {
|
|
@@ -1036,6 +1064,11 @@ export class DataLayer {
|
|
|
1036
1064
|
return this.isReadOnly() || this.isRemoteLayer()
|
|
1037
1065
|
}
|
|
1038
1066
|
|
|
1067
|
+
setReferenceVersion({ response, sync }) {
|
|
1068
|
+
this._referenceVersion = response.headers.get('X-Datalayer-Version')
|
|
1069
|
+
this.sync.update('_referenceVersion', this._referenceVersion)
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1039
1072
|
async save() {
|
|
1040
1073
|
if (this.isDeleted) return await this.saveDelete()
|
|
1041
1074
|
if (!this.isLoaded()) {
|
|
@@ -1050,19 +1083,21 @@ export class DataLayer {
|
|
|
1050
1083
|
// Filename support is shaky, don't do it for now.
|
|
1051
1084
|
const blob = new Blob([JSON.stringify(geojson)], { type: 'application/json' })
|
|
1052
1085
|
formData.append('geojson', blob)
|
|
1053
|
-
const
|
|
1054
|
-
map_id: this.
|
|
1055
|
-
pk: this.
|
|
1086
|
+
const saveURL = this._umap.urls.get('datalayer_save', {
|
|
1087
|
+
map_id: this._umap.id,
|
|
1088
|
+
pk: this.id,
|
|
1089
|
+
created: this.createdOnServer,
|
|
1056
1090
|
})
|
|
1057
|
-
const headers = this.
|
|
1058
|
-
? { 'X-Datalayer-Reference': this.
|
|
1091
|
+
const headers = this._referenceVersion
|
|
1092
|
+
? { 'X-Datalayer-Reference': this._referenceVersion }
|
|
1059
1093
|
: {}
|
|
1060
|
-
await this._trySave(
|
|
1094
|
+
const status = await this._trySave(saveURL, headers, formData)
|
|
1061
1095
|
this._geojson = geojson
|
|
1096
|
+
return status
|
|
1062
1097
|
}
|
|
1063
1098
|
|
|
1064
1099
|
async _trySave(url, headers, formData) {
|
|
1065
|
-
const [data, response, error] = await this.
|
|
1100
|
+
const [data, response, error] = await this._umap.server.post(url, headers, formData)
|
|
1066
1101
|
if (error) {
|
|
1067
1102
|
if (response && response.status === 412) {
|
|
1068
1103
|
AlertConflict.error(
|
|
@@ -1071,7 +1106,15 @@ export class DataLayer {
|
|
|
1071
1106
|
'This situation is tricky, you have to choose carefully which version is pertinent.'
|
|
1072
1107
|
),
|
|
1073
1108
|
async () => {
|
|
1074
|
-
|
|
1109
|
+
// Save again this layer
|
|
1110
|
+
const status = await this._trySave(url, {}, formData)
|
|
1111
|
+
if (status) {
|
|
1112
|
+
this.isDirty = false
|
|
1113
|
+
|
|
1114
|
+
// Call the main save, in case something else needs to be saved
|
|
1115
|
+
// as the conflict stopped the saving flow
|
|
1116
|
+
await this._umap.saveAll()
|
|
1117
|
+
}
|
|
1075
1118
|
}
|
|
1076
1119
|
)
|
|
1077
1120
|
}
|
|
@@ -1083,30 +1126,27 @@ export class DataLayer {
|
|
|
1083
1126
|
this.fromGeoJSON(data.geojson)
|
|
1084
1127
|
delete data.geojson
|
|
1085
1128
|
}
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
this.setUmapId(data.id)
|
|
1129
|
+
delete data.id
|
|
1130
|
+
delete data._referenceVersion
|
|
1090
1131
|
this.updateOptions(data)
|
|
1132
|
+
|
|
1133
|
+
this.setReferenceVersion({ response, sync: true })
|
|
1134
|
+
|
|
1091
1135
|
this.backupOptions()
|
|
1136
|
+
this.backupData()
|
|
1092
1137
|
this.connectToMap()
|
|
1093
1138
|
this._loaded = true
|
|
1094
1139
|
this.redraw() // Needed for reordering features
|
|
1095
|
-
|
|
1096
|
-
this.permissions.save()
|
|
1140
|
+
return true
|
|
1097
1141
|
}
|
|
1098
1142
|
}
|
|
1099
1143
|
|
|
1100
1144
|
async saveDelete() {
|
|
1101
|
-
if (this.
|
|
1102
|
-
await this.
|
|
1145
|
+
if (this.createdOnServer) {
|
|
1146
|
+
await this._umap.server.post(this.getDeleteUrl())
|
|
1103
1147
|
}
|
|
1104
|
-
delete this.
|
|
1105
|
-
|
|
1106
|
-
}
|
|
1107
|
-
|
|
1108
|
-
getMap() {
|
|
1109
|
-
return this.map
|
|
1148
|
+
delete this._umap.datalayers[stamp(this)]
|
|
1149
|
+
return true
|
|
1110
1150
|
}
|
|
1111
1151
|
|
|
1112
1152
|
getName() {
|
|
@@ -1115,7 +1155,7 @@ export class DataLayer {
|
|
|
1115
1155
|
|
|
1116
1156
|
tableEdit() {
|
|
1117
1157
|
if (!this.isVisible()) return
|
|
1118
|
-
const editor = new TableEditor(this)
|
|
1158
|
+
const editor = new TableEditor(this._umap, this, this._leafletMap)
|
|
1119
1159
|
editor.open()
|
|
1120
1160
|
}
|
|
1121
1161
|
|
|
@@ -1123,14 +1163,16 @@ export class DataLayer {
|
|
|
1123
1163
|
// This keys will be used to filter feature from the browser text input.
|
|
1124
1164
|
// By default, it will we use the "name" property, which is also the one used as label in the features list.
|
|
1125
1165
|
// When map owner has configured another label or sort key, we try to be smart and search in the same keys.
|
|
1126
|
-
if (this.
|
|
1166
|
+
if (this._umap.properties.filterKey) return this._umap.properties.filterKey
|
|
1127
1167
|
if (this.getOption('labelKey')) return this.getOption('labelKey')
|
|
1128
|
-
if (this.
|
|
1168
|
+
if (this._umap.properties.sortKey) return this._umap.properties.sortKey
|
|
1129
1169
|
return 'displayName'
|
|
1130
1170
|
}
|
|
1131
1171
|
|
|
1132
1172
|
renderLegend() {
|
|
1133
|
-
for (const container of document.querySelectorAll(
|
|
1173
|
+
for (const container of document.querySelectorAll(
|
|
1174
|
+
`.${this.cssId} .datalayer-legend`
|
|
1175
|
+
)) {
|
|
1134
1176
|
container.innerHTML = ''
|
|
1135
1177
|
if (this.layer.renderLegend) return this.layer.renderLegend(container)
|
|
1136
1178
|
const color = DomUtil.create('span', 'datalayer-color', container)
|
|
@@ -1174,7 +1216,7 @@ export class DataLayer {
|
|
|
1174
1216
|
'click',
|
|
1175
1217
|
function () {
|
|
1176
1218
|
if (!this.isVisible()) return
|
|
1177
|
-
this.
|
|
1219
|
+
this._umap.dialog
|
|
1178
1220
|
.confirm(translate('Are you sure you want to delete this layer?'))
|
|
1179
1221
|
.then(() => {
|
|
1180
1222
|
this._delete()
|