umap-project 2.6.3__py3-none-any.whl → 2.7.0b0__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/admin.py +64 -1
- umap/context_processors.py +1 -0
- umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- umap/locale/cs_CZ/LC_MESSAGES/django.po +96 -92
- umap/locale/de/LC_MESSAGES/django.mo +0 -0
- umap/locale/de/LC_MESSAGES/django.po +19 -18
- umap/locale/en/LC_MESSAGES/django.po +47 -43
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +51 -47
- umap/locale/pt/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt/LC_MESSAGES/django.po +64 -60
- umap/management/commands/clean_tilelayer.py +152 -0
- umap/management/commands/purge_purgatory.py +28 -0
- umap/models.py +27 -2
- umap/settings/base.py +2 -0
- umap/static/umap/base.css +4 -4
- umap/static/umap/css/contextmenu.css +5 -0
- umap/static/umap/css/icon.css +7 -2
- umap/static/umap/img/16-white.svg +9 -2
- umap/static/umap/img/16.svg +3 -0
- umap/static/umap/img/source/16-white.svg +10 -3
- umap/static/umap/img/source/16.svg +4 -1
- umap/static/umap/js/modules/autocomplete.js +7 -3
- umap/static/umap/js/modules/browser.js +7 -1
- umap/static/umap/js/modules/caption.js +6 -1
- umap/static/umap/js/modules/data/features.js +176 -2
- umap/static/umap/js/modules/data/layer.js +31 -26
- umap/static/umap/js/modules/formatter.js +3 -2
- umap/static/umap/js/modules/global.js +2 -0
- umap/static/umap/js/modules/importers/communesfr.js +13 -1
- umap/static/umap/js/modules/permissions.js +123 -93
- umap/static/umap/js/modules/rendering/ui.js +37 -212
- umap/static/umap/js/modules/sync/engine.js +365 -14
- umap/static/umap/js/modules/sync/hlc.js +106 -0
- umap/static/umap/js/modules/sync/updaters.js +4 -4
- umap/static/umap/js/modules/sync/websocket.js +1 -1
- umap/static/umap/js/modules/ui/base.js +2 -2
- umap/static/umap/js/modules/ui/contextmenu.js +34 -17
- umap/static/umap/js/modules/urls.js +5 -1
- umap/static/umap/js/modules/utils.js +5 -1
- umap/static/umap/js/umap.controls.js +47 -47
- umap/static/umap/js/umap.core.js +3 -3
- umap/static/umap/js/umap.forms.js +3 -1
- umap/static/umap/js/umap.js +95 -112
- umap/static/umap/locale/br.js +13 -4
- umap/static/umap/locale/br.json +13 -4
- umap/static/umap/locale/ca.js +21 -12
- umap/static/umap/locale/ca.json +21 -12
- umap/static/umap/locale/cs_CZ.js +87 -78
- umap/static/umap/locale/cs_CZ.json +87 -78
- umap/static/umap/locale/de.js +17 -8
- umap/static/umap/locale/de.json +17 -8
- umap/static/umap/locale/en.js +9 -2
- umap/static/umap/locale/en.json +9 -2
- umap/static/umap/locale/eu.js +10 -3
- umap/static/umap/locale/eu.json +10 -3
- umap/static/umap/locale/fa_IR.js +11 -4
- umap/static/umap/locale/fa_IR.json +11 -4
- umap/static/umap/locale/fr.js +11 -4
- umap/static/umap/locale/fr.json +11 -4
- umap/static/umap/locale/hu.js +10 -3
- umap/static/umap/locale/hu.json +10 -3
- umap/static/umap/locale/pt.js +17 -8
- umap/static/umap/locale/pt.json +17 -8
- umap/static/umap/locale/pt_PT.js +13 -4
- umap/static/umap/locale/pt_PT.json +13 -4
- umap/static/umap/locale/zh_TW.js +13 -4
- umap/static/umap/locale/zh_TW.json +13 -4
- umap/static/umap/map.css +7 -22
- umap/static/umap/unittests/hlc.js +158 -0
- umap/static/umap/unittests/sync.js +321 -15
- umap/static/umap/unittests/utils.js +23 -0
- umap/static/umap/vendors/georsstogeojson/GeoRSSToGeoJSON.js +111 -80
- umap/templates/umap/dashboard_menu.html +4 -2
- umap/templates/umap/js.html +0 -4
- umap/tests/integration/test_anonymous_owned_map.py +1 -0
- umap/tests/integration/test_basics.py +1 -1
- umap/tests/integration/test_circles_layer.py +12 -0
- umap/tests/integration/test_datalayer.py +5 -0
- umap/tests/integration/test_draw_polygon.py +17 -9
- umap/tests/integration/test_draw_polyline.py +12 -8
- umap/tests/integration/test_edit_datalayer.py +4 -6
- umap/tests/integration/test_edit_map.py +1 -1
- umap/tests/integration/test_import.py +5 -0
- umap/tests/integration/test_map.py +5 -0
- umap/tests/integration/test_owned_map.py +1 -1
- umap/tests/integration/test_view_polygon.py +12 -12
- umap/tests/integration/test_websocket_sync.py +65 -3
- umap/tests/test_clean_tilelayer.py +83 -0
- umap/tests/test_datalayer.py +24 -0
- umap/tests/test_map_views.py +1 -0
- umap/tests/test_purge_purgatory.py +25 -0
- umap/tests/test_websocket_server.py +22 -0
- umap/urls.py +5 -1
- umap/views.py +6 -3
- umap/websocket_server.py +130 -27
- {umap_project-2.6.3.dist-info → umap_project-2.7.0b0.dist-info}/METADATA +9 -9
- {umap_project-2.6.3.dist-info → umap_project-2.7.0b0.dist-info}/RECORD +102 -97
- umap/static/umap/vendors/contextmenu/leaflet.contextmenu.min.css +0 -1
- umap/static/umap/vendors/contextmenu/leaflet.contextmenu.min.js +0 -7
- {umap_project-2.6.3.dist-info → umap_project-2.7.0b0.dist-info}/WHEEL +0 -0
- {umap_project-2.6.3.dist-info → umap_project-2.7.0b0.dist-info}/entry_points.txt +0 -0
- {umap_project-2.6.3.dist-info → umap_project-2.7.0b0.dist-info}/licenses/LICENSE +0 -0
|
@@ -578,11 +578,15 @@ const ControlsMixin = {
|
|
|
578
578
|
],
|
|
579
579
|
|
|
580
580
|
renderEditToolbar: function () {
|
|
581
|
-
const
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
581
|
+
const className = 'umap-main-edit-toolbox'
|
|
582
|
+
const container =
|
|
583
|
+
document.querySelector(`.${className}`) ||
|
|
584
|
+
L.DomUtil.create(
|
|
585
|
+
'div',
|
|
586
|
+
`${className} with-transition dark`,
|
|
587
|
+
this._controlContainer
|
|
588
|
+
)
|
|
589
|
+
container.innerHTML = ''
|
|
586
590
|
const leftContainer = L.DomUtil.create('div', 'umap-left-edit-toolbox', container)
|
|
587
591
|
const rightContainer = L.DomUtil.create('div', 'umap-right-edit-toolbox', container)
|
|
588
592
|
const logo = L.DomUtil.create('div', 'logo', leftContainer)
|
|
@@ -623,32 +627,44 @@ const ControlsMixin = {
|
|
|
623
627
|
},
|
|
624
628
|
this
|
|
625
629
|
)
|
|
626
|
-
const update = () => {
|
|
627
|
-
const status = this.permissions.getShareStatusDisplay()
|
|
628
|
-
nameButton.textContent = this.getDisplayName()
|
|
629
|
-
// status is not set until map is saved once
|
|
630
|
-
if (status) {
|
|
631
|
-
shareStatusButton.textContent = L._('Visibility: {status}', {
|
|
632
|
-
status: status,
|
|
633
|
-
})
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
update()
|
|
637
|
-
this.once('saved', L.bind(update, this))
|
|
638
630
|
if (this.options.editMode === 'advanced') {
|
|
639
631
|
L.DomEvent.on(nameButton, 'click', this.editCaption, this)
|
|
640
632
|
L.DomEvent.on(shareStatusButton, 'click', this.permissions.edit, this.permissions)
|
|
641
633
|
}
|
|
642
|
-
this.on('postsync', L.bind(update, this))
|
|
643
634
|
if (this.options.user?.id) {
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
)
|
|
635
|
+
const button = U.Utils.loadTemplate(`
|
|
636
|
+
<button class="umap-user flat" type="button">
|
|
637
|
+
<i class="icon icon-16 icon-profile"></i>
|
|
638
|
+
<span>${this.options.user.name}</span>
|
|
639
|
+
</button>
|
|
640
|
+
`)
|
|
641
|
+
rightContainer.appendChild(button)
|
|
642
|
+
const menu = new U.ContextMenu({ className: 'dark', fixed: true })
|
|
643
|
+
const actions = [
|
|
644
|
+
{
|
|
645
|
+
label: L._('New map'),
|
|
646
|
+
action: this.urls.get('map_new'),
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
label: L._('My maps'),
|
|
650
|
+
action: this.urls.get('user_dashboard'),
|
|
651
|
+
},
|
|
652
|
+
{
|
|
653
|
+
label: L._('My teams'),
|
|
654
|
+
action: this.urls.get('user_teams'),
|
|
655
|
+
},
|
|
656
|
+
]
|
|
657
|
+
if (this.urls.has('user_profile')) {
|
|
658
|
+
actions.push({
|
|
659
|
+
label: L._('My profile'),
|
|
660
|
+
action: this.urls.get('user_profile'),
|
|
661
|
+
})
|
|
662
|
+
}
|
|
663
|
+
button.addEventListener('click', () => {
|
|
664
|
+
const x = button.offsetLeft
|
|
665
|
+
const y = button.offsetTop + button.offsetHeight
|
|
666
|
+
menu.open([x, y], actions)
|
|
667
|
+
})
|
|
652
668
|
}
|
|
653
669
|
this.help.getStartedLink(rightContainer)
|
|
654
670
|
const controlEditCancel = L.DomUtil.createButton(
|
|
@@ -808,7 +824,8 @@ U.TileLayerControl = L.Control.IconLayers.extend({
|
|
|
808
824
|
)
|
|
809
825
|
const button = L.DomUtil.element({
|
|
810
826
|
tagName: 'button',
|
|
811
|
-
className:
|
|
827
|
+
className:
|
|
828
|
+
'leaflet-iconLayers-layerCell leaflet-iconLayers-layerCell-plus button',
|
|
812
829
|
textContent: '+',
|
|
813
830
|
parent: lastRow,
|
|
814
831
|
})
|
|
@@ -1140,23 +1157,6 @@ L.Control.Loading.include({
|
|
|
1140
1157
|
},
|
|
1141
1158
|
})
|
|
1142
1159
|
|
|
1143
|
-
/*
|
|
1144
|
-
* Make it dynamic
|
|
1145
|
-
*/
|
|
1146
|
-
U.ContextMenu = L.Map.ContextMenu.extend({
|
|
1147
|
-
_createItems: function (e) {
|
|
1148
|
-
this._map.setContextMenuItems(e)
|
|
1149
|
-
L.Map.ContextMenu.prototype._createItems.call(this)
|
|
1150
|
-
},
|
|
1151
|
-
|
|
1152
|
-
_showAtPoint: function (pt, e) {
|
|
1153
|
-
this._items = []
|
|
1154
|
-
this._container.innerHTML = ''
|
|
1155
|
-
this._createItems(e)
|
|
1156
|
-
L.Map.ContextMenu.prototype._showAtPoint.call(this, pt, e)
|
|
1157
|
-
},
|
|
1158
|
-
})
|
|
1159
|
-
|
|
1160
1160
|
U.Editable = L.Editable.extend({
|
|
1161
1161
|
initialize: function (map, options) {
|
|
1162
1162
|
L.Editable.prototype.initialize.call(this, map, options)
|
|
@@ -1181,9 +1181,9 @@ U.Editable = L.Editable.extend({
|
|
|
1181
1181
|
if (this.map.editedFeature !== event.layer) event.layer.feature.edit(event)
|
|
1182
1182
|
})
|
|
1183
1183
|
this.on('editable:editing', (event) => {
|
|
1184
|
-
const
|
|
1185
|
-
|
|
1186
|
-
|
|
1184
|
+
const feature = event.layer.feature
|
|
1185
|
+
feature.isDirty = true
|
|
1186
|
+
feature.pullGeometry(false)
|
|
1187
1187
|
})
|
|
1188
1188
|
this.on('editable:vertex:ctrlclick', (event) => {
|
|
1189
1189
|
const index = event.vertex.getIndex()
|
umap/static/umap/js/umap.core.js
CHANGED
|
@@ -141,10 +141,10 @@ L.DomUtil.createButtonIcon = (parent, className, title, callback, size = 16) =>
|
|
|
141
141
|
return el
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
L.DomUtil.createTitle = (parent, text, className, tag = 'h3') => {
|
|
144
|
+
L.DomUtil.createTitle = (parent, text, iconClassName, className = '', tag = 'h3') => {
|
|
145
145
|
const title = L.DomUtil.create(tag, '', parent)
|
|
146
|
-
if (className) L.DomUtil.createIcon(title,
|
|
147
|
-
L.DomUtil.add('span',
|
|
146
|
+
if (className) L.DomUtil.createIcon(title, iconClassName)
|
|
147
|
+
L.DomUtil.add('span', className, title, text)
|
|
148
148
|
return title
|
|
149
149
|
}
|
|
150
150
|
|
|
@@ -1029,6 +1029,7 @@ L.FormBuilder.ManageOwner = L.FormBuilder.Element.extend({
|
|
|
1029
1029
|
const options = {
|
|
1030
1030
|
className: 'edit-owner',
|
|
1031
1031
|
on_select: L.bind(this.onSelect, this),
|
|
1032
|
+
placeholder: L._("Type new owner's username"),
|
|
1032
1033
|
}
|
|
1033
1034
|
this.autocomplete = new U.AjaxAutocomplete(this.parentNode, options)
|
|
1034
1035
|
const owner = this.toHTML()
|
|
@@ -1058,6 +1059,7 @@ L.FormBuilder.ManageEditors = L.FormBuilder.Element.extend({
|
|
|
1058
1059
|
className: 'edit-editors',
|
|
1059
1060
|
on_select: L.bind(this.onSelect, this),
|
|
1060
1061
|
on_unselect: L.bind(this.onUnselect, this),
|
|
1062
|
+
placeholder: L._("Type editor's username"),
|
|
1061
1063
|
}
|
|
1062
1064
|
this.autocomplete = new U.AjaxAutocompleteMultiple(this.parentNode, options)
|
|
1063
1065
|
this._values = this.toHTML()
|
|
@@ -1131,7 +1133,7 @@ U.FormBuilder = L.FormBuilder.extend({
|
|
|
1131
1133
|
else schema.handler = 'IntInput'
|
|
1132
1134
|
} else if (schema.choices) {
|
|
1133
1135
|
const text_length = schema.choices.reduce(
|
|
1134
|
-
(acc, [
|
|
1136
|
+
(acc, [_, label]) => acc + label.length,
|
|
1135
1137
|
0
|
|
1136
1138
|
)
|
|
1137
1139
|
// Try to be smart and use MultiChoice only
|
umap/static/umap/js/umap.js
CHANGED
|
@@ -58,6 +58,7 @@ U.Map = L.Map.extend({
|
|
|
58
58
|
this.panel = new U.Panel(this)
|
|
59
59
|
this.dialog = new U.Dialog({ className: 'dark' })
|
|
60
60
|
this.tooltip = new U.Tooltip(this._controlContainer)
|
|
61
|
+
this.contextmenu = new U.ContextMenu()
|
|
61
62
|
if (this.hasEditMode()) {
|
|
62
63
|
this.editPanel = new U.EditPanel(this)
|
|
63
64
|
this.fullPanel = new U.FullPanel(this)
|
|
@@ -109,10 +110,9 @@ U.Map = L.Map.extend({
|
|
|
109
110
|
delete this.options.advancedFilterKey
|
|
110
111
|
}
|
|
111
112
|
|
|
112
|
-
// Global storage for retrieving datalayers and features
|
|
113
|
-
this.datalayers = {}
|
|
114
|
-
this.datalayers_index = []
|
|
115
|
-
this.dirty_datalayers = []
|
|
113
|
+
// Global storage for retrieving datalayers and features.
|
|
114
|
+
this.datalayers = {} // All datalayers, including deleted.
|
|
115
|
+
this.datalayers_index = [] // Datalayers actually on the map and ordered.
|
|
116
116
|
this.features_index = {}
|
|
117
117
|
|
|
118
118
|
// Needed for actions labels
|
|
@@ -197,8 +197,9 @@ U.Map = L.Map.extend({
|
|
|
197
197
|
|
|
198
198
|
window.onbeforeunload = () => (this.editEnabled && this.isDirty) || null
|
|
199
199
|
this.backup()
|
|
200
|
-
this.initContextMenu()
|
|
201
200
|
this.on('click', this.closeInplaceToolbar)
|
|
201
|
+
this.on('contextmenu', this.onContextMenu)
|
|
202
|
+
this.propagate()
|
|
202
203
|
},
|
|
203
204
|
|
|
204
205
|
initSyncEngine: async function () {
|
|
@@ -230,6 +231,7 @@ U.Map = L.Map.extend({
|
|
|
230
231
|
this.renderEditToolbar()
|
|
231
232
|
this.renderControls()
|
|
232
233
|
this.browser.redraw()
|
|
234
|
+
this.propagate()
|
|
233
235
|
break
|
|
234
236
|
case 'data':
|
|
235
237
|
this.redrawVisibleDataLayers()
|
|
@@ -486,7 +488,7 @@ U.Map = L.Map.extend({
|
|
|
486
488
|
loadDataLayers: async function () {
|
|
487
489
|
this.datalayersLoaded = true
|
|
488
490
|
this.fire('datalayersloaded')
|
|
489
|
-
for (const datalayer of
|
|
491
|
+
for (const datalayer of this.datalayers_index) {
|
|
490
492
|
if (datalayer.showAtLoad()) await datalayer.show()
|
|
491
493
|
}
|
|
492
494
|
this.dataloaded = true
|
|
@@ -724,6 +726,10 @@ U.Map = L.Map.extend({
|
|
|
724
726
|
}
|
|
725
727
|
},
|
|
726
728
|
|
|
729
|
+
hasLayers: function () {
|
|
730
|
+
return Boolean(this.datalayers_index.length)
|
|
731
|
+
},
|
|
732
|
+
|
|
727
733
|
fitDataBounds: function () {
|
|
728
734
|
const bounds = this.getLayersBounds()
|
|
729
735
|
if (!this.hasData() || !bounds.isValid()) return false
|
|
@@ -928,6 +934,7 @@ U.Map = L.Map.extend({
|
|
|
928
934
|
if (mustReindex) datalayer.reindex()
|
|
929
935
|
datalayer.redraw()
|
|
930
936
|
})
|
|
937
|
+
this.propagate()
|
|
931
938
|
this.fire('postsync')
|
|
932
939
|
this.isDirty = true
|
|
933
940
|
},
|
|
@@ -991,12 +998,12 @@ U.Map = L.Map.extend({
|
|
|
991
998
|
if (this.editTools) this.editTools.stopDrawing()
|
|
992
999
|
this.resetOptions()
|
|
993
1000
|
this.datalayers_index = [].concat(this._datalayers_index_bk)
|
|
994
|
-
|
|
1001
|
+
// Iter over all datalayers, including deleted if any.
|
|
1002
|
+
for (const datalayer of Object.values(this.datalayers)) {
|
|
995
1003
|
if (datalayer.isDeleted) datalayer.connectToMap()
|
|
996
|
-
datalayer.reset()
|
|
997
|
-
}
|
|
1004
|
+
if (datalayer.isDirty) datalayer.reset()
|
|
1005
|
+
}
|
|
998
1006
|
this.ensurePanesOrder()
|
|
999
|
-
this.dirty_datalayers = []
|
|
1000
1007
|
this.initTileLayers()
|
|
1001
1008
|
this.isDirty = false
|
|
1002
1009
|
this.onDataLayersChanged()
|
|
@@ -1006,25 +1013,6 @@ U.Map = L.Map.extend({
|
|
|
1006
1013
|
this._container.classList.toggle('umap-is-dirty', this.isDirty)
|
|
1007
1014
|
},
|
|
1008
1015
|
|
|
1009
|
-
addDirtyDatalayer: function (datalayer) {
|
|
1010
|
-
if (this.dirty_datalayers.indexOf(datalayer) === -1) {
|
|
1011
|
-
this.dirty_datalayers.push(datalayer)
|
|
1012
|
-
this.isDirty = true
|
|
1013
|
-
}
|
|
1014
|
-
},
|
|
1015
|
-
|
|
1016
|
-
removeDirtyDatalayer: function (datalayer) {
|
|
1017
|
-
if (this.dirty_datalayers.indexOf(datalayer) !== -1) {
|
|
1018
|
-
this.dirty_datalayers.splice(this.dirty_datalayers.indexOf(datalayer), 1)
|
|
1019
|
-
this.checkDirty()
|
|
1020
|
-
}
|
|
1021
|
-
},
|
|
1022
|
-
|
|
1023
|
-
continueSaving: function () {
|
|
1024
|
-
if (this.dirty_datalayers.length) this.dirty_datalayers[0].save()
|
|
1025
|
-
else this.fire('saved')
|
|
1026
|
-
},
|
|
1027
|
-
|
|
1028
1016
|
exportOptions: function () {
|
|
1029
1017
|
const properties = {}
|
|
1030
1018
|
for (const option of Object.keys(U.SCHEMA)) {
|
|
@@ -1054,19 +1042,17 @@ U.Map = L.Map.extend({
|
|
|
1054
1042
|
return
|
|
1055
1043
|
}
|
|
1056
1044
|
if (data.login_required) {
|
|
1057
|
-
window.onLogin = () => this.
|
|
1045
|
+
window.onLogin = () => this.save()
|
|
1058
1046
|
window.open(data.login_required)
|
|
1059
1047
|
return
|
|
1060
1048
|
}
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
this.renderEditToolbar()
|
|
1064
|
-
}
|
|
1049
|
+
this.options.user = data.user
|
|
1050
|
+
this.renderEditToolbar()
|
|
1065
1051
|
if (!this.options.umap_id) {
|
|
1066
1052
|
this.options.umap_id = data.id
|
|
1067
1053
|
this.permissions.setOptions(data.permissions)
|
|
1068
1054
|
this.permissions.commit()
|
|
1069
|
-
if (data
|
|
1055
|
+
if (data.permissions?.anonymous_edit_url) {
|
|
1070
1056
|
this.once('saved', () => {
|
|
1071
1057
|
U.AlertCreation.info(
|
|
1072
1058
|
L._('Your map has been created with an anonymous account!'),
|
|
@@ -1099,21 +1085,42 @@ U.Map = L.Map.extend({
|
|
|
1099
1085
|
} else {
|
|
1100
1086
|
window.location = data.url
|
|
1101
1087
|
}
|
|
1102
|
-
this.
|
|
1088
|
+
this.propagate()
|
|
1089
|
+
return true
|
|
1103
1090
|
},
|
|
1104
1091
|
|
|
1105
|
-
save: function () {
|
|
1092
|
+
save: async function () {
|
|
1106
1093
|
if (!this.isDirty) return
|
|
1107
1094
|
if (this._default_extent) this._setCenterAndZoom()
|
|
1108
1095
|
this.backup()
|
|
1109
|
-
this.once('saved', () => {
|
|
1110
|
-
this.isDirty = false
|
|
1111
|
-
})
|
|
1112
1096
|
if (this.options.editMode === 'advanced') {
|
|
1113
1097
|
// Only save the map if the user has the rights to do so.
|
|
1114
|
-
this.saveSelf()
|
|
1115
|
-
|
|
1116
|
-
|
|
1098
|
+
const ok = await this.saveSelf()
|
|
1099
|
+
if (!ok) return
|
|
1100
|
+
}
|
|
1101
|
+
await this.permissions.save()
|
|
1102
|
+
// Iter over all datalayers, including deleted.
|
|
1103
|
+
for (const datalayer of Object.values(this.datalayers)) {
|
|
1104
|
+
if (datalayer.isDirty) await datalayer.save()
|
|
1105
|
+
}
|
|
1106
|
+
this.isDirty = false
|
|
1107
|
+
this.renderEditToolbar()
|
|
1108
|
+
this.fire('saved')
|
|
1109
|
+
},
|
|
1110
|
+
|
|
1111
|
+
propagate: function () {
|
|
1112
|
+
let els = document.querySelectorAll('.map-name')
|
|
1113
|
+
for (const el of els) {
|
|
1114
|
+
el.textContent = this.getDisplayName()
|
|
1115
|
+
}
|
|
1116
|
+
const status = this.permissions.getShareStatusDisplay()
|
|
1117
|
+
els = document.querySelectorAll('.share-status')
|
|
1118
|
+
for (const el of els) {
|
|
1119
|
+
if (status) {
|
|
1120
|
+
el.textContent = L._('Visibility: {status}', {
|
|
1121
|
+
status: status,
|
|
1122
|
+
})
|
|
1123
|
+
}
|
|
1117
1124
|
}
|
|
1118
1125
|
},
|
|
1119
1126
|
|
|
@@ -1653,13 +1660,13 @@ U.Map = L.Map.extend({
|
|
|
1653
1660
|
},
|
|
1654
1661
|
|
|
1655
1662
|
clone: async function () {
|
|
1656
|
-
|
|
1657
|
-
confirm(L._('Are you sure you want to clone this map and all its datalayers?'))
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
+
this.dialog
|
|
1664
|
+
.confirm(L._('Are you sure you want to clone this map and all its datalayers?'))
|
|
1665
|
+
.then(async () => {
|
|
1666
|
+
const url = this.urls.get('map_clone', { map_id: this.options.umap_id })
|
|
1667
|
+
const [data, response, error] = await this.server.post(url)
|
|
1668
|
+
if (data.redirect) window.location = data.redirect
|
|
1669
|
+
})
|
|
1663
1670
|
},
|
|
1664
1671
|
|
|
1665
1672
|
removeDataLayers: function () {
|
|
@@ -1679,118 +1686,94 @@ U.Map = L.Map.extend({
|
|
|
1679
1686
|
this.loader.onAdd(this)
|
|
1680
1687
|
},
|
|
1681
1688
|
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
this.contextmenu.enable()
|
|
1685
|
-
},
|
|
1686
|
-
|
|
1687
|
-
setContextMenuItems: function (e) {
|
|
1688
|
-
let items = []
|
|
1689
|
-
if (this._zoom !== this.getMaxZoom()) {
|
|
1690
|
-
items.push({
|
|
1691
|
-
text: L._('Zoom in'),
|
|
1692
|
-
callback: function () {
|
|
1693
|
-
this.zoomIn()
|
|
1694
|
-
},
|
|
1695
|
-
})
|
|
1696
|
-
}
|
|
1697
|
-
if (this._zoom !== this.getMinZoom()) {
|
|
1698
|
-
items.push({
|
|
1699
|
-
text: L._('Zoom out'),
|
|
1700
|
-
callback: function () {
|
|
1701
|
-
this.zoomOut()
|
|
1702
|
-
},
|
|
1703
|
-
})
|
|
1704
|
-
}
|
|
1705
|
-
if (e?.relatedTarget) {
|
|
1706
|
-
if (e.relatedTarget.getContextMenuItems) {
|
|
1707
|
-
items = items.concat(e.relatedTarget.getContextMenuItems(e))
|
|
1708
|
-
}
|
|
1709
|
-
}
|
|
1689
|
+
getContextMenuItems: function (event) {
|
|
1690
|
+
const items = []
|
|
1710
1691
|
if (this.hasEditMode()) {
|
|
1711
|
-
items.push('-')
|
|
1712
1692
|
if (this.editEnabled) {
|
|
1713
1693
|
if (!this.isDirty) {
|
|
1714
1694
|
items.push({
|
|
1715
|
-
|
|
1716
|
-
|
|
1695
|
+
label: this.help.displayLabel('STOP_EDIT'),
|
|
1696
|
+
action: () => this.disableEdit(),
|
|
1717
1697
|
})
|
|
1718
1698
|
}
|
|
1719
1699
|
if (this.options.enableMarkerDraw) {
|
|
1720
1700
|
items.push({
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
context: this,
|
|
1701
|
+
label: this.help.displayLabel('DRAW_MARKER'),
|
|
1702
|
+
action: () => this.startMarker(event),
|
|
1724
1703
|
})
|
|
1725
1704
|
}
|
|
1726
1705
|
if (this.options.enablePolylineDraw) {
|
|
1727
1706
|
items.push({
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
context: this,
|
|
1707
|
+
label: this.help.displayLabel('DRAW_POLYGON'),
|
|
1708
|
+
action: () => this.startPolygon(event),
|
|
1731
1709
|
})
|
|
1732
1710
|
}
|
|
1733
1711
|
if (this.options.enablePolygonDraw) {
|
|
1734
1712
|
items.push({
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
context: this,
|
|
1713
|
+
label: this.help.displayLabel('DRAW_LINE'),
|
|
1714
|
+
action: () => this.startPolyline(event),
|
|
1738
1715
|
})
|
|
1739
1716
|
}
|
|
1740
1717
|
items.push('-')
|
|
1741
1718
|
items.push({
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
this.help.show('edit')
|
|
1745
|
-
},
|
|
1719
|
+
label: L._('Help'),
|
|
1720
|
+
action: () => this.help.show('edit'),
|
|
1746
1721
|
})
|
|
1747
1722
|
} else {
|
|
1748
1723
|
items.push({
|
|
1749
|
-
|
|
1750
|
-
|
|
1724
|
+
label: this.help.displayLabel('TOGGLE_EDIT'),
|
|
1725
|
+
action: () => this.enableEdit(),
|
|
1751
1726
|
})
|
|
1752
1727
|
}
|
|
1753
1728
|
}
|
|
1754
1729
|
items.push(
|
|
1755
1730
|
'-',
|
|
1756
1731
|
{
|
|
1757
|
-
|
|
1758
|
-
|
|
1732
|
+
label: L._('Open browser'),
|
|
1733
|
+
action: () => this.openBrowser('layers'),
|
|
1759
1734
|
},
|
|
1760
1735
|
{
|
|
1761
|
-
|
|
1762
|
-
|
|
1736
|
+
label: L._('Browse data'),
|
|
1737
|
+
action: () => this.openBrowser('data'),
|
|
1763
1738
|
}
|
|
1764
1739
|
)
|
|
1765
1740
|
if (this.options.facetKey) {
|
|
1766
1741
|
items.push({
|
|
1767
|
-
|
|
1768
|
-
|
|
1742
|
+
label: L._('Filter data'),
|
|
1743
|
+
action: () => this.openBrowser('filters'),
|
|
1769
1744
|
})
|
|
1770
1745
|
}
|
|
1771
1746
|
items.push(
|
|
1772
1747
|
{
|
|
1773
|
-
|
|
1774
|
-
|
|
1748
|
+
label: L._('Open caption'),
|
|
1749
|
+
action: () => this.openCaption(),
|
|
1775
1750
|
},
|
|
1776
1751
|
{
|
|
1777
|
-
|
|
1778
|
-
|
|
1752
|
+
label: this.help.displayLabel('SEARCH'),
|
|
1753
|
+
action: () => this.search(event),
|
|
1779
1754
|
}
|
|
1780
1755
|
)
|
|
1781
1756
|
if (this.options.urls.routing) {
|
|
1782
1757
|
items.push('-', {
|
|
1783
|
-
|
|
1784
|
-
|
|
1758
|
+
label: L._('Directions from here'),
|
|
1759
|
+
action: () => this.openExternalRouting(event),
|
|
1785
1760
|
})
|
|
1786
1761
|
}
|
|
1787
1762
|
if (this.options.urls.edit_in_osm) {
|
|
1788
1763
|
items.push('-', {
|
|
1789
|
-
|
|
1790
|
-
|
|
1764
|
+
label: L._('Edit in OpenStreetMap'),
|
|
1765
|
+
action: () => this.editInOSM(event),
|
|
1791
1766
|
})
|
|
1792
1767
|
}
|
|
1793
|
-
|
|
1768
|
+
return items
|
|
1769
|
+
},
|
|
1770
|
+
|
|
1771
|
+
onContextMenu: function (event) {
|
|
1772
|
+
const items = this.getContextMenuItems(event)
|
|
1773
|
+
this.contextmenu.open(
|
|
1774
|
+
[event.originalEvent.clientX, event.originalEvent.clientY],
|
|
1775
|
+
items
|
|
1776
|
+
)
|
|
1794
1777
|
},
|
|
1795
1778
|
|
|
1796
1779
|
editInOSM: function (e) {
|
|
@@ -1850,7 +1833,7 @@ U.Map = L.Map.extend({
|
|
|
1850
1833
|
|
|
1851
1834
|
getFeatureById: function (id) {
|
|
1852
1835
|
let feature
|
|
1853
|
-
for (const datalayer of
|
|
1836
|
+
for (const datalayer of this.datalayers_index) {
|
|
1854
1837
|
feature = datalayer.getFeatureById(id)
|
|
1855
1838
|
if (feature) return feature
|
|
1856
1839
|
}
|
umap/static/umap/locale/br.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const locale = {
|
|
2
|
-
"(area: {measure})": "(
|
|
3
|
-
"(length: {measure})": "(
|
|
2
|
+
"(area: {measure})": "(area: {measure})",
|
|
3
|
+
"(length: {measure})": "(length: {measure})",
|
|
4
4
|
"# one hash for main heading": "# un diezenn evit an titl pennañ",
|
|
5
5
|
"## two hashes for second heading": "## div ziezenn evit an eil titl",
|
|
6
6
|
"### three hashes for third heading": "### teir diezenn evit an trede titl",
|
|
@@ -477,7 +477,6 @@ const locale = {
|
|
|
477
477
|
"Search area": "Search area",
|
|
478
478
|
"Type area name, or let empty to load data in current map view": "Type area name, or let empty to load data in current map view",
|
|
479
479
|
"Data successfully imported!": "Roadennoù enporzhiet gant berzh!",
|
|
480
|
-
"My Dashboard ({username})": "Ma Zaolenn-vourzh ({username})",
|
|
481
480
|
"Clear data": "Skarzhañ ar roadennoù",
|
|
482
481
|
"Remove layers": "Lemel ar gwiskadoù",
|
|
483
482
|
"Categorized": "Dre rummad",
|
|
@@ -504,7 +503,17 @@ const locale = {
|
|
|
504
503
|
"Property name to compute circles": "Property name to compute circles",
|
|
505
504
|
"Min circle radius": "Min circle radius",
|
|
506
505
|
"Max circle radius": "Max circle radius",
|
|
507
|
-
"Display the open browser control": "Display the open browser control"
|
|
506
|
+
"Display the open browser control": "Display the open browser control",
|
|
507
|
+
"Copy as GeoJSON": "Copy as GeoJSON",
|
|
508
|
+
"Please zoom in to edit the geometry": "Please zoom in to edit the geometry",
|
|
509
|
+
"New map": "New map",
|
|
510
|
+
"My maps": "My maps",
|
|
511
|
+
"My teams": "My teams",
|
|
512
|
+
"My profile": "My profile",
|
|
513
|
+
"Type new owner's username": "Type new owner's username",
|
|
514
|
+
"Type editor's username": "Type editor's username",
|
|
515
|
+
"Map": "Map",
|
|
516
|
+
"Manage collaborators": "Manage collaborators"
|
|
508
517
|
}
|
|
509
518
|
L.registerLocale("br", locale)
|
|
510
519
|
L.setLocale("br")
|
umap/static/umap/locale/br.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"(area: {measure})": "(
|
|
3
|
-
"(length: {measure})": "(
|
|
2
|
+
"(area: {measure})": "(area: {measure})",
|
|
3
|
+
"(length: {measure})": "(length: {measure})",
|
|
4
4
|
"# one hash for main heading": "# un diezenn evit an titl pennañ",
|
|
5
5
|
"## two hashes for second heading": "## div ziezenn evit an eil titl",
|
|
6
6
|
"### three hashes for third heading": "### teir diezenn evit an trede titl",
|
|
@@ -477,7 +477,6 @@
|
|
|
477
477
|
"Search area": "Search area",
|
|
478
478
|
"Type area name, or let empty to load data in current map view": "Type area name, or let empty to load data in current map view",
|
|
479
479
|
"Data successfully imported!": "Roadennoù enporzhiet gant berzh!",
|
|
480
|
-
"My Dashboard ({username})": "Ma Zaolenn-vourzh ({username})",
|
|
481
480
|
"Clear data": "Skarzhañ ar roadennoù",
|
|
482
481
|
"Remove layers": "Lemel ar gwiskadoù",
|
|
483
482
|
"Categorized": "Dre rummad",
|
|
@@ -504,5 +503,15 @@
|
|
|
504
503
|
"Property name to compute circles": "Property name to compute circles",
|
|
505
504
|
"Min circle radius": "Min circle radius",
|
|
506
505
|
"Max circle radius": "Max circle radius",
|
|
507
|
-
"Display the open browser control": "Display the open browser control"
|
|
506
|
+
"Display the open browser control": "Display the open browser control",
|
|
507
|
+
"Copy as GeoJSON": "Copy as GeoJSON",
|
|
508
|
+
"Please zoom in to edit the geometry": "Please zoom in to edit the geometry",
|
|
509
|
+
"New map": "New map",
|
|
510
|
+
"My maps": "My maps",
|
|
511
|
+
"My teams": "My teams",
|
|
512
|
+
"My profile": "My profile",
|
|
513
|
+
"Type new owner's username": "Type new owner's username",
|
|
514
|
+
"Type editor's username": "Type editor's username",
|
|
515
|
+
"Map": "Map",
|
|
516
|
+
"Manage collaborators": "Manage collaborators"
|
|
508
517
|
}
|