umap-project 1.14.0a5__py3-none-any.whl → 2.0.0a0__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.
Potentially problematic release.
This version of umap-project might be problematic. Click here for more details.
- umap/__init__.py +1 -1
- umap/decorators.py +0 -14
- umap/locale/br/LC_MESSAGES/django.mo +0 -0
- umap/locale/br/LC_MESSAGES/django.po +137 -85
- umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- umap/locale/cs_CZ/LC_MESSAGES/django.po +136 -84
- umap/locale/el/LC_MESSAGES/django.mo +0 -0
- umap/locale/el/LC_MESSAGES/django.po +136 -84
- umap/locale/en/LC_MESSAGES/django.po +128 -88
- umap/locale/es/LC_MESSAGES/django.mo +0 -0
- umap/locale/es/LC_MESSAGES/django.po +136 -84
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +131 -91
- umap/locale/hu/LC_MESSAGES/django.mo +0 -0
- umap/locale/hu/LC_MESSAGES/django.po +137 -85
- umap/locale/it/LC_MESSAGES/django.mo +0 -0
- umap/locale/it/LC_MESSAGES/django.po +136 -84
- umap/locale/ms/LC_MESSAGES/django.mo +0 -0
- umap/locale/ms/LC_MESSAGES/django.po +136 -84
- umap/locale/pl/LC_MESSAGES/django.mo +0 -0
- umap/locale/pl/LC_MESSAGES/django.po +136 -84
- umap/locale/sv/LC_MESSAGES/django.mo +0 -0
- umap/locale/sv/LC_MESSAGES/django.po +135 -83
- umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
- umap/locale/zh_TW/LC_MESSAGES/django.po +143 -91
- umap/models.py +23 -1
- umap/settings/__init__.py +1 -4
- umap/settings/base.py +1 -0
- umap/static/umap/base.css +5 -0
- umap/static/umap/content.css +185 -13
- umap/static/umap/favicons/icon.svg +2 -2
- umap/static/umap/img/edit.svg +3 -3
- umap/static/umap/img/icon-delete.svg +4 -0
- umap/static/umap/img/icon-download.svg +13 -0
- umap/static/umap/img/icon-duplicate.svg +5 -0
- umap/static/umap/img/icon-edit.svg +12 -0
- umap/static/umap/img/icon-share.svg +11 -0
- umap/static/umap/img/icon-view.svg +12 -0
- umap/static/umap/img/logo.svg +2 -2
- umap/static/umap/img/logo_small.svg +2 -2
- umap/static/umap/img/marker.svg +4 -0
- umap/static/umap/img/opensource.svg +2 -2
- umap/static/umap/img/osm.svg +2 -2
- umap/static/umap/js/components/fragment.js +1 -1
- umap/static/umap/js/modules/browser.js +159 -0
- umap/static/umap/js/modules/global.js +3 -1
- umap/static/umap/js/modules/request.js +155 -0
- umap/static/umap/js/umap.autocomplete.js +28 -38
- umap/static/umap/js/umap.controls.js +73 -58
- umap/static/umap/js/umap.core.js +4 -9
- umap/static/umap/js/umap.datalayer.permissions.js +13 -12
- umap/static/umap/js/umap.features.js +51 -49
- umap/static/umap/js/umap.forms.js +19 -19
- umap/static/umap/js/umap.icon.js +17 -17
- umap/static/umap/js/umap.importer.js +2 -1
- umap/static/umap/js/umap.js +242 -291
- umap/static/umap/js/umap.layer.js +173 -141
- umap/static/umap/js/umap.permissions.js +24 -25
- umap/static/umap/js/umap.popup.js +14 -14
- umap/static/umap/js/umap.share.js +4 -4
- umap/static/umap/js/umap.slideshow.js +4 -4
- umap/static/umap/js/umap.tableeditor.js +2 -2
- umap/static/umap/js/umap.ui.js +1 -1
- umap/static/umap/locale/am_ET.js +1 -11
- umap/static/umap/locale/am_ET.json +1 -11
- umap/static/umap/locale/ar.js +1 -11
- umap/static/umap/locale/ar.json +1 -11
- umap/static/umap/locale/ast.js +1 -11
- umap/static/umap/locale/ast.json +1 -11
- umap/static/umap/locale/bg.js +1 -11
- umap/static/umap/locale/bg.json +1 -11
- umap/static/umap/locale/br.js +1 -11
- umap/static/umap/locale/br.json +1 -11
- umap/static/umap/locale/ca.js +1 -11
- umap/static/umap/locale/ca.json +1 -11
- umap/static/umap/locale/cs_CZ.js +1 -11
- umap/static/umap/locale/cs_CZ.json +1 -11
- umap/static/umap/locale/da.js +1 -11
- umap/static/umap/locale/da.json +1 -11
- umap/static/umap/locale/de.js +1 -11
- umap/static/umap/locale/de.json +1 -11
- umap/static/umap/locale/el.js +1 -11
- umap/static/umap/locale/el.json +1 -11
- umap/static/umap/locale/en.js +1 -11
- umap/static/umap/locale/en.json +1 -11
- umap/static/umap/locale/en_US.json +1 -11
- umap/static/umap/locale/es.js +1 -11
- umap/static/umap/locale/es.json +1 -11
- umap/static/umap/locale/et.js +1 -11
- umap/static/umap/locale/et.json +1 -11
- umap/static/umap/locale/fa_IR.js +6 -16
- umap/static/umap/locale/fa_IR.json +6 -16
- umap/static/umap/locale/fi.js +1 -11
- umap/static/umap/locale/fi.json +1 -11
- umap/static/umap/locale/fr.js +1 -11
- umap/static/umap/locale/fr.json +1 -11
- umap/static/umap/locale/gl.js +1 -11
- umap/static/umap/locale/gl.json +1 -11
- umap/static/umap/locale/he.js +1 -11
- umap/static/umap/locale/he.json +1 -11
- umap/static/umap/locale/hr.js +1 -11
- umap/static/umap/locale/hr.json +1 -11
- umap/static/umap/locale/hu.js +1 -11
- umap/static/umap/locale/hu.json +1 -11
- umap/static/umap/locale/id.js +1 -11
- umap/static/umap/locale/id.json +1 -11
- umap/static/umap/locale/is.js +1 -11
- umap/static/umap/locale/is.json +1 -11
- umap/static/umap/locale/it.js +1 -11
- umap/static/umap/locale/it.json +1 -11
- umap/static/umap/locale/ja.js +1 -11
- umap/static/umap/locale/ja.json +1 -11
- umap/static/umap/locale/ko.js +1 -11
- umap/static/umap/locale/ko.json +1 -11
- umap/static/umap/locale/lt.js +1 -11
- umap/static/umap/locale/lt.json +1 -11
- umap/static/umap/locale/ms.js +1 -11
- umap/static/umap/locale/ms.json +1 -11
- umap/static/umap/locale/nl.js +1 -11
- umap/static/umap/locale/nl.json +1 -11
- umap/static/umap/locale/no.js +1 -11
- umap/static/umap/locale/no.json +1 -11
- umap/static/umap/locale/pl.js +1 -11
- umap/static/umap/locale/pl.json +1 -11
- umap/static/umap/locale/pl_PL.json +1 -11
- umap/static/umap/locale/pt.js +1 -11
- umap/static/umap/locale/pt.json +1 -11
- umap/static/umap/locale/pt_BR.js +1 -11
- umap/static/umap/locale/pt_BR.json +1 -11
- umap/static/umap/locale/pt_PT.js +1 -11
- umap/static/umap/locale/pt_PT.json +1 -11
- umap/static/umap/locale/ro.js +1 -11
- umap/static/umap/locale/ro.json +1 -11
- umap/static/umap/locale/ru.js +1 -11
- umap/static/umap/locale/ru.json +1 -11
- umap/static/umap/locale/sk_SK.js +1 -11
- umap/static/umap/locale/sk_SK.json +1 -11
- umap/static/umap/locale/sl.js +1 -11
- umap/static/umap/locale/sl.json +1 -11
- umap/static/umap/locale/sr.js +1 -11
- umap/static/umap/locale/sr.json +1 -11
- umap/static/umap/locale/sv.js +1 -11
- umap/static/umap/locale/sv.json +1 -11
- umap/static/umap/locale/th_TH.js +1 -11
- umap/static/umap/locale/th_TH.json +1 -11
- umap/static/umap/locale/tr.js +1 -11
- umap/static/umap/locale/tr.json +1 -11
- umap/static/umap/locale/uk_UA.js +1 -11
- umap/static/umap/locale/uk_UA.json +1 -11
- umap/static/umap/locale/vi.js +1 -11
- umap/static/umap/locale/vi.json +1 -11
- umap/static/umap/locale/vi_VN.json +1 -11
- umap/static/umap/locale/zh.js +1 -11
- umap/static/umap/locale/zh.json +1 -11
- umap/static/umap/locale/zh_CN.json +1 -11
- umap/static/umap/locale/zh_TW.Big5.json +1 -11
- umap/static/umap/locale/zh_TW.js +17 -27
- umap/static/umap/locale/zh_TW.json +17 -27
- umap/static/umap/map.css +2 -2
- umap/static/umap/nav.css +2 -1
- umap/static/umap/test/.eslintrc +0 -1
- umap/static/umap/test/Choropleth.js +29 -27
- umap/static/umap/test/DataLayer.js +207 -239
- umap/static/umap/test/Feature.js +33 -58
- umap/static/umap/test/Map.Export.js +11 -11
- umap/static/umap/test/Map.js +66 -67
- umap/static/umap/test/Marker.js +36 -32
- umap/static/umap/test/Polygon.js +95 -95
- umap/static/umap/test/Polyline.js +31 -31
- umap/static/umap/test/TableEditor.js +29 -25
- umap/static/umap/test/_pre.js +2 -7
- umap/static/umap/test/index.html +4 -4
- umap/static/umap/vendors/contextmenu/leaflet.contextmenu.css +54 -0
- umap/static/umap/vendors/contextmenu/leaflet.contextmenu.js +586 -0
- umap/static/umap/vendors/csv2geojson/index.js +259 -0
- umap/static/umap/vendors/dompurify/purify.js +1633 -0
- umap/static/umap/vendors/locatecontrol/L.Control.Locate.css +63 -0
- umap/static/umap/vendors/locatecontrol/L.Control.Locate.js +950 -0
- umap/static/umap/vendors/minimap/Control.MiniMap.css +88 -0
- umap/static/umap/vendors/minimap/Control.MiniMap.js +352 -0
- umap/static/umap/vendors/togeojson/togeojson.js +2 -0
- umap/templates/auth/user_form.html +3 -2
- umap/templates/base.html +1 -0
- umap/templates/registration/login.html +51 -36
- umap/templates/umap/about_summary.html +1 -1
- umap/templates/umap/branding.html +3 -0
- umap/templates/umap/content.html +15 -39
- umap/templates/umap/header.html +0 -0
- umap/templates/umap/home.html +4 -2
- umap/templates/umap/js.html +0 -1
- umap/templates/umap/map_detail.html +9 -0
- umap/templates/umap/map_init.html +1 -1
- umap/templates/umap/map_messages.html +4 -2
- umap/templates/umap/map_table.html +130 -69
- umap/templates/umap/navigation.html +2 -4
- umap/templates/umap/user_dashboard.html +29 -6
- umap/tests/base.py +1 -1
- umap/tests/integration/conftest.py +18 -0
- umap/tests/integration/test_anonymous_owned_map.py +6 -3
- umap/tests/integration/test_browser.py +166 -6
- umap/tests/integration/test_collaborative_editing.py +23 -5
- umap/tests/integration/test_dashboard.py +17 -0
- umap/tests/integration/test_edit_datalayer.py +4 -3
- umap/tests/integration/test_export_map.py +1 -1
- umap/tests/integration/test_import.py +9 -4
- umap/tests/integration/test_map.py +64 -0
- umap/tests/integration/test_map_preview.py +75 -0
- umap/tests/integration/test_owned_map.py +11 -25
- umap/tests/integration/test_picto.py +3 -3
- umap/tests/integration/test_querystring.py +52 -0
- umap/tests/integration/test_share.py +22 -0
- umap/tests/test_map_views.py +157 -14
- umap/tests/test_views.py +50 -11
- umap/urls.py +6 -12
- umap/views.py +170 -47
- {umap_project-1.14.0a5.dist-info → umap_project-2.0.0a0.dist-info}/METADATA +13 -15
- {umap_project-1.14.0a5.dist-info → umap_project-2.0.0a0.dist-info}/RECORD +220 -199
- umap/static/umap/js/umap.browser.js +0 -148
- umap/static/umap/js/umap.xhr.js +0 -304
- umap/static/umap/test/Controls.js +0 -100
- umap/static/umap/test/Map.Init.js +0 -46
- {umap_project-1.14.0a5.dist-info → umap_project-2.0.0a0.dist-info}/WHEEL +0 -0
- {umap_project-1.14.0a5.dist-info → umap_project-2.0.0a0.dist-info}/entry_points.txt +0 -0
- {umap_project-1.14.0a5.dist-info → umap_project-2.0.0a0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
U.Layer = {
|
|
2
|
+
browsable: true,
|
|
3
3
|
|
|
4
4
|
getType: function () {
|
|
5
5
|
const proto = Object.getPrototypeOf(this)
|
|
@@ -26,12 +26,12 @@ L.U.Layer = {
|
|
|
26
26
|
},
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
U.Layer.Default = L.FeatureGroup.extend({
|
|
30
30
|
statics: {
|
|
31
31
|
NAME: L._('Default'),
|
|
32
32
|
TYPE: 'Default',
|
|
33
33
|
},
|
|
34
|
-
includes: [
|
|
34
|
+
includes: [U.Layer],
|
|
35
35
|
|
|
36
36
|
initialize: function (datalayer) {
|
|
37
37
|
this.datalayer = datalayer
|
|
@@ -39,7 +39,7 @@ L.U.Layer.Default = L.FeatureGroup.extend({
|
|
|
39
39
|
},
|
|
40
40
|
})
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
U.MarkerCluster = L.MarkerCluster.extend({
|
|
43
43
|
// Custom class so we can call computeTextColor
|
|
44
44
|
// when element is already on the DOM.
|
|
45
45
|
|
|
@@ -51,12 +51,12 @@ L.U.MarkerCluster = L.MarkerCluster.extend({
|
|
|
51
51
|
},
|
|
52
52
|
})
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
U.Layer.Cluster = L.MarkerClusterGroup.extend({
|
|
55
55
|
statics: {
|
|
56
56
|
NAME: L._('Clustered'),
|
|
57
57
|
TYPE: 'Cluster',
|
|
58
58
|
},
|
|
59
|
-
includes: [
|
|
59
|
+
includes: [U.Layer],
|
|
60
60
|
|
|
61
61
|
initialize: function (datalayer) {
|
|
62
62
|
this.datalayer = datalayer
|
|
@@ -65,14 +65,14 @@ L.U.Layer.Cluster = L.MarkerClusterGroup.extend({
|
|
|
65
65
|
color: this.datalayer.getColor(),
|
|
66
66
|
},
|
|
67
67
|
iconCreateFunction: function (cluster) {
|
|
68
|
-
return new
|
|
68
|
+
return new U.Icon.Cluster(datalayer, cluster)
|
|
69
69
|
},
|
|
70
70
|
}
|
|
71
71
|
if (this.datalayer.options.cluster && this.datalayer.options.cluster.radius) {
|
|
72
72
|
options.maxClusterRadius = this.datalayer.options.cluster.radius
|
|
73
73
|
}
|
|
74
74
|
L.MarkerClusterGroup.prototype.initialize.call(this, options)
|
|
75
|
-
this._markerCluster =
|
|
75
|
+
this._markerCluster = U.MarkerCluster
|
|
76
76
|
this._layers = []
|
|
77
77
|
},
|
|
78
78
|
|
|
@@ -132,13 +132,12 @@ L.U.Layer.Cluster = L.MarkerClusterGroup.extend({
|
|
|
132
132
|
},
|
|
133
133
|
})
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
U.Layer.Choropleth = L.FeatureGroup.extend({
|
|
136
136
|
statics: {
|
|
137
137
|
NAME: L._('Choropleth'),
|
|
138
138
|
TYPE: 'Choropleth',
|
|
139
139
|
},
|
|
140
|
-
includes: [
|
|
141
|
-
canBrowse: true,
|
|
140
|
+
includes: [U.Layer],
|
|
142
141
|
// Have defaults that better suit the choropleth mode.
|
|
143
142
|
defaults: {
|
|
144
143
|
color: 'white',
|
|
@@ -194,6 +193,7 @@ L.U.Layer.Choropleth = L.FeatureGroup.extend({
|
|
|
194
193
|
let mode = this.datalayer.options.choropleth.mode,
|
|
195
194
|
classes = +this.datalayer.options.choropleth.classes || 5,
|
|
196
195
|
breaks
|
|
196
|
+
classes = Math.min(classes, values.length)
|
|
197
197
|
if (mode === 'manual') {
|
|
198
198
|
const manualBreaks = this.datalayer.options.choropleth.breaks
|
|
199
199
|
if (manualBreaks) {
|
|
@@ -338,13 +338,13 @@ L.U.Layer.Choropleth = L.FeatureGroup.extend({
|
|
|
338
338
|
},
|
|
339
339
|
})
|
|
340
340
|
|
|
341
|
-
|
|
341
|
+
U.Layer.Heat = L.HeatLayer.extend({
|
|
342
342
|
statics: {
|
|
343
343
|
NAME: L._('Heatmap'),
|
|
344
344
|
TYPE: 'Heat',
|
|
345
345
|
},
|
|
346
|
-
includes: [
|
|
347
|
-
|
|
346
|
+
includes: [U.Layer],
|
|
347
|
+
browsable: false,
|
|
348
348
|
|
|
349
349
|
initialize: function (datalayer) {
|
|
350
350
|
this.datalayer = datalayer
|
|
@@ -505,7 +505,7 @@ L.U.Layer.Heat = L.HeatLayer.extend({
|
|
|
505
505
|
},
|
|
506
506
|
})
|
|
507
507
|
|
|
508
|
-
|
|
508
|
+
U.DataLayer = L.Evented.extend({
|
|
509
509
|
options: {
|
|
510
510
|
displayOnLoad: true,
|
|
511
511
|
inCaption: true,
|
|
@@ -579,9 +579,11 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
579
579
|
}
|
|
580
580
|
this.backupOptions()
|
|
581
581
|
this.connectToMap()
|
|
582
|
-
this.permissions = new
|
|
583
|
-
if (this.
|
|
584
|
-
|
|
582
|
+
this.permissions = new U.DataLayerPermissions(this)
|
|
583
|
+
if (!this.umap_id) {
|
|
584
|
+
if (this.showAtLoad()) this.show()
|
|
585
|
+
this.isDirty = true
|
|
586
|
+
}
|
|
585
587
|
|
|
586
588
|
this.onceLoaded(function () {
|
|
587
589
|
this.map.on('moveend', this.onMoveEnd, this)
|
|
@@ -646,7 +648,7 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
646
648
|
if (this.layer) this.layer.clearLayers()
|
|
647
649
|
// delete this.layer?
|
|
648
650
|
if (visible) this.map.removeLayer(this.layer)
|
|
649
|
-
const Class =
|
|
651
|
+
const Class = U.Layer[this.options.type] || U.Layer.Default
|
|
650
652
|
this.layer = new Class(this)
|
|
651
653
|
this.eachLayer(this.showFeature)
|
|
652
654
|
if (visible) this.show()
|
|
@@ -661,7 +663,7 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
661
663
|
},
|
|
662
664
|
|
|
663
665
|
eachFeature: function (method, context) {
|
|
664
|
-
if (this.
|
|
666
|
+
if (this.isBrowsable()) {
|
|
665
667
|
for (let i = 0; i < this._index.length; i++) {
|
|
666
668
|
method.call(context || this, this._layers[this._index[i]])
|
|
667
669
|
}
|
|
@@ -669,30 +671,28 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
669
671
|
return this
|
|
670
672
|
},
|
|
671
673
|
|
|
672
|
-
fetchData: function () {
|
|
674
|
+
fetchData: async function () {
|
|
673
675
|
if (!this.umap_id) return
|
|
674
676
|
if (this._loading) return
|
|
675
677
|
this._loading = true
|
|
676
|
-
this.map.get(this._dataUrl()
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
context: this,
|
|
695
|
-
})
|
|
678
|
+
const [geojson, response, error] = await this.map.server.get(this._dataUrl())
|
|
679
|
+
if (!error) {
|
|
680
|
+
this._last_modified = response.headers.get('last-modified')
|
|
681
|
+
// FIXME: for now this property is set dynamically from backend
|
|
682
|
+
// And thus it's not in the geojson file in the server
|
|
683
|
+
// So do not let all options to be reset
|
|
684
|
+
// Fix is a proper migration so all datalayers settings are
|
|
685
|
+
// in DB, and we remove it from geojson flat files.
|
|
686
|
+
if (geojson._umap_options) {
|
|
687
|
+
geojson._umap_options.editMode = this.options.editMode
|
|
688
|
+
}
|
|
689
|
+
// In case of maps pre 1.0 still around
|
|
690
|
+
if (geojson._storage) geojson._storage.editMode = this.options.editMode
|
|
691
|
+
this.fromUmapGeoJSON(geojson)
|
|
692
|
+
this.backupOptions()
|
|
693
|
+
this.fire('loaded')
|
|
694
|
+
this._loading = false
|
|
695
|
+
}
|
|
696
696
|
},
|
|
697
697
|
|
|
698
698
|
fromGeoJSON: function (geojson) {
|
|
@@ -743,23 +743,27 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
743
743
|
return !((!isNaN(from) && zoom < from) || (!isNaN(to) && zoom > to))
|
|
744
744
|
},
|
|
745
745
|
|
|
746
|
-
|
|
746
|
+
hasDynamicData: function () {
|
|
747
|
+
return !!(this.options.remoteData && this.options.remoteData.dynamic)
|
|
748
|
+
},
|
|
749
|
+
|
|
750
|
+
fetchRemoteData: async function (force) {
|
|
747
751
|
if (!this.isRemoteLayer()) return
|
|
748
|
-
if (!this.
|
|
752
|
+
if (!this.hasDynamicData() && this.hasDataLoaded() && !force) return
|
|
749
753
|
if (!this.isVisible()) return
|
|
750
754
|
let url = this.map.localizeUrl(this.options.remoteData.url)
|
|
751
|
-
if (this.options.remoteData.proxy)
|
|
755
|
+
if (this.options.remoteData.proxy) {
|
|
752
756
|
url = this.map.proxyUrl(url, this.options.remoteData.ttl)
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
)
|
|
761
|
-
|
|
762
|
-
}
|
|
757
|
+
}
|
|
758
|
+
const response = await this.map.request.get(url)
|
|
759
|
+
if (response && response.ok) {
|
|
760
|
+
this.clear()
|
|
761
|
+
this.rawToGeoJSON(
|
|
762
|
+
await response.text(),
|
|
763
|
+
this.options.remoteData.format,
|
|
764
|
+
(geojson) => this.fromGeoJSON(geojson)
|
|
765
|
+
)
|
|
766
|
+
}
|
|
763
767
|
},
|
|
764
768
|
|
|
765
769
|
onceLoaded: function (callback, context) {
|
|
@@ -796,7 +800,8 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
796
800
|
},
|
|
797
801
|
|
|
798
802
|
setOptions: function (options) {
|
|
799
|
-
|
|
803
|
+
delete options.geojson
|
|
804
|
+
this.options = L.Util.CopyJSON(U.DataLayer.prototype.options) // Start from fresh.
|
|
800
805
|
this.updateOptions(options)
|
|
801
806
|
},
|
|
802
807
|
|
|
@@ -924,7 +929,7 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
924
929
|
})
|
|
925
930
|
}
|
|
926
931
|
this.map.ui.alert({ content: message, level: 'error', duration: 10000 })
|
|
927
|
-
console.
|
|
932
|
+
console.error(err)
|
|
928
933
|
}
|
|
929
934
|
if (result && result.features.length) {
|
|
930
935
|
callback(result)
|
|
@@ -1022,11 +1027,11 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
1022
1027
|
},
|
|
1023
1028
|
|
|
1024
1029
|
_pointToLayer: function (geojson, latlng) {
|
|
1025
|
-
return new
|
|
1030
|
+
return new U.Marker(this.map, latlng, { geojson: geojson, datalayer: this })
|
|
1026
1031
|
},
|
|
1027
1032
|
|
|
1028
1033
|
_lineToLayer: function (geojson, latlngs) {
|
|
1029
|
-
return new
|
|
1034
|
+
return new U.Polyline(this.map, latlngs, {
|
|
1030
1035
|
geojson: geojson,
|
|
1031
1036
|
datalayer: this,
|
|
1032
1037
|
color: null,
|
|
@@ -1038,7 +1043,7 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
1038
1043
|
// for (let i = latlngs.length - 1; i > 0; i--) {
|
|
1039
1044
|
// if (!latlngs.slice()[i].length) latlngs.splice(i, 1);
|
|
1040
1045
|
// }
|
|
1041
|
-
return new
|
|
1046
|
+
return new U.Polygon(this.map, latlngs, { geojson: geojson, datalayer: this })
|
|
1042
1047
|
},
|
|
1043
1048
|
|
|
1044
1049
|
importRaw: function (raw, type) {
|
|
@@ -1060,13 +1065,12 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
1060
1065
|
reader.onload = (e) => this.importRaw(e.target.result, type)
|
|
1061
1066
|
},
|
|
1062
1067
|
|
|
1063
|
-
importFromUrl: function (
|
|
1064
|
-
|
|
1065
|
-
this.map.
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
})
|
|
1068
|
+
importFromUrl: async function (uri, type) {
|
|
1069
|
+
uri = this.map.localizeUrl(uri)
|
|
1070
|
+
const response = await this.map.request.get(uri)
|
|
1071
|
+
if (response && response.ok) {
|
|
1072
|
+
this.importRaw(await response.text(), type)
|
|
1073
|
+
}
|
|
1070
1074
|
},
|
|
1071
1075
|
|
|
1072
1076
|
getColor: function () {
|
|
@@ -1182,7 +1186,7 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
1182
1186
|
],
|
|
1183
1187
|
]
|
|
1184
1188
|
const title = L.DomUtil.add('h3', '', container, L._('Layer properties'))
|
|
1185
|
-
let builder = new
|
|
1189
|
+
let builder = new U.FormBuilder(this, metadataFields, {
|
|
1186
1190
|
callback: function (e) {
|
|
1187
1191
|
this.map.updateDatalayersControl()
|
|
1188
1192
|
if (e.helper.field === 'options.type') {
|
|
@@ -1204,7 +1208,7 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
1204
1208
|
const layerOptions = this.layer.getEditableOptions()
|
|
1205
1209
|
|
|
1206
1210
|
if (layerOptions.length) {
|
|
1207
|
-
builder = new
|
|
1211
|
+
builder = new U.FormBuilder(this, layerOptions, {
|
|
1208
1212
|
id: 'datalayer-layer-properties',
|
|
1209
1213
|
callback: redrawCallback,
|
|
1210
1214
|
})
|
|
@@ -1228,7 +1232,7 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
1228
1232
|
'options.fillOpacity',
|
|
1229
1233
|
]
|
|
1230
1234
|
|
|
1231
|
-
builder = new
|
|
1235
|
+
builder = new U.FormBuilder(this, shapeOptions, {
|
|
1232
1236
|
id: 'datalayer-advanced-properties',
|
|
1233
1237
|
callback: redrawCallback,
|
|
1234
1238
|
})
|
|
@@ -1244,7 +1248,7 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
1244
1248
|
'options.labelKey',
|
|
1245
1249
|
]
|
|
1246
1250
|
|
|
1247
|
-
builder = new
|
|
1251
|
+
builder = new U.FormBuilder(this, optionsFields, {
|
|
1248
1252
|
id: 'datalayer-advanced-properties',
|
|
1249
1253
|
callback: redrawCallback,
|
|
1250
1254
|
})
|
|
@@ -1264,7 +1268,7 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
1264
1268
|
'options.outlinkTarget',
|
|
1265
1269
|
'options.interactive',
|
|
1266
1270
|
]
|
|
1267
|
-
builder = new
|
|
1271
|
+
builder = new U.FormBuilder(this, popupFields, { callback: redrawCallback })
|
|
1268
1272
|
const popupFieldset = L.DomUtil.createFieldset(
|
|
1269
1273
|
container,
|
|
1270
1274
|
L._('Interaction options')
|
|
@@ -1310,7 +1314,7 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
1310
1314
|
}
|
|
1311
1315
|
|
|
1312
1316
|
const remoteDataContainer = L.DomUtil.createFieldset(container, L._('Remote data'))
|
|
1313
|
-
builder = new
|
|
1317
|
+
builder = new U.FormBuilder(this, remoteDataFields)
|
|
1314
1318
|
remoteDataContainer.appendChild(builder.build())
|
|
1315
1319
|
L.DomUtil.createButton(
|
|
1316
1320
|
'button umap-verify',
|
|
@@ -1383,8 +1387,8 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
1383
1387
|
}
|
|
1384
1388
|
},
|
|
1385
1389
|
|
|
1386
|
-
buildVersionsFieldset: function (container) {
|
|
1387
|
-
const appendVersion =
|
|
1390
|
+
buildVersionsFieldset: async function (container) {
|
|
1391
|
+
const appendVersion = (data) => {
|
|
1388
1392
|
const date = new Date(parseInt(data.at, 10))
|
|
1389
1393
|
const content = `${date.toLocaleString(L.lang)} (${parseInt(data.size) / 1000}Kb)`
|
|
1390
1394
|
const el = L.DomUtil.create('div', 'umap-datalayer-version', versionsContainer)
|
|
@@ -1400,34 +1404,30 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
1400
1404
|
}
|
|
1401
1405
|
|
|
1402
1406
|
const versionsContainer = L.DomUtil.createFieldset(container, L._('Versions'), {
|
|
1403
|
-
callback: function () {
|
|
1404
|
-
this.map.
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
}
|
|
1409
|
-
},
|
|
1410
|
-
context: this,
|
|
1411
|
-
})
|
|
1407
|
+
callback: async function () {
|
|
1408
|
+
const [{ versions }, response, error] = await this.map.server.get(
|
|
1409
|
+
this.getVersionsUrl()
|
|
1410
|
+
)
|
|
1411
|
+
if (!error) versions.forEach(appendVersion)
|
|
1412
1412
|
},
|
|
1413
1413
|
context: this,
|
|
1414
1414
|
})
|
|
1415
1415
|
},
|
|
1416
1416
|
|
|
1417
|
-
restore: function (version) {
|
|
1417
|
+
restore: async function (version) {
|
|
1418
1418
|
if (!this.map.editEnabled) return
|
|
1419
1419
|
if (!confirm(L._('Are you sure you want to restore this version?'))) return
|
|
1420
|
-
this.map.
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
}
|
|
1420
|
+
const [geojson, response, error] = await this.map.server.get(
|
|
1421
|
+
this.getVersionUrl(version)
|
|
1422
|
+
)
|
|
1423
|
+
if (!error) {
|
|
1424
|
+
if (geojson._storage) geojson._umap_options = geojson._storage // Retrocompat.
|
|
1425
|
+
if (geojson._umap_options) this.setOptions(geojson._umap_options)
|
|
1426
|
+
this.empty()
|
|
1427
|
+
if (this.isRemoteLayer()) this.fetchRemoteData()
|
|
1428
|
+
else this.addData(geojson)
|
|
1429
|
+
this.isDirty = true
|
|
1430
|
+
}
|
|
1431
1431
|
},
|
|
1432
1432
|
|
|
1433
1433
|
featuresToGeoJSON: function () {
|
|
@@ -1436,9 +1436,9 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
1436
1436
|
return features
|
|
1437
1437
|
},
|
|
1438
1438
|
|
|
1439
|
-
show: function () {
|
|
1440
|
-
if (!this.isLoaded()) this.fetchData()
|
|
1439
|
+
show: async function () {
|
|
1441
1440
|
this.map.addLayer(this.layer)
|
|
1441
|
+
if (!this.isLoaded()) await this.fetchData()
|
|
1442
1442
|
this.fire('show')
|
|
1443
1443
|
},
|
|
1444
1444
|
|
|
@@ -1461,8 +1461,22 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
1461
1461
|
if (bounds.isValid()) this.map.fitBounds(bounds)
|
|
1462
1462
|
},
|
|
1463
1463
|
|
|
1464
|
+
// Is this layer type browsable in theorie
|
|
1465
|
+
isBrowsable: function () {
|
|
1466
|
+
return this.layer && this.layer.browsable
|
|
1467
|
+
},
|
|
1468
|
+
|
|
1469
|
+
// Is this layer browsable in theorie
|
|
1470
|
+
// AND the user allows it
|
|
1464
1471
|
allowBrowse: function () {
|
|
1465
|
-
return !!this.options.browsable && this.
|
|
1472
|
+
return !!this.options.browsable && this.isBrowsable()
|
|
1473
|
+
},
|
|
1474
|
+
|
|
1475
|
+
// Is this layer browsable in theorie
|
|
1476
|
+
// AND the user allows it
|
|
1477
|
+
// AND it makes actually sense (is visible, it has data…)
|
|
1478
|
+
canBrowse: function () {
|
|
1479
|
+
return this.allowBrowse() && this.isVisible() && this.hasData()
|
|
1466
1480
|
},
|
|
1467
1481
|
|
|
1468
1482
|
count: function () {
|
|
@@ -1477,10 +1491,6 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
1477
1491
|
return this.layer && this.map.hasLayer(this.layer)
|
|
1478
1492
|
},
|
|
1479
1493
|
|
|
1480
|
-
canBrowse: function () {
|
|
1481
|
-
return this.layer && this.layer.canBrowse
|
|
1482
|
-
},
|
|
1483
|
-
|
|
1484
1494
|
getFeatureByIndex: function (index) {
|
|
1485
1495
|
if (index === -1) index = this._index.length - 1
|
|
1486
1496
|
const id = this._index[index]
|
|
@@ -1509,7 +1519,7 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
1509
1519
|
let next
|
|
1510
1520
|
const index = this.map.datalayers_index
|
|
1511
1521
|
while (((id = index[++id] ? id : 0), (next = index[id]))) {
|
|
1512
|
-
if (next === this ||
|
|
1522
|
+
if (next === this || next.canBrowse()) break
|
|
1513
1523
|
}
|
|
1514
1524
|
return next
|
|
1515
1525
|
},
|
|
@@ -1519,7 +1529,7 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
1519
1529
|
let prev
|
|
1520
1530
|
const index = this.map.datalayers_index
|
|
1521
1531
|
while (((id = index[--id] ? id : index.length - 1), (prev = index[id]))) {
|
|
1522
|
-
if (prev === this ||
|
|
1532
|
+
if (prev === this || prev.canBrowse()) break
|
|
1523
1533
|
}
|
|
1524
1534
|
return prev
|
|
1525
1535
|
},
|
|
@@ -1546,7 +1556,7 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
1546
1556
|
return this.isReadOnly() || this.isRemoteLayer()
|
|
1547
1557
|
},
|
|
1548
1558
|
|
|
1549
|
-
save: function () {
|
|
1559
|
+
save: async function () {
|
|
1550
1560
|
if (this.isDeleted) return this.saveDelete()
|
|
1551
1561
|
if (!this.isLoaded()) {
|
|
1552
1562
|
return
|
|
@@ -1564,44 +1574,66 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
1564
1574
|
map_id: this.map.options.umap_id,
|
|
1565
1575
|
pk: this.umap_id,
|
|
1566
1576
|
})
|
|
1567
|
-
this.
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
if (data.geojson) {
|
|
1573
|
-
this.clear()
|
|
1574
|
-
this.fromGeoJSON(data.geojson)
|
|
1575
|
-
delete data.geojson
|
|
1576
|
-
}
|
|
1577
|
-
this._geojson = geojson
|
|
1578
|
-
this._last_modified = response.getResponseHeader('Last-Modified')
|
|
1579
|
-
this.setUmapId(data.id)
|
|
1580
|
-
this.updateOptions(data)
|
|
1581
|
-
this.backupOptions()
|
|
1582
|
-
this.connectToMap()
|
|
1583
|
-
this._loaded = true
|
|
1584
|
-
this.redraw() // Needed for reordering features
|
|
1585
|
-
this.isDirty = false
|
|
1586
|
-
this.permissions.save()
|
|
1587
|
-
},
|
|
1588
|
-
context: this,
|
|
1589
|
-
headers: this._last_modified
|
|
1590
|
-
? { 'If-Unmodified-Since': this._last_modified }
|
|
1591
|
-
: {},
|
|
1592
|
-
})
|
|
1577
|
+
const headers = this._last_modified
|
|
1578
|
+
? { 'If-Unmodified-Since': this._last_modified }
|
|
1579
|
+
: {}
|
|
1580
|
+
await this._trySave(saveUrl, headers, formData)
|
|
1581
|
+
this._geojson = geojson
|
|
1593
1582
|
},
|
|
1594
1583
|
|
|
1595
|
-
|
|
1596
|
-
const
|
|
1584
|
+
_trySave: async function (url, headers, formData) {
|
|
1585
|
+
const [data, response, error] = await this.map.server.post(url, headers, formData)
|
|
1586
|
+
if (error) {
|
|
1587
|
+
if (response && response.status === 412) {
|
|
1588
|
+
const msg = L._(
|
|
1589
|
+
'Woops! Someone else seems to have edited the data. You can save anyway, but this will erase the changes made by others.'
|
|
1590
|
+
)
|
|
1591
|
+
const actions = [
|
|
1592
|
+
{
|
|
1593
|
+
label: L._('Save anyway'),
|
|
1594
|
+
callback: async () => {
|
|
1595
|
+
// Save again,
|
|
1596
|
+
// but do not pass If-Unmodified-Since this time
|
|
1597
|
+
await this._trySave(url, {}, formData)
|
|
1598
|
+
},
|
|
1599
|
+
},
|
|
1600
|
+
{
|
|
1601
|
+
label: L._('Cancel'),
|
|
1602
|
+
},
|
|
1603
|
+
]
|
|
1604
|
+
this.map.ui.alert({
|
|
1605
|
+
content: msg,
|
|
1606
|
+
level: 'error',
|
|
1607
|
+
duration: 100000,
|
|
1608
|
+
actions: actions,
|
|
1609
|
+
})
|
|
1610
|
+
}
|
|
1611
|
+
} else {
|
|
1612
|
+
// Response contains geojson only if save has conflicted and conflicts have
|
|
1613
|
+
// been resolved. So we need to reload to get extra data (added by someone else)
|
|
1614
|
+
if (data.geojson) {
|
|
1615
|
+
this.clear()
|
|
1616
|
+
this.fromGeoJSON(data.geojson)
|
|
1617
|
+
delete data.geojson
|
|
1618
|
+
}
|
|
1619
|
+
this._last_modified = response.headers.get('last-modified')
|
|
1620
|
+
this.setUmapId(data.id)
|
|
1621
|
+
this.updateOptions(data)
|
|
1622
|
+
this.backupOptions()
|
|
1623
|
+
this.connectToMap()
|
|
1624
|
+
this._loaded = true
|
|
1625
|
+
this.redraw() // Needed for reordering features
|
|
1597
1626
|
this.isDirty = false
|
|
1598
|
-
this.
|
|
1627
|
+
this.permissions.save()
|
|
1599
1628
|
}
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1629
|
+
},
|
|
1630
|
+
|
|
1631
|
+
saveDelete: async function () {
|
|
1632
|
+
if (this.umap_id) {
|
|
1633
|
+
await this.map.server.post(this.getDeleteUrl())
|
|
1634
|
+
}
|
|
1635
|
+
this.isDirty = false
|
|
1636
|
+
this.map.continueSaving()
|
|
1605
1637
|
},
|
|
1606
1638
|
|
|
1607
1639
|
getMap: function () {
|
|
@@ -1614,7 +1646,7 @@ L.U.DataLayer = L.Evented.extend({
|
|
|
1614
1646
|
|
|
1615
1647
|
tableEdit: function () {
|
|
1616
1648
|
if (this.isRemoteLayer() || !this.isVisible()) return
|
|
1617
|
-
const editor = new
|
|
1649
|
+
const editor = new U.TableEditor(this)
|
|
1618
1650
|
editor.edit()
|
|
1619
1651
|
},
|
|
1620
1652
|
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Dedicated object so we can deal with a separate dirty status, and thus
|
|
2
2
|
// call the endpoint only when needed, saving one call at each save.
|
|
3
|
-
|
|
3
|
+
U.MapPermissions = L.Class.extend({
|
|
4
4
|
options: {
|
|
5
5
|
owner: null,
|
|
6
6
|
editors: [],
|
|
@@ -105,7 +105,7 @@ L.U.MapPermissions = L.Class.extend({
|
|
|
105
105
|
])
|
|
106
106
|
}
|
|
107
107
|
title.textContent = L._('Update permissions')
|
|
108
|
-
const builder = new
|
|
108
|
+
const builder = new U.FormBuilder(this, fields)
|
|
109
109
|
const form = builder.build()
|
|
110
110
|
container.appendChild(form)
|
|
111
111
|
if (this.isAnonymousMap() && this.map.options.user) {
|
|
@@ -131,21 +131,19 @@ L.U.MapPermissions = L.Class.extend({
|
|
|
131
131
|
this.map.ui.openPanel({ data: { html: container }, className: 'dark' })
|
|
132
132
|
},
|
|
133
133
|
|
|
134
|
-
attach: function () {
|
|
135
|
-
this.map.post(this.getAttachUrl()
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
context: this,
|
|
145
|
-
})
|
|
134
|
+
attach: async function () {
|
|
135
|
+
const [data, response, error] = await this.map.server.post(this.getAttachUrl())
|
|
136
|
+
if (!error) {
|
|
137
|
+
this.options.owner = this.map.options.user
|
|
138
|
+
this.map.ui.alert({
|
|
139
|
+
content: L._('Map has been attached to your account'),
|
|
140
|
+
level: 'info',
|
|
141
|
+
})
|
|
142
|
+
this.map.ui.closePanel()
|
|
143
|
+
}
|
|
146
144
|
},
|
|
147
145
|
|
|
148
|
-
save: function () {
|
|
146
|
+
save: async function () {
|
|
149
147
|
if (!this.isDirty) return this.map.continueSaving()
|
|
150
148
|
const formData = new FormData()
|
|
151
149
|
if (!this.isAnonymousMap() && this.options.editors) {
|
|
@@ -159,16 +157,17 @@ L.U.MapPermissions = L.Class.extend({
|
|
|
159
157
|
formData.append('owner', this.options.owner && this.options.owner.id)
|
|
160
158
|
formData.append('share_status', this.options.share_status)
|
|
161
159
|
}
|
|
162
|
-
this.map.post(
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
160
|
+
const [data, response, error] = await this.map.server.post(
|
|
161
|
+
this.getUrl(),
|
|
162
|
+
{},
|
|
163
|
+
formData
|
|
164
|
+
)
|
|
165
|
+
if (!error) {
|
|
166
|
+
this.commit()
|
|
167
|
+
this.isDirty = false
|
|
168
|
+
this.map.continueSaving()
|
|
169
|
+
this.map.fire('postsync')
|
|
170
|
+
}
|
|
172
171
|
},
|
|
173
172
|
|
|
174
173
|
getUrl: function () {
|