umap-project 2.3.0__py3-none-any.whl → 2.4.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.
Potentially problematic release.
This version of umap-project might be problematic. Click here for more details.
- umap/__init__.py +1 -1
- umap/locale/en/LC_MESSAGES/django.po +81 -31
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +117 -66
- umap/locale/pl/LC_MESSAGES/django.mo +0 -0
- umap/locale/pl/LC_MESSAGES/django.po +83 -78
- umap/locale/pt/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt/LC_MESSAGES/django.po +129 -123
- umap/management/commands/run_websocket_server.py +23 -0
- umap/models.py +6 -1
- umap/settings/base.py +11 -3
- umap/static/umap/base.css +68 -186
- umap/static/umap/content.css +3 -2
- umap/static/umap/css/dialog.css +18 -0
- umap/static/umap/css/icon.css +8 -0
- umap/static/umap/css/importers.css +51 -0
- umap/static/umap/css/panel.css +18 -57
- umap/static/umap/css/tooltip.css +59 -0
- umap/static/umap/css/window.css +35 -0
- umap/static/umap/img/16-white.svg +1 -3
- umap/static/umap/img/alert-icon-error.svg +8 -0
- umap/static/umap/img/alert-icon-info.svg +4 -0
- umap/static/umap/img/alert-icon-success.svg +3 -0
- umap/static/umap/img/icon-external-link.svg +3 -0
- umap/static/umap/img/importers/communesfr.svg +5 -0
- umap/static/umap/img/importers/datasets.svg +13 -0
- umap/static/umap/img/importers/geodatamine.svg +10 -0
- umap/static/umap/img/importers/overpass.svg +7 -0
- umap/static/umap/img/importers/random.svg +18 -0
- umap/static/umap/img/importers/random1.svg +4 -0
- umap/static/umap/img/importers/random2.svg +4 -0
- umap/static/umap/img/source/16-white.svg +2 -4
- umap/static/umap/js/components/alerts/alert.css +160 -0
- umap/static/umap/js/components/alerts/alert.js +169 -0
- umap/static/umap/js/components/base.js +54 -0
- umap/static/umap/js/modules/autocomplete.js +347 -0
- umap/static/umap/js/modules/browser.js +14 -21
- umap/static/umap/js/modules/caption.js +119 -0
- umap/static/umap/js/modules/global.js +37 -11
- umap/static/umap/js/modules/help.js +255 -0
- umap/static/umap/js/modules/importer.js +308 -0
- umap/static/umap/js/modules/importers/communesfr.js +44 -0
- umap/static/umap/js/modules/importers/datasets.js +42 -0
- umap/static/umap/js/modules/importers/geodatamine.js +95 -0
- umap/static/umap/js/modules/importers/overpass.js +84 -0
- umap/static/umap/js/modules/request.js +12 -14
- umap/static/umap/js/modules/rules.js +241 -0
- umap/static/umap/js/modules/schema.js +63 -14
- umap/static/umap/js/modules/sync/engine.js +93 -0
- umap/static/umap/js/modules/sync/updaters.js +109 -0
- umap/static/umap/js/modules/sync/websocket.js +25 -0
- umap/static/umap/js/modules/ui/dialog.js +52 -0
- umap/static/umap/js/modules/{panel.js → ui/panel.js} +37 -20
- umap/static/umap/js/modules/ui/tooltip.js +116 -0
- umap/static/umap/js/modules/utils.js +25 -18
- umap/static/umap/js/umap.controls.js +37 -112
- umap/static/umap/js/umap.core.js +1 -327
- umap/static/umap/js/umap.features.js +77 -29
- umap/static/umap/js/umap.forms.js +17 -19
- umap/static/umap/js/umap.js +265 -228
- umap/static/umap/js/umap.layer.js +154 -76
- umap/static/umap/js/umap.permissions.js +5 -9
- umap/static/umap/js/umap.popup.js +2 -1
- umap/static/umap/js/umap.tableeditor.js +8 -8
- umap/static/umap/locale/am_ET.js +51 -16
- umap/static/umap/locale/am_ET.json +51 -16
- umap/static/umap/locale/ar.js +51 -16
- umap/static/umap/locale/ar.json +51 -16
- umap/static/umap/locale/ast.js +51 -16
- umap/static/umap/locale/ast.json +51 -16
- umap/static/umap/locale/bg.js +51 -16
- umap/static/umap/locale/bg.json +51 -16
- umap/static/umap/locale/br.js +55 -20
- umap/static/umap/locale/br.json +55 -20
- umap/static/umap/locale/ca.js +51 -16
- umap/static/umap/locale/ca.json +51 -16
- umap/static/umap/locale/cs_CZ.js +93 -58
- umap/static/umap/locale/cs_CZ.json +93 -58
- umap/static/umap/locale/da.js +51 -16
- umap/static/umap/locale/da.json +51 -16
- umap/static/umap/locale/de.js +56 -21
- umap/static/umap/locale/de.json +56 -21
- umap/static/umap/locale/el.js +51 -16
- umap/static/umap/locale/el.json +51 -16
- umap/static/umap/locale/en.js +52 -16
- umap/static/umap/locale/en.json +52 -16
- umap/static/umap/locale/en_US.json +51 -16
- umap/static/umap/locale/es.js +51 -16
- umap/static/umap/locale/es.json +51 -16
- umap/static/umap/locale/et.js +51 -16
- umap/static/umap/locale/et.json +51 -16
- umap/static/umap/locale/eu.js +51 -16
- umap/static/umap/locale/eu.json +51 -16
- umap/static/umap/locale/fa_IR.js +51 -16
- umap/static/umap/locale/fa_IR.json +51 -16
- umap/static/umap/locale/fi.js +51 -16
- umap/static/umap/locale/fi.json +51 -16
- umap/static/umap/locale/fr.js +61 -25
- umap/static/umap/locale/fr.json +61 -25
- umap/static/umap/locale/gl.js +51 -16
- umap/static/umap/locale/gl.json +51 -16
- umap/static/umap/locale/he.js +51 -16
- umap/static/umap/locale/he.json +51 -16
- umap/static/umap/locale/hr.js +51 -16
- umap/static/umap/locale/hr.json +51 -16
- umap/static/umap/locale/hu.js +51 -16
- umap/static/umap/locale/hu.json +51 -16
- umap/static/umap/locale/id.js +51 -16
- umap/static/umap/locale/id.json +51 -16
- umap/static/umap/locale/is.js +51 -16
- umap/static/umap/locale/is.json +51 -16
- umap/static/umap/locale/it.js +51 -16
- umap/static/umap/locale/it.json +51 -16
- umap/static/umap/locale/ja.js +51 -16
- umap/static/umap/locale/ja.json +51 -16
- umap/static/umap/locale/ko.js +51 -16
- umap/static/umap/locale/ko.json +51 -16
- umap/static/umap/locale/lt.js +51 -16
- umap/static/umap/locale/lt.json +51 -16
- umap/static/umap/locale/ms.js +51 -16
- umap/static/umap/locale/ms.json +51 -16
- umap/static/umap/locale/nl.js +51 -16
- umap/static/umap/locale/nl.json +51 -16
- umap/static/umap/locale/no.js +51 -16
- umap/static/umap/locale/no.json +51 -16
- umap/static/umap/locale/pl.js +93 -58
- umap/static/umap/locale/pl.json +93 -58
- umap/static/umap/locale/pl_PL.json +51 -16
- umap/static/umap/locale/pt.js +215 -180
- umap/static/umap/locale/pt.json +215 -180
- umap/static/umap/locale/pt_BR.js +51 -16
- umap/static/umap/locale/pt_BR.json +51 -16
- umap/static/umap/locale/pt_PT.js +51 -16
- umap/static/umap/locale/pt_PT.json +51 -16
- umap/static/umap/locale/ro.js +51 -16
- umap/static/umap/locale/ro.json +51 -16
- umap/static/umap/locale/ru.js +51 -16
- umap/static/umap/locale/ru.json +51 -16
- umap/static/umap/locale/si.js +51 -16
- umap/static/umap/locale/si.json +51 -16
- umap/static/umap/locale/sk_SK.js +51 -16
- umap/static/umap/locale/sk_SK.json +51 -16
- umap/static/umap/locale/sl.js +51 -16
- umap/static/umap/locale/sl.json +51 -16
- umap/static/umap/locale/sr.js +51 -16
- umap/static/umap/locale/sr.json +51 -16
- umap/static/umap/locale/sv.js +51 -16
- umap/static/umap/locale/sv.json +51 -16
- umap/static/umap/locale/th_TH.js +51 -16
- umap/static/umap/locale/th_TH.json +51 -16
- umap/static/umap/locale/tr.js +51 -16
- umap/static/umap/locale/tr.json +51 -16
- umap/static/umap/locale/uk_UA.js +51 -16
- umap/static/umap/locale/uk_UA.json +51 -16
- umap/static/umap/locale/vi.js +51 -16
- umap/static/umap/locale/vi.json +51 -16
- umap/static/umap/locale/vi_VN.json +51 -16
- umap/static/umap/locale/zh.js +51 -16
- umap/static/umap/locale/zh.json +51 -16
- umap/static/umap/locale/zh_CN.json +51 -16
- umap/static/umap/locale/zh_TW.Big5.json +51 -16
- umap/static/umap/locale/zh_TW.js +51 -16
- umap/static/umap/locale/zh_TW.json +51 -16
- umap/static/umap/map.css +40 -53
- umap/static/umap/unittests/sync.js +105 -0
- umap/static/umap/unittests/utils.js +78 -36
- umap/static/umap/vars.css +19 -1
- umap/static/umap/vendors/dompurify/purify.es.js +50 -15
- umap/static/umap/vendors/dompurify/purify.es.mjs.map +1 -1
- umap/static/umap/vendors/formbuilder/Leaflet.FormBuilder.js +2 -2
- umap/templates/umap/components/alerts/alert.html +89 -0
- umap/templates/umap/content.html +4 -3
- umap/templates/umap/css.html +4 -0
- umap/templates/umap/home.html +3 -0
- umap/templates/umap/js.html +0 -3
- umap/templates/umap/map_init.html +2 -8
- umap/templates/umap/messages.html +9 -11
- umap/templates/umap/search.html +3 -0
- umap/tests/base.py +3 -0
- umap/tests/integration/conftest.py +30 -0
- umap/tests/integration/test_anonymous_owned_map.py +8 -13
- umap/tests/integration/test_browser.py +81 -6
- umap/tests/integration/test_caption.py +27 -0
- umap/tests/integration/test_conditional_rules.py +201 -0
- umap/tests/integration/test_dashboard.py +1 -1
- umap/tests/integration/test_datalayer.py +2 -3
- umap/tests/integration/test_edit_datalayer.py +32 -3
- umap/tests/integration/test_edit_map.py +1 -1
- umap/tests/integration/test_facets_browser.py +7 -4
- umap/tests/integration/test_import.py +185 -49
- umap/tests/integration/test_map.py +31 -17
- umap/tests/integration/{test_collaborative_editing.py → test_optimistic_merge.py} +7 -7
- umap/tests/integration/test_owned_map.py +1 -1
- umap/tests/integration/test_picto.py +2 -2
- umap/tests/integration/test_statics.py +1 -1
- umap/tests/integration/test_view_marker.py +19 -2
- umap/tests/integration/test_websocket_sync.py +283 -0
- umap/tests/settings.py +5 -0
- umap/tests/test_datalayer_views.py +0 -1
- umap/tests/test_views.py +53 -0
- umap/urls.py +5 -0
- umap/views.py +40 -11
- umap/websocket_server.py +92 -0
- {umap_project-2.3.0.dist-info → umap_project-2.4.0.dist-info}/METADATA +13 -11
- {umap_project-2.3.0.dist-info → umap_project-2.4.0.dist-info}/RECORD +208 -172
- umap/static/umap/js/umap.autocomplete.js +0 -341
- umap/static/umap/js/umap.importer.js +0 -187
- umap/static/umap/js/umap.ui.js +0 -190
- {umap_project-2.3.0.dist-info → umap_project-2.4.0.dist-info}/WHEEL +0 -0
- {umap_project-2.3.0.dist-info → umap_project-2.4.0.dist-info}/entry_points.txt +0 -0
- {umap_project-2.3.0.dist-info → umap_project-2.4.0.dist-info}/licenses/LICENSE +0 -0
umap/static/umap/js/umap.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
L.Map.mergeOptions({
|
|
2
|
-
overlay:
|
|
2
|
+
overlay: {},
|
|
3
3
|
datalayers: [],
|
|
4
4
|
hash: true,
|
|
5
5
|
maxZoomLimit: 24,
|
|
@@ -20,9 +20,6 @@ L.Map.mergeOptions({
|
|
|
20
20
|
enablePolygonDraw: true,
|
|
21
21
|
enablePolylineDraw: true,
|
|
22
22
|
limitBounds: {},
|
|
23
|
-
importPresets: [
|
|
24
|
-
// {url: 'http://localhost:8019/en/datalayer/1502/', label: 'Simplified World Countries', format: 'geojson'}
|
|
25
|
-
],
|
|
26
23
|
slideshow: {},
|
|
27
24
|
clickable: true,
|
|
28
25
|
permissions: {},
|
|
@@ -33,6 +30,8 @@ U.Map = L.Map.extend({
|
|
|
33
30
|
includes: [ControlsMixin],
|
|
34
31
|
|
|
35
32
|
initialize: function (el, geojson) {
|
|
33
|
+
this.sync_engine = new U.SyncEngine(this)
|
|
34
|
+
this.sync = this.sync_engine.proxy(this)
|
|
36
35
|
// Locale name (pt_PT, en_US…)
|
|
37
36
|
// To be used for Django localization
|
|
38
37
|
if (geojson.properties.locale) L.setLocale(geojson.properties.locale)
|
|
@@ -57,15 +56,16 @@ U.Map = L.Map.extend({
|
|
|
57
56
|
this.urls = new U.URLs(this.options.urls)
|
|
58
57
|
|
|
59
58
|
this.panel = new U.Panel(this)
|
|
59
|
+
this.tooltip = new U.Tooltip(this._controlContainer)
|
|
60
|
+
this.dialog = new U.Dialog(this._controlContainer)
|
|
60
61
|
if (this.hasEditMode()) {
|
|
61
62
|
this.editPanel = new U.EditPanel(this)
|
|
62
63
|
this.fullPanel = new U.FullPanel(this)
|
|
63
64
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
this.
|
|
67
|
-
this.
|
|
68
|
-
this.request = new U.Request(this.ui)
|
|
65
|
+
L.DomEvent.on(document.body, 'dataloading', (e) => this.fire('dataloading', e))
|
|
66
|
+
L.DomEvent.on(document.body, 'dataload', (e) => this.fire('dataload', e))
|
|
67
|
+
this.server = new U.ServerRequest()
|
|
68
|
+
this.request = new U.Request()
|
|
69
69
|
|
|
70
70
|
this.initLoader()
|
|
71
71
|
this.name = this.options.name
|
|
@@ -205,40 +205,9 @@ U.Map = L.Map.extend({
|
|
|
205
205
|
this.editTools = new U.Editable(this)
|
|
206
206
|
this.renderEditToolbar()
|
|
207
207
|
}
|
|
208
|
+
|
|
208
209
|
this.initShortcuts()
|
|
209
|
-
this.onceDataLoaded(
|
|
210
|
-
const slug = L.Util.queryString('feature')
|
|
211
|
-
if (slug && this.features_index[slug]) this.features_index[slug].view()
|
|
212
|
-
if (this.options.noControl) return
|
|
213
|
-
this.initCaptionBar()
|
|
214
|
-
if (L.Util.queryString('share')) {
|
|
215
|
-
this.share.open()
|
|
216
|
-
} else if (this.options.onLoadPanel === 'databrowser') {
|
|
217
|
-
this.openBrowser('data')
|
|
218
|
-
} else if (this.options.onLoadPanel === 'datalayers') {
|
|
219
|
-
this.openBrowser('layers')
|
|
220
|
-
} else if (this.options.onLoadPanel === 'datafilters') {
|
|
221
|
-
this.panel.mode = 'expanded'
|
|
222
|
-
this.openBrowser('filters')
|
|
223
|
-
} else if (this.options.onLoadPanel === 'caption') {
|
|
224
|
-
this.panel.mode = 'condensed'
|
|
225
|
-
this.displayCaption()
|
|
226
|
-
}
|
|
227
|
-
if (L.Util.queryString('edit')) {
|
|
228
|
-
if (this.hasEditMode()) this.enableEdit()
|
|
229
|
-
// Sometimes users share the ?edit link by mistake, let's remove
|
|
230
|
-
// this search parameter from URL to prevent this
|
|
231
|
-
const url = new URL(window.location)
|
|
232
|
-
url.searchParams.delete('edit')
|
|
233
|
-
history.pushState({}, '', url)
|
|
234
|
-
}
|
|
235
|
-
if (L.Util.queryString('download')) {
|
|
236
|
-
const download_url = this.urls.get('map_download', {
|
|
237
|
-
map_id: this.options.umap_id,
|
|
238
|
-
})
|
|
239
|
-
window.location = download_url
|
|
240
|
-
}
|
|
241
|
-
})
|
|
210
|
+
this.onceDataLoaded(this.setViewFromQueryString)
|
|
242
211
|
|
|
243
212
|
window.onbeforeunload = () => (this.editEnabled && this.isDirty) || null
|
|
244
213
|
this.backup()
|
|
@@ -246,6 +215,25 @@ U.Map = L.Map.extend({
|
|
|
246
215
|
this.on('click contextmenu.show', this.closeInplaceToolbar)
|
|
247
216
|
},
|
|
248
217
|
|
|
218
|
+
initSyncEngine: async function () {
|
|
219
|
+
if (this.options.websocketEnabled == false) return
|
|
220
|
+
if (this.options.syncEnabled != true) {
|
|
221
|
+
this.sync.stop()
|
|
222
|
+
} else {
|
|
223
|
+
const ws_token_uri = this.urls.get('map_websocket_auth_token', {
|
|
224
|
+
map_id: this.options.umap_id,
|
|
225
|
+
})
|
|
226
|
+
await this.sync.authenticate(ws_token_uri, this.options.websocketURI, this.server)
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
|
|
230
|
+
getSyncMetadata: function () {
|
|
231
|
+
return {
|
|
232
|
+
engine: this.sync,
|
|
233
|
+
subject: 'map',
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
|
|
249
237
|
render: function (fields) {
|
|
250
238
|
let impacts = U.Utils.getImpactsFromSchema(fields)
|
|
251
239
|
|
|
@@ -269,6 +257,8 @@ U.Map = L.Map.extend({
|
|
|
269
257
|
case 'bounds':
|
|
270
258
|
this.handleLimitBounds()
|
|
271
259
|
break
|
|
260
|
+
case 'sync':
|
|
261
|
+
this.initSyncEngine()
|
|
272
262
|
}
|
|
273
263
|
}
|
|
274
264
|
},
|
|
@@ -311,6 +301,44 @@ U.Map = L.Map.extend({
|
|
|
311
301
|
}
|
|
312
302
|
},
|
|
313
303
|
|
|
304
|
+
setViewFromQueryString: function () {
|
|
305
|
+
if (this.options.noControl) return
|
|
306
|
+
this.initCaptionBar()
|
|
307
|
+
if (L.Util.queryString('share')) {
|
|
308
|
+
this.share.open()
|
|
309
|
+
} else if (this.options.onLoadPanel === 'databrowser') {
|
|
310
|
+
this.panel.setDefaultMode('expanded')
|
|
311
|
+
this.openBrowser('data')
|
|
312
|
+
} else if (this.options.onLoadPanel === 'datalayers') {
|
|
313
|
+
this.panel.setDefaultMode('condensed')
|
|
314
|
+
this.openBrowser('layers')
|
|
315
|
+
} else if (this.options.onLoadPanel === 'datafilters') {
|
|
316
|
+
this.panel.setDefaultMode('expanded')
|
|
317
|
+
this.openBrowser('filters')
|
|
318
|
+
} else if (this.options.onLoadPanel === 'caption') {
|
|
319
|
+
this.panel.setDefaultMode('condensed')
|
|
320
|
+
this.openCaption()
|
|
321
|
+
}
|
|
322
|
+
// Comes after default panels, so if it opens in a panel it will
|
|
323
|
+
// take precedence.
|
|
324
|
+
const slug = L.Util.queryString('feature')
|
|
325
|
+
if (slug && this.features_index[slug]) this.features_index[slug].view()
|
|
326
|
+
if (L.Util.queryString('edit')) {
|
|
327
|
+
if (this.hasEditMode()) this.enableEdit()
|
|
328
|
+
// Sometimes users share the ?edit link by mistake, let's remove
|
|
329
|
+
// this search parameter from URL to prevent this
|
|
330
|
+
const url = new URL(window.location)
|
|
331
|
+
url.searchParams.delete('edit')
|
|
332
|
+
history.pushState({}, '', url)
|
|
333
|
+
}
|
|
334
|
+
if (L.Util.queryString('download')) {
|
|
335
|
+
const download_url = this.urls.get('map_download', {
|
|
336
|
+
map_id: this.options.umap_id,
|
|
337
|
+
})
|
|
338
|
+
window.location = download_url
|
|
339
|
+
}
|
|
340
|
+
},
|
|
341
|
+
|
|
314
342
|
// Merge the given schema with the default one
|
|
315
343
|
// Missing keys inside the schema are merged with the default ones.
|
|
316
344
|
overrideSchema: function (schema) {
|
|
@@ -357,7 +385,7 @@ U.Map = L.Map.extend({
|
|
|
357
385
|
icon: 'umap-fake-class',
|
|
358
386
|
iconLoading: 'umap-fake-class',
|
|
359
387
|
flyTo: this.options.easing,
|
|
360
|
-
onLocationError: (err) =>
|
|
388
|
+
onLocationError: (err) => U.Alert.error(err.message),
|
|
361
389
|
})
|
|
362
390
|
this._controls.fullscreen = new L.Control.Fullscreen({
|
|
363
391
|
title: { false: L._('View Fullscreen'), true: L._('Exit Fullscreen') },
|
|
@@ -382,24 +410,21 @@ U.Map = L.Map.extend({
|
|
|
382
410
|
else this.scrollWheelZoom.disable()
|
|
383
411
|
this.browser = new U.Browser(this)
|
|
384
412
|
this.facets = new U.Facets(this)
|
|
413
|
+
this.caption = new U.Caption(this)
|
|
385
414
|
this.importer = new U.Importer(this)
|
|
386
415
|
this.drop = new U.DropControl(this)
|
|
387
416
|
this.share = new U.Share(this)
|
|
417
|
+
this.rules = new U.Rules(this)
|
|
388
418
|
this._controls.tilelayers = new U.TileLayerControl(this)
|
|
389
419
|
},
|
|
390
420
|
|
|
391
421
|
renderControls: function () {
|
|
392
|
-
|
|
393
|
-
document.body,
|
|
394
|
-
'umap-caption-bar-enabled',
|
|
395
|
-
this.options.captionBar ||
|
|
396
|
-
(this.options.slideshow && this.options.slideshow.active)
|
|
397
|
-
)
|
|
398
|
-
L.DomUtil.classIf(
|
|
399
|
-
document.body,
|
|
400
|
-
'umap-slideshow-enabled',
|
|
422
|
+
const hasSlideshow = Boolean(
|
|
401
423
|
this.options.slideshow && this.options.slideshow.active
|
|
402
424
|
)
|
|
425
|
+
const barEnabled = this.options.captionBar || hasSlideshow
|
|
426
|
+
document.body.classList.toggle('umap-caption-bar-enabled', barEnabled)
|
|
427
|
+
document.body.classList.toggle('umap-slideshow-enabled', hasSlideshow)
|
|
403
428
|
for (const control of Object.values(this._controls)) {
|
|
404
429
|
this.removeControl(control)
|
|
405
430
|
}
|
|
@@ -474,6 +499,7 @@ U.Map = L.Map.extend({
|
|
|
474
499
|
|
|
475
500
|
onDataLayersChanged: function () {
|
|
476
501
|
if (this.browser) this.browser.update()
|
|
502
|
+
this.caption.refresh()
|
|
477
503
|
},
|
|
478
504
|
|
|
479
505
|
ensurePanesOrder: function () {
|
|
@@ -517,73 +543,80 @@ U.Map = L.Map.extend({
|
|
|
517
543
|
|
|
518
544
|
initShortcuts: function () {
|
|
519
545
|
const globalShortcuts = function (e) {
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
} else {
|
|
531
|
-
this.panel.close()
|
|
546
|
+
if (e.key === 'Escape') {
|
|
547
|
+
if (this.dialog.visible) {
|
|
548
|
+
this.dialog.close()
|
|
549
|
+
} else if (this.importer.dialog.visible) {
|
|
550
|
+
this.importer.dialog.close()
|
|
551
|
+
} else if (this.editEnabled && this.editTools.drawing()) {
|
|
552
|
+
this.editTools.stopDrawing()
|
|
553
|
+
} else if (this.measureTools.enabled()) {
|
|
554
|
+
this.measureTools.stopDrawing()
|
|
555
|
+
} else if (this.editPanel?.isOpen()) {
|
|
532
556
|
this.editPanel?.close()
|
|
557
|
+
} else if (this.fullPanel?.isOpen()) {
|
|
533
558
|
this.fullPanel?.close()
|
|
559
|
+
} else if (this.panel.isOpen()) {
|
|
560
|
+
this.panel.close()
|
|
534
561
|
}
|
|
535
562
|
}
|
|
536
563
|
|
|
537
|
-
|
|
564
|
+
// From now on, only ctrl/meta shortcut
|
|
565
|
+
if (!(e.ctrlKey || e.metaKey) || e.shiftKey) return
|
|
538
566
|
|
|
539
|
-
|
|
540
|
-
if (key === U.Keys.E && modifierKey && !this.editEnabled) {
|
|
541
|
-
L.DomEvent.stop(e)
|
|
542
|
-
this.enableEdit()
|
|
543
|
-
} else if (key === U.Keys.E && modifierKey && this.editEnabled && !this.isDirty) {
|
|
567
|
+
if (e.key === 'f') {
|
|
544
568
|
L.DomEvent.stop(e)
|
|
545
|
-
this.
|
|
569
|
+
this.search()
|
|
546
570
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
571
|
+
|
|
572
|
+
/* Edit mode only shortcuts */
|
|
573
|
+
if (!this.hasEditMode()) return
|
|
574
|
+
|
|
575
|
+
// Edit mode Off
|
|
576
|
+
if (!this.editEnabled) {
|
|
577
|
+
switch (e.key) {
|
|
578
|
+
case 'e':
|
|
579
|
+
L.DomEvent.stop(e)
|
|
580
|
+
this.enableEdit()
|
|
581
|
+
break
|
|
551
582
|
}
|
|
583
|
+
return
|
|
552
584
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
585
|
+
|
|
586
|
+
// Edit mode on
|
|
587
|
+
let used = true
|
|
588
|
+
switch (e.key) {
|
|
589
|
+
case 'e':
|
|
590
|
+
if (!this.isDirty) this.disableEdit()
|
|
591
|
+
break
|
|
592
|
+
case 's':
|
|
593
|
+
if (this.isDirty) this.save()
|
|
594
|
+
break
|
|
595
|
+
case 'z':
|
|
596
|
+
if (this.isDirty) this.askForReset()
|
|
597
|
+
break
|
|
598
|
+
case 'm':
|
|
599
|
+
this.editTools.startMarker()
|
|
600
|
+
break
|
|
601
|
+
case 'p':
|
|
602
|
+
this.editTools.startPolygon()
|
|
603
|
+
break
|
|
604
|
+
case 'l':
|
|
605
|
+
this.editTools.startPolyline()
|
|
606
|
+
break
|
|
607
|
+
case 'i':
|
|
608
|
+
this.importer.open()
|
|
609
|
+
break
|
|
610
|
+
case 'o':
|
|
611
|
+
this.importer.openFiles()
|
|
612
|
+
break
|
|
613
|
+
case 'h':
|
|
614
|
+
this.help.show('edit')
|
|
615
|
+
break
|
|
616
|
+
default:
|
|
617
|
+
used = false
|
|
586
618
|
}
|
|
619
|
+
if (used) L.DomEvent.stop(e)
|
|
587
620
|
}
|
|
588
621
|
L.DomEvent.addListener(document, 'keydown', globalShortcuts, this)
|
|
589
622
|
},
|
|
@@ -644,10 +677,7 @@ U.Map = L.Map.extend({
|
|
|
644
677
|
} catch (e) {
|
|
645
678
|
console.error(e)
|
|
646
679
|
this.removeLayer(tilelayer)
|
|
647
|
-
|
|
648
|
-
content: `${L._('Error in the tilelayer URL')}: ${tilelayer._url}`,
|
|
649
|
-
level: 'error',
|
|
650
|
-
})
|
|
680
|
+
U.Alert.error(`${L._('Error in the tilelayer URL')}: ${tilelayer._url}`)
|
|
651
681
|
// Users can put tilelayer URLs by hand, and if they add wrong {variable},
|
|
652
682
|
// Leaflet throw an error, and then the map is no more editable
|
|
653
683
|
}
|
|
@@ -679,10 +709,7 @@ U.Map = L.Map.extend({
|
|
|
679
709
|
} catch (e) {
|
|
680
710
|
this.removeLayer(overlay)
|
|
681
711
|
console.error(e)
|
|
682
|
-
|
|
683
|
-
content: `${L._('Error in the overlay URL')}: ${overlay._url}`,
|
|
684
|
-
level: 'error',
|
|
685
|
-
})
|
|
712
|
+
U.Alert.error(`${L._('Error in the overlay URL')}: ${overlay._url}`)
|
|
686
713
|
}
|
|
687
714
|
},
|
|
688
715
|
|
|
@@ -773,11 +800,14 @@ U.Map = L.Map.extend({
|
|
|
773
800
|
return L.Map.prototype.setMaxBounds.call(this, bounds)
|
|
774
801
|
},
|
|
775
802
|
|
|
776
|
-
createDataLayer: function (
|
|
777
|
-
|
|
778
|
-
|
|
803
|
+
createDataLayer: function (options = {}, sync) {
|
|
804
|
+
options.name = options.name || `${L._('Layer')} ${this.datalayers_index.length + 1}`
|
|
805
|
+
const datalayer = new U.DataLayer(this, options, sync)
|
|
806
|
+
|
|
807
|
+
if (sync !== false) {
|
|
808
|
+
datalayer.sync.upsert(datalayer.options)
|
|
779
809
|
}
|
|
780
|
-
return
|
|
810
|
+
return datalayer
|
|
781
811
|
},
|
|
782
812
|
|
|
783
813
|
newDataLayer: function () {
|
|
@@ -789,24 +819,25 @@ U.Map = L.Map.extend({
|
|
|
789
819
|
return U.SCHEMA[option] && U.SCHEMA[option].default
|
|
790
820
|
},
|
|
791
821
|
|
|
792
|
-
getOption: function (option) {
|
|
822
|
+
getOption: function (option, feature) {
|
|
823
|
+
if (feature) {
|
|
824
|
+
const value = this.rules.getOption(option, feature)
|
|
825
|
+
if (value !== undefined) return value
|
|
826
|
+
}
|
|
793
827
|
if (U.Utils.usableOption(this.options, option)) return this.options[option]
|
|
794
828
|
return this.getDefaultOption(option)
|
|
795
829
|
},
|
|
796
830
|
|
|
797
|
-
|
|
831
|
+
setCenterAndZoom: function () {
|
|
832
|
+
this._setCenterAndZoom()
|
|
833
|
+
U.Alert.success(L._('The zoom and center have been modified.'))
|
|
834
|
+
},
|
|
835
|
+
|
|
836
|
+
_setCenterAndZoom: function () {
|
|
798
837
|
this.options.center = this.getCenter()
|
|
799
838
|
this.options.zoom = this.getZoom()
|
|
800
839
|
this.isDirty = true
|
|
801
840
|
this._default_extent = false
|
|
802
|
-
if (this.options.umap_id) {
|
|
803
|
-
// We do not want an extra message during the map creation
|
|
804
|
-
// to avoid the double notification/alert.
|
|
805
|
-
this.ui.alert({
|
|
806
|
-
content: L._('The zoom and center have been modified.'),
|
|
807
|
-
level: 'info',
|
|
808
|
-
})
|
|
809
|
-
}
|
|
810
841
|
},
|
|
811
842
|
|
|
812
843
|
updateTileLayers: function () {
|
|
@@ -845,12 +876,11 @@ U.Map = L.Map.extend({
|
|
|
845
876
|
processFileToImport: function (file, layer, type) {
|
|
846
877
|
type = type || U.Utils.detectFileType(file)
|
|
847
878
|
if (!type) {
|
|
848
|
-
|
|
849
|
-
|
|
879
|
+
U.Alert.error(
|
|
880
|
+
L._('Unable to detect format of file {filename}', {
|
|
850
881
|
filename: file.name,
|
|
851
|
-
})
|
|
852
|
-
|
|
853
|
-
})
|
|
882
|
+
})
|
|
883
|
+
)
|
|
854
884
|
return
|
|
855
885
|
}
|
|
856
886
|
if (type === 'umap') {
|
|
@@ -861,6 +891,13 @@ U.Map = L.Map.extend({
|
|
|
861
891
|
}
|
|
862
892
|
},
|
|
863
893
|
|
|
894
|
+
importFromUrl: async function (uri) {
|
|
895
|
+
const response = await this.request.get(uri)
|
|
896
|
+
if (response && response.ok) {
|
|
897
|
+
this.importRaw(await response.text())
|
|
898
|
+
}
|
|
899
|
+
},
|
|
900
|
+
|
|
864
901
|
importRaw: function (rawData) {
|
|
865
902
|
const importedData = JSON.parse(rawData)
|
|
866
903
|
|
|
@@ -876,7 +913,11 @@ U.Map = L.Map.extend({
|
|
|
876
913
|
if (importedData.geometry) this.options.center = this.latLng(importedData.geometry)
|
|
877
914
|
const self = this
|
|
878
915
|
importedData.layers.forEach((geojson) => {
|
|
879
|
-
|
|
916
|
+
if (!geojson._umap_options && geojson._storage) {
|
|
917
|
+
geojson._umap_options = geojson._storage
|
|
918
|
+
delete geojson._storage
|
|
919
|
+
}
|
|
920
|
+
delete geojson._umap_options?.id // Never trust an id at this stage
|
|
880
921
|
const dataLayer = self.createDataLayer(geojson._umap_options)
|
|
881
922
|
dataLayer.fromUmapGeoJSON(geojson)
|
|
882
923
|
})
|
|
@@ -902,18 +943,17 @@ U.Map = L.Map.extend({
|
|
|
902
943
|
self.importRaw(rawData)
|
|
903
944
|
} catch (e) {
|
|
904
945
|
console.error('Error importing data', e)
|
|
905
|
-
|
|
906
|
-
content: L._('Invalid umap data in {filename}', { filename: file.name }),
|
|
907
|
-
level: 'error',
|
|
908
|
-
})
|
|
946
|
+
U.Alert.error(L._('Invalid umap data in {filename}', { filename: file.name }))
|
|
909
947
|
}
|
|
910
948
|
}
|
|
911
949
|
},
|
|
912
950
|
|
|
913
951
|
openBrowser: function (mode) {
|
|
914
|
-
this.onceDatalayersLoaded(
|
|
915
|
-
|
|
916
|
-
|
|
952
|
+
this.onceDatalayersLoaded(() => this.browser.open(mode))
|
|
953
|
+
},
|
|
954
|
+
|
|
955
|
+
openCaption: function () {
|
|
956
|
+
this.onceDatalayersLoaded(() => this.caption.open())
|
|
917
957
|
},
|
|
918
958
|
|
|
919
959
|
eachDataLayer: function (method, context) {
|
|
@@ -965,7 +1005,7 @@ U.Map = L.Map.extend({
|
|
|
965
1005
|
},
|
|
966
1006
|
|
|
967
1007
|
checkDirty: function () {
|
|
968
|
-
|
|
1008
|
+
this._container.classList.toggle('umap-is-dirty', this.isDirty)
|
|
969
1009
|
},
|
|
970
1010
|
|
|
971
1011
|
addDirtyDatalayer: function (datalayer) {
|
|
@@ -998,6 +1038,7 @@ U.Map = L.Map.extend({
|
|
|
998
1038
|
},
|
|
999
1039
|
|
|
1000
1040
|
saveSelf: async function () {
|
|
1041
|
+
this.rules.commit()
|
|
1001
1042
|
const geojson = {
|
|
1002
1043
|
type: 'Feature',
|
|
1003
1044
|
geometry: this.geometry(),
|
|
@@ -1008,66 +1049,56 @@ U.Map = L.Map.extend({
|
|
|
1008
1049
|
formData.append('center', JSON.stringify(this.geometry()))
|
|
1009
1050
|
formData.append('settings', JSON.stringify(geojson))
|
|
1010
1051
|
const uri = this.urls.get('map_save', { map_id: this.options.umap_id })
|
|
1011
|
-
const [data,
|
|
1052
|
+
const [data, _, error] = await this.server.post(uri, {}, formData)
|
|
1012
1053
|
// FIXME: login_required response will not be an error, so it will not
|
|
1013
1054
|
// stop code while it should
|
|
1014
|
-
if (
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
L._(
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
},
|
|
1041
|
-
]
|
|
1042
|
-
if (this.options.urls.map_send_edit_link) {
|
|
1043
|
-
alert.actions.push({
|
|
1044
|
-
label: L._('Send me the link'),
|
|
1045
|
-
input: L._('Email'),
|
|
1046
|
-
callback: this.sendEditLink,
|
|
1047
|
-
callbackContext: this,
|
|
1048
|
-
})
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
1051
|
-
} else if (!this.permissions.isDirty) {
|
|
1055
|
+
if (error) {
|
|
1056
|
+
return
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
if (!this.options.umap_id) {
|
|
1060
|
+
this.options.umap_id = data.id
|
|
1061
|
+
this.permissions.setOptions(data.permissions)
|
|
1062
|
+
this.permissions.commit()
|
|
1063
|
+
if (data?.permissions?.anonymous_edit_url) {
|
|
1064
|
+
this.once('saved', () => {
|
|
1065
|
+
U.AlertCreation.info(
|
|
1066
|
+
L._('Your map has been created with an anonymous account!'),
|
|
1067
|
+
Number.Infinity,
|
|
1068
|
+
data.permissions.anonymous_edit_url,
|
|
1069
|
+
this.options.urls.map_send_edit_link
|
|
1070
|
+
? this.sendEditLinkEmail.bind(this)
|
|
1071
|
+
: null
|
|
1072
|
+
)
|
|
1073
|
+
})
|
|
1074
|
+
} else {
|
|
1075
|
+
this.once('saved', () => {
|
|
1076
|
+
U.Alert.success(L._('Congratulations, your map has been created!'))
|
|
1077
|
+
})
|
|
1078
|
+
}
|
|
1079
|
+
} else {
|
|
1080
|
+
if (!this.permissions.isDirty) {
|
|
1052
1081
|
// Do not override local changes to permissions,
|
|
1053
1082
|
// but update in case some other editors changed them in the meantime.
|
|
1054
1083
|
this.permissions.setOptions(data.permissions)
|
|
1055
1084
|
this.permissions.commit()
|
|
1056
1085
|
}
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
else window.location = data.url
|
|
1061
|
-
alert.content = data.info || alert.content
|
|
1062
|
-
this.once('saved', () => this.ui.alert(alert))
|
|
1063
|
-
this.editPanel.close()
|
|
1064
|
-
this.permissions.save()
|
|
1086
|
+
this.once('saved', () => {
|
|
1087
|
+
U.Alert.success(data.info || L._('Map has been saved!'))
|
|
1088
|
+
})
|
|
1065
1089
|
}
|
|
1090
|
+
// Update URL in case the name has changed.
|
|
1091
|
+
if (history?.pushState) {
|
|
1092
|
+
history.pushState({}, this.options.name, data.url)
|
|
1093
|
+
} else {
|
|
1094
|
+
window.location = data.url
|
|
1095
|
+
}
|
|
1096
|
+
this.permissions.save()
|
|
1066
1097
|
},
|
|
1067
1098
|
|
|
1068
1099
|
save: function () {
|
|
1069
1100
|
if (!this.isDirty) return
|
|
1070
|
-
if (this._default_extent) this.
|
|
1101
|
+
if (this._default_extent) this._setCenterAndZoom()
|
|
1071
1102
|
this.backup()
|
|
1072
1103
|
this.once('saved', () => {
|
|
1073
1104
|
this.isDirty = false
|
|
@@ -1080,33 +1111,20 @@ U.Map = L.Map.extend({
|
|
|
1080
1111
|
}
|
|
1081
1112
|
},
|
|
1082
1113
|
|
|
1083
|
-
sendEditLink: async function () {
|
|
1084
|
-
const input = this.ui._alert.querySelector('input')
|
|
1085
|
-
const email = input.value
|
|
1086
|
-
|
|
1087
|
-
const formData = new FormData()
|
|
1088
|
-
formData.append('email', email)
|
|
1089
|
-
|
|
1090
|
-
const url = this.urls.get('map_send_edit_link', { map_id: this.options.umap_id })
|
|
1091
|
-
await this.server.post(url, {}, formData)
|
|
1092
|
-
},
|
|
1093
|
-
|
|
1094
1114
|
star: async function () {
|
|
1095
|
-
if (!this.options.umap_id)
|
|
1096
|
-
return
|
|
1097
|
-
|
|
1098
|
-
level: 'error',
|
|
1099
|
-
})
|
|
1115
|
+
if (!this.options.umap_id) {
|
|
1116
|
+
return U.Alert.error(L._('Please save the map first'))
|
|
1117
|
+
}
|
|
1100
1118
|
const url = this.urls.get('map_star', { map_id: this.options.umap_id })
|
|
1101
1119
|
const [data, response, error] = await this.server.post(url)
|
|
1102
|
-
if (
|
|
1103
|
-
|
|
1104
|
-
let msg = data.starred
|
|
1105
|
-
? L._('Map has been starred')
|
|
1106
|
-
: L._('Map has been unstarred')
|
|
1107
|
-
this.ui.alert({ content: msg, level: 'info' })
|
|
1108
|
-
this.renderControls()
|
|
1120
|
+
if (error) {
|
|
1121
|
+
return
|
|
1109
1122
|
}
|
|
1123
|
+
this.options.starred = data.starred
|
|
1124
|
+
U.Alert.success(
|
|
1125
|
+
data.starred ? L._('Map has been starred') : L._('Map has been unstarred')
|
|
1126
|
+
)
|
|
1127
|
+
this.renderControls()
|
|
1110
1128
|
},
|
|
1111
1129
|
|
|
1112
1130
|
geometry: function () {
|
|
@@ -1410,6 +1428,8 @@ U.Map = L.Map.extend({
|
|
|
1410
1428
|
this.options.limitBounds.north = L.Util.formatNum(bounds.getNorth())
|
|
1411
1429
|
this.options.limitBounds.east = L.Util.formatNum(bounds.getEast())
|
|
1412
1430
|
boundsBuilder.fetchAll()
|
|
1431
|
+
|
|
1432
|
+
this.sync.update(this, 'options.limitBounds', this.options.limitBounds)
|
|
1413
1433
|
this.isDirty = true
|
|
1414
1434
|
this.handleLimitBounds()
|
|
1415
1435
|
},
|
|
@@ -1465,6 +1485,12 @@ U.Map = L.Map.extend({
|
|
|
1465
1485
|
slideshow.appendChild(slideshowBuilder.build())
|
|
1466
1486
|
},
|
|
1467
1487
|
|
|
1488
|
+
_editSync: function (container) {
|
|
1489
|
+
const sync = L.DomUtil.createFieldset(container, L._('Real-time collaboration'))
|
|
1490
|
+
const builder = new U.FormBuilder(this, ['options.syncEnabled'])
|
|
1491
|
+
sync.appendChild(builder.build())
|
|
1492
|
+
},
|
|
1493
|
+
|
|
1468
1494
|
_advancedActions: function (container) {
|
|
1469
1495
|
const advancedActions = L.DomUtil.createFieldset(container, L._('Advanced actions'))
|
|
1470
1496
|
const advancedButtons = L.DomUtil.create('div', 'button-bar half', advancedActions)
|
|
@@ -1510,10 +1536,10 @@ U.Map = L.Map.extend({
|
|
|
1510
1536
|
editCaption: function () {
|
|
1511
1537
|
if (!this.editEnabled) return
|
|
1512
1538
|
if (this.options.editMode !== 'advanced') return
|
|
1513
|
-
const container = L.DomUtil.create('div', 'umap-edit-container')
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1539
|
+
const container = L.DomUtil.create('div', 'umap-edit-container')
|
|
1540
|
+
const metadataFields = ['options.name', 'options.description']
|
|
1541
|
+
|
|
1542
|
+
L.DomUtil.createTitle(container, L._('Edit map details'), 'icon-caption')
|
|
1517
1543
|
const builder = new U.FormBuilder(this, metadataFields, {
|
|
1518
1544
|
className: 'map-metadata',
|
|
1519
1545
|
})
|
|
@@ -1542,10 +1568,14 @@ U.Map = L.Map.extend({
|
|
|
1542
1568
|
this._editShapeProperties(container)
|
|
1543
1569
|
this._editDefaultProperties(container)
|
|
1544
1570
|
this._editInteractionsProperties(container)
|
|
1571
|
+
this.rules.edit(container)
|
|
1545
1572
|
this._editTilelayer(container)
|
|
1546
1573
|
this._editOverlay(container)
|
|
1547
1574
|
this._editBounds(container)
|
|
1548
1575
|
this._editSlideshow(container)
|
|
1576
|
+
if (this.options.websocketEnabled) {
|
|
1577
|
+
this._editSync(container)
|
|
1578
|
+
}
|
|
1549
1579
|
this._advancedActions(container)
|
|
1550
1580
|
|
|
1551
1581
|
this.editPanel.open({ content: container, className: 'dark' })
|
|
@@ -1556,6 +1586,7 @@ U.Map = L.Map.extend({
|
|
|
1556
1586
|
this.editEnabled = true
|
|
1557
1587
|
this.drop.enable()
|
|
1558
1588
|
this.fire('edit:enabled')
|
|
1589
|
+
this.initSyncEngine()
|
|
1559
1590
|
},
|
|
1560
1591
|
|
|
1561
1592
|
disableEdit: function () {
|
|
@@ -1567,6 +1598,7 @@ U.Map = L.Map.extend({
|
|
|
1567
1598
|
this.fire('edit:disabled')
|
|
1568
1599
|
this.editPanel.close()
|
|
1569
1600
|
this.fullPanel.close()
|
|
1601
|
+
this.sync.stop()
|
|
1570
1602
|
},
|
|
1571
1603
|
|
|
1572
1604
|
hasEditMode: function () {
|
|
@@ -1590,8 +1622,8 @@ U.Map = L.Map.extend({
|
|
|
1590
1622
|
L.DomUtil.createButton(
|
|
1591
1623
|
'umap-about-link flat',
|
|
1592
1624
|
container,
|
|
1593
|
-
L._('
|
|
1594
|
-
this.
|
|
1625
|
+
L._('Open caption'),
|
|
1626
|
+
this.openCaption,
|
|
1595
1627
|
this
|
|
1596
1628
|
)
|
|
1597
1629
|
L.DomUtil.createButton(
|
|
@@ -1741,7 +1773,7 @@ U.Map = L.Map.extend({
|
|
|
1741
1773
|
items.push(
|
|
1742
1774
|
'-',
|
|
1743
1775
|
{
|
|
1744
|
-
text: L._('
|
|
1776
|
+
text: L._('Open browser'),
|
|
1745
1777
|
callback: () => this.openBrowser('layers'),
|
|
1746
1778
|
},
|
|
1747
1779
|
{
|
|
@@ -1757,8 +1789,8 @@ U.Map = L.Map.extend({
|
|
|
1757
1789
|
}
|
|
1758
1790
|
items.push(
|
|
1759
1791
|
{
|
|
1760
|
-
text: L._('
|
|
1761
|
-
callback: this.
|
|
1792
|
+
text: L._('Open caption'),
|
|
1793
|
+
callback: this.openCaption,
|
|
1762
1794
|
},
|
|
1763
1795
|
{
|
|
1764
1796
|
text: this.help.displayLabel('SEARCH'),
|
|
@@ -1844,10 +1876,6 @@ U.Map = L.Map.extend({
|
|
|
1844
1876
|
if (this._controls.search) this._controls.search.open()
|
|
1845
1877
|
},
|
|
1846
1878
|
|
|
1847
|
-
getFilterKeys: function () {
|
|
1848
|
-
return (this.options.filterKey || this.options.sortKey || 'name').split(',')
|
|
1849
|
-
},
|
|
1850
|
-
|
|
1851
1879
|
getLayersBounds: function () {
|
|
1852
1880
|
const bounds = new L.latLngBounds()
|
|
1853
1881
|
this.eachBrowsableDataLayer((d) => {
|
|
@@ -1855,4 +1883,13 @@ U.Map = L.Map.extend({
|
|
|
1855
1883
|
})
|
|
1856
1884
|
return bounds
|
|
1857
1885
|
},
|
|
1886
|
+
|
|
1887
|
+
sendEditLinkEmail: async function (formData) {
|
|
1888
|
+
const sendLink =
|
|
1889
|
+
this.options.urls.map_send_edit_link &&
|
|
1890
|
+
this.urls.get('map_send_edit_link', {
|
|
1891
|
+
map_id: this.options.umap_id,
|
|
1892
|
+
})
|
|
1893
|
+
await this.server.post(sendLink, {}, formData)
|
|
1894
|
+
},
|
|
1858
1895
|
})
|