umap-project 2.3.1__py3-none-any.whl → 2.4.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.
- umap/.DS_Store +0 -0
- 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 +109 -59
- umap/management/commands/run_websocket_server.py +23 -0
- umap/models.py +6 -1
- umap/settings/base.py +11 -3
- umap/static/.DS_Store +0 -0
- umap/static/umap/.DS_Store +0 -0
- umap/static/umap/base.css +53 -162
- 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 +44 -0
- umap/static/umap/css/panel.css +19 -57
- umap/static/umap/css/tooltip.css +59 -0
- umap/static/umap/css/window.css +35 -0
- umap/static/umap/favicons/.DS_Store +0 -0
- umap/static/umap/fonts/.DS_Store +0 -0
- umap/static/umap/img/.DS_Store +0 -0
- 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/.DS_Store +0 -0
- 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 +1 -1
- umap/static/umap/js/modules/caption.js +4 -3
- umap/static/umap/js/modules/global.js +36 -12
- umap/static/umap/js/modules/help.js +255 -0
- umap/static/umap/js/modules/importer.js +280 -0
- umap/static/umap/js/modules/importers/communesfr.js +44 -0
- umap/static/umap/js/modules/importers/datasets.js +41 -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} +25 -14
- 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 +13 -14
- umap/static/umap/js/umap.core.js +1 -324
- umap/static/umap/js/umap.features.js +67 -27
- umap/static/umap/js/umap.forms.js +9 -13
- umap/static/umap/js/umap.js +220 -180
- umap/static/umap/js/umap.layer.js +142 -74
- umap/static/umap/js/umap.permissions.js +5 -9
- 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 +51 -16
- umap/static/umap/locale/en.json +51 -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 +52 -17
- umap/static/umap/locale/fr.json +52 -17
- 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 +27 -41
- umap/static/umap/unittests/sync.js +105 -0
- umap/static/umap/unittests/utils.js +76 -34
- umap/static/umap/vars.css +18 -1
- umap/static/umap/vendors/dompurify/purify.es.js +5 -59
- umap/static/umap/vendors/dompurify/purify.es.mjs.map +1 -1
- 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/.DS_Store +0 -0
- umap/tests/base.py +2 -0
- umap/tests/integration/.DS_Store +0 -0
- umap/tests/integration/conftest.py +30 -0
- umap/tests/integration/test_anonymous_owned_map.py +8 -13
- umap/tests/integration/test_browser.py +1 -1
- 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 +4 -4
- umap/tests/integration/test_edit_map.py +1 -1
- umap/tests/integration/test_facets_browser.py +3 -3
- umap/tests/integration/test_import.py +138 -49
- umap/tests/integration/test_map.py +2 -2
- 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_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.1.dist-info → umap_project-2.4.0b0.dist-info}/METADATA +11 -9
- {umap_project-2.3.1.dist-info → umap_project-2.4.0b0.dist-info}/RECORD +207 -164
- {umap_project-2.3.1.dist-info → umap_project-2.4.0b0.dist-info}/WHEEL +1 -1
- 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.1.dist-info → umap_project-2.4.0b0.dist-info}/entry_points.txt +0 -0
- {umap_project-2.3.1.dist-info → umap_project-2.4.0b0.dist-info}/licenses/LICENSE +0 -0
umap/static/umap/js/umap.core.js
CHANGED
|
@@ -139,7 +139,7 @@ L.DomUtil.createButtonIcon = (parent, className, title, size = 16) => {
|
|
|
139
139
|
|
|
140
140
|
L.DomUtil.createTitle = (parent, text, className, tag = 'h3') => {
|
|
141
141
|
const title = L.DomUtil.create(tag, '', parent)
|
|
142
|
-
L.DomUtil.createIcon(title, className)
|
|
142
|
+
if (className) L.DomUtil.createIcon(title, className)
|
|
143
143
|
L.DomUtil.add('span', '', title, text)
|
|
144
144
|
return title
|
|
145
145
|
}
|
|
@@ -245,329 +245,6 @@ L.DomEvent.once = (el, types, fn, context) => {
|
|
|
245
245
|
return L.DomEvent.on(el, types, fn, context).on(el, types, handler, context)
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
-
/*
|
|
249
|
-
* Global events
|
|
250
|
-
*/
|
|
251
|
-
U.Keys = {
|
|
252
|
-
LEFT: 37,
|
|
253
|
-
UP: 38,
|
|
254
|
-
RIGHT: 39,
|
|
255
|
-
DOWN: 40,
|
|
256
|
-
TAB: 9,
|
|
257
|
-
ENTER: 13,
|
|
258
|
-
ESC: 27,
|
|
259
|
-
APPLE: 91,
|
|
260
|
-
SHIFT: 16,
|
|
261
|
-
ALT: 17,
|
|
262
|
-
CTRL: 18,
|
|
263
|
-
E: 69,
|
|
264
|
-
F: 70,
|
|
265
|
-
H: 72,
|
|
266
|
-
I: 73,
|
|
267
|
-
L: 76,
|
|
268
|
-
M: 77,
|
|
269
|
-
O: 79,
|
|
270
|
-
P: 80,
|
|
271
|
-
S: 83,
|
|
272
|
-
Z: 90,
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
U.Help = L.Class.extend({
|
|
276
|
-
SHORTCUTS: {
|
|
277
|
-
DRAW_MARKER: {
|
|
278
|
-
shortcut: 'Modifier+M',
|
|
279
|
-
label: L._('Draw a marker'),
|
|
280
|
-
},
|
|
281
|
-
DRAW_LINE: {
|
|
282
|
-
shortcut: 'Modifier+L',
|
|
283
|
-
label: L._('Draw a polyline'),
|
|
284
|
-
},
|
|
285
|
-
DRAW_POLYGON: {
|
|
286
|
-
shortcut: 'Modifier+P',
|
|
287
|
-
label: L._('Draw a polygon'),
|
|
288
|
-
},
|
|
289
|
-
TOGGLE_EDIT: {
|
|
290
|
-
shortcut: 'Modifier+E',
|
|
291
|
-
label: L._('Toggle edit mode'),
|
|
292
|
-
},
|
|
293
|
-
STOP_EDIT: {
|
|
294
|
-
shortcut: 'Modifier+E',
|
|
295
|
-
label: L._('Stop editing'),
|
|
296
|
-
},
|
|
297
|
-
SAVE_MAP: {
|
|
298
|
-
shortcut: 'Modifier+S',
|
|
299
|
-
label: L._('Save map'),
|
|
300
|
-
},
|
|
301
|
-
IMPORT_PANEL: {
|
|
302
|
-
shortcut: 'Modifier+I',
|
|
303
|
-
label: L._('Import data'),
|
|
304
|
-
},
|
|
305
|
-
SEARCH: {
|
|
306
|
-
shortcut: 'Modifier+F',
|
|
307
|
-
label: L._('Search location'),
|
|
308
|
-
},
|
|
309
|
-
CANCEL: {
|
|
310
|
-
shortcut: 'Modifier+Z',
|
|
311
|
-
label: L._('Cancel edits'),
|
|
312
|
-
},
|
|
313
|
-
PREVIEW: {
|
|
314
|
-
shortcut: 'Modifier+E',
|
|
315
|
-
label: L._('Back to preview'),
|
|
316
|
-
},
|
|
317
|
-
SAVE: {
|
|
318
|
-
shortcut: 'Modifier+S',
|
|
319
|
-
label: L._('Save current edits'),
|
|
320
|
-
},
|
|
321
|
-
EDIT_FEATURE_LAYER: {
|
|
322
|
-
shortcut: 'Modifier+⇧+Click',
|
|
323
|
-
label: L._("Edit feature's layer"),
|
|
324
|
-
},
|
|
325
|
-
CONTINUE_LINE: {
|
|
326
|
-
shortcut: 'Modifier+Click',
|
|
327
|
-
label: L._('Continue line'),
|
|
328
|
-
},
|
|
329
|
-
},
|
|
330
|
-
|
|
331
|
-
displayLabel: function (action, withKbdTag = true) {
|
|
332
|
-
let { shortcut, label } = this.SHORTCUTS[action]
|
|
333
|
-
const modifier = this.isMacOS ? 'Cmd' : 'Ctrl'
|
|
334
|
-
shortcut = shortcut.replace('Modifier', modifier)
|
|
335
|
-
if (withKbdTag) {
|
|
336
|
-
shortcut = shortcut
|
|
337
|
-
.split('+')
|
|
338
|
-
.map((el) => `<kbd>${el}</kbd>`)
|
|
339
|
-
.join('+')
|
|
340
|
-
label += ` ${shortcut}`
|
|
341
|
-
} else {
|
|
342
|
-
label += ` (${shortcut})`
|
|
343
|
-
}
|
|
344
|
-
return label
|
|
345
|
-
},
|
|
346
|
-
|
|
347
|
-
initialize: function (map) {
|
|
348
|
-
this.map = map
|
|
349
|
-
this.box = L.DomUtil.create(
|
|
350
|
-
'div',
|
|
351
|
-
'umap-help-box with-transition dark',
|
|
352
|
-
document.body
|
|
353
|
-
)
|
|
354
|
-
const closeButton = L.DomUtil.createButton(
|
|
355
|
-
'umap-close-link',
|
|
356
|
-
this.box,
|
|
357
|
-
'',
|
|
358
|
-
this.hide,
|
|
359
|
-
this
|
|
360
|
-
)
|
|
361
|
-
L.DomUtil.add('i', 'umap-close-icon', closeButton)
|
|
362
|
-
const label = L.DomUtil.create('span', '', closeButton)
|
|
363
|
-
label.title = label.textContent = L._('Close')
|
|
364
|
-
this.content = L.DomUtil.create('div', 'umap-help-content', this.box)
|
|
365
|
-
this.isMacOS = /mac/i.test(
|
|
366
|
-
// eslint-disable-next-line compat/compat -- Fallback available.
|
|
367
|
-
navigator.userAgentData ? navigator.userAgentData.platform : navigator.platform
|
|
368
|
-
)
|
|
369
|
-
},
|
|
370
|
-
|
|
371
|
-
onKeyDown: function (e) {
|
|
372
|
-
const key = e.keyCode,
|
|
373
|
-
ESC = 27
|
|
374
|
-
if (key === ESC) {
|
|
375
|
-
this.hide()
|
|
376
|
-
}
|
|
377
|
-
},
|
|
378
|
-
|
|
379
|
-
show: function () {
|
|
380
|
-
this.content.innerHTML = ''
|
|
381
|
-
for (let i = 0, name; i < arguments.length; i++) {
|
|
382
|
-
name = arguments[i]
|
|
383
|
-
L.DomUtil.add('div', 'umap-help-entry', this.content, this.resolve(name))
|
|
384
|
-
}
|
|
385
|
-
L.DomUtil.addClass(document.body, 'umap-help-on')
|
|
386
|
-
},
|
|
387
|
-
|
|
388
|
-
hide: function () {
|
|
389
|
-
L.DomUtil.removeClass(document.body, 'umap-help-on')
|
|
390
|
-
},
|
|
391
|
-
|
|
392
|
-
visible: function () {
|
|
393
|
-
return L.DomUtil.hasClass(document.body, 'umap-help-on')
|
|
394
|
-
},
|
|
395
|
-
|
|
396
|
-
resolve: function (name) {
|
|
397
|
-
return typeof this[name] === 'function' ? this[name]() : this[name]
|
|
398
|
-
},
|
|
399
|
-
|
|
400
|
-
button: function (container, entries, classname) {
|
|
401
|
-
const helpButton = L.DomUtil.createButton(
|
|
402
|
-
classname || 'umap-help-button',
|
|
403
|
-
container,
|
|
404
|
-
L._('Help')
|
|
405
|
-
)
|
|
406
|
-
if (entries) {
|
|
407
|
-
L.DomEvent.on(helpButton, 'click', L.DomEvent.stop).on(
|
|
408
|
-
helpButton,
|
|
409
|
-
'click',
|
|
410
|
-
function (e) {
|
|
411
|
-
const args = typeof entries === 'string' ? [entries] : entries
|
|
412
|
-
this.show.apply(this, args)
|
|
413
|
-
},
|
|
414
|
-
this
|
|
415
|
-
)
|
|
416
|
-
}
|
|
417
|
-
return helpButton
|
|
418
|
-
},
|
|
419
|
-
|
|
420
|
-
link: function (container, entries) {
|
|
421
|
-
const helpButton = this.button(container, entries, 'umap-help-link')
|
|
422
|
-
helpButton.textContent = L._('Help')
|
|
423
|
-
return helpButton
|
|
424
|
-
},
|
|
425
|
-
|
|
426
|
-
edit: function () {
|
|
427
|
-
const container = L.DomUtil.create('div', ''),
|
|
428
|
-
self = this,
|
|
429
|
-
title = L.DomUtil.create('h3', '', container),
|
|
430
|
-
actionsContainer = L.DomUtil.create('ul', 'umap-edit-actions', container)
|
|
431
|
-
const addAction = (action) => {
|
|
432
|
-
const actionContainer = L.DomUtil.add('li', '', actionsContainer)
|
|
433
|
-
L.DomUtil.add('i', action.options.className, actionContainer),
|
|
434
|
-
L.DomUtil.add('span', '', actionContainer, action.options.tooltip)
|
|
435
|
-
L.DomEvent.on(actionContainer, 'click', action.addHooks, action)
|
|
436
|
-
L.DomEvent.on(actionContainer, 'click', self.hide, self)
|
|
437
|
-
}
|
|
438
|
-
title.textContent = L._('Where do we go from here?')
|
|
439
|
-
for (const id in this.map.helpMenuActions) {
|
|
440
|
-
addAction(this.map.helpMenuActions[id])
|
|
441
|
-
}
|
|
442
|
-
return container
|
|
443
|
-
},
|
|
444
|
-
|
|
445
|
-
importFormats: function () {
|
|
446
|
-
const container = L.DomUtil.create('div')
|
|
447
|
-
L.DomUtil.add('h3', '', container, 'GeojSON')
|
|
448
|
-
L.DomUtil.add('p', '', container, L._('All properties are imported.'))
|
|
449
|
-
L.DomUtil.add('h3', '', container, 'GPX')
|
|
450
|
-
L.DomUtil.add('p', '', container, `${L._('Properties imported:')}name, desc`)
|
|
451
|
-
L.DomUtil.add('h3', '', container, 'KML')
|
|
452
|
-
L.DomUtil.add('p', '', container, `${L._('Properties imported:')}name, description`)
|
|
453
|
-
L.DomUtil.add('h3', '', container, 'CSV')
|
|
454
|
-
L.DomUtil.add(
|
|
455
|
-
'p',
|
|
456
|
-
'',
|
|
457
|
-
container,
|
|
458
|
-
L._(
|
|
459
|
-
'Comma, tab or semi-colon separated values. SRS WGS84 is implied. Only Point geometries are imported. The import will look at the column headers for any mention of «lat» and «lon» at the begining of the header, case insensitive. All other column are imported as properties.'
|
|
460
|
-
)
|
|
461
|
-
)
|
|
462
|
-
L.DomUtil.add('h3', '', container, 'uMap')
|
|
463
|
-
L.DomUtil.add(
|
|
464
|
-
'p',
|
|
465
|
-
'',
|
|
466
|
-
container,
|
|
467
|
-
L._('Imports all umap data, including layers and settings.')
|
|
468
|
-
)
|
|
469
|
-
return container
|
|
470
|
-
},
|
|
471
|
-
|
|
472
|
-
textFormatting: function () {
|
|
473
|
-
const container = L.DomUtil.create('div'),
|
|
474
|
-
title = L.DomUtil.add('h3', '', container, L._('Text formatting')),
|
|
475
|
-
elements = L.DomUtil.create('ul', '', container)
|
|
476
|
-
L.DomUtil.add('li', '', elements, L._('*single star for italic*'))
|
|
477
|
-
L.DomUtil.add('li', '', elements, L._('**double star for bold**'))
|
|
478
|
-
L.DomUtil.add('li', '', elements, L._('# one hash for main heading'))
|
|
479
|
-
L.DomUtil.add('li', '', elements, L._('## two hashes for second heading'))
|
|
480
|
-
L.DomUtil.add('li', '', elements, L._('### three hashes for third heading'))
|
|
481
|
-
L.DomUtil.add('li', '', elements, L._('Simple link: [[http://example.com]]'))
|
|
482
|
-
L.DomUtil.add(
|
|
483
|
-
'li',
|
|
484
|
-
'',
|
|
485
|
-
elements,
|
|
486
|
-
L._('Link with text: [[http://example.com|text of the link]]')
|
|
487
|
-
)
|
|
488
|
-
L.DomUtil.add('li', '', elements, L._('Image: {{http://image.url.com}}'))
|
|
489
|
-
L.DomUtil.add(
|
|
490
|
-
'li',
|
|
491
|
-
'',
|
|
492
|
-
elements,
|
|
493
|
-
L._('Image with custom width (in px): {{http://image.url.com|width}}')
|
|
494
|
-
)
|
|
495
|
-
L.DomUtil.add('li', '', elements, L._('Iframe: {{{http://iframe.url.com}}}'))
|
|
496
|
-
L.DomUtil.add(
|
|
497
|
-
'li',
|
|
498
|
-
'',
|
|
499
|
-
elements,
|
|
500
|
-
L._('Iframe with custom height (in px): {{{http://iframe.url.com|height}}}')
|
|
501
|
-
)
|
|
502
|
-
L.DomUtil.add(
|
|
503
|
-
'li',
|
|
504
|
-
'',
|
|
505
|
-
elements,
|
|
506
|
-
L._(
|
|
507
|
-
'Iframe with custom height and width (in px): {{{http://iframe.url.com|height*width}}}'
|
|
508
|
-
)
|
|
509
|
-
)
|
|
510
|
-
L.DomUtil.add('li', '', elements, L._('--- for a horizontal rule'))
|
|
511
|
-
return container
|
|
512
|
-
},
|
|
513
|
-
|
|
514
|
-
dynamicProperties: function () {
|
|
515
|
-
const container = L.DomUtil.create('div')
|
|
516
|
-
L.DomUtil.add('h3', '', container, L._('Dynamic properties'))
|
|
517
|
-
L.DomUtil.add(
|
|
518
|
-
'p',
|
|
519
|
-
'',
|
|
520
|
-
container,
|
|
521
|
-
L._(
|
|
522
|
-
'Use placeholders with feature properties between brackets, eg. {name}, they will be dynamically replaced by the corresponding values.'
|
|
523
|
-
)
|
|
524
|
-
)
|
|
525
|
-
return container
|
|
526
|
-
},
|
|
527
|
-
|
|
528
|
-
formatURL: `${L._(
|
|
529
|
-
'Supported variables that will be dynamically replaced'
|
|
530
|
-
)}: {bbox}, {lat}, {lng}, {zoom}, {east}, {north}..., {left}, {top}..., locale, lang`,
|
|
531
|
-
colorValue: L._('Must be a valid CSS value (eg.: DarkBlue or #123456)'),
|
|
532
|
-
smoothFactor: L._(
|
|
533
|
-
'How much to simplify the polyline on each zoom level (more = better performance and smoother look, less = more accurate)'
|
|
534
|
-
),
|
|
535
|
-
dashArray: L._(
|
|
536
|
-
'A comma separated list of numbers that defines the stroke dash pattern. Ex.: "5, 10, 15".'
|
|
537
|
-
),
|
|
538
|
-
zoomTo: L._('Zoom level for automatic zooms'),
|
|
539
|
-
labelKey: L._(
|
|
540
|
-
'The name of the property to use as feature label (eg.: "nom"). You can also use properties inside brackets to use more than one or mix with static content (eg.: "{name} in {place}")'
|
|
541
|
-
),
|
|
542
|
-
stroke: L._('Whether to display or not polygons paths.'),
|
|
543
|
-
fill: L._('Whether to fill polygons with color.'),
|
|
544
|
-
fillColor: L._('Optional. Same as color if not set.'),
|
|
545
|
-
shortCredit: L._('Will be displayed in the bottom right corner of the map'),
|
|
546
|
-
longCredit: L._('Will be visible in the caption of the map'),
|
|
547
|
-
permanentCredit: L._(
|
|
548
|
-
'Will be permanently visible in the bottom left corner of the map'
|
|
549
|
-
),
|
|
550
|
-
sortKey: L._(
|
|
551
|
-
'Comma separated list of properties to use for sorting features. To reverse the sort, put a minus sign (-) before. Eg. mykey,-otherkey.'
|
|
552
|
-
),
|
|
553
|
-
slugKey: L._('The name of the property to use as feature unique identifier.'),
|
|
554
|
-
filterKey: L._(
|
|
555
|
-
'Comma separated list of properties to use when filtering features by text input'
|
|
556
|
-
),
|
|
557
|
-
facetKey: L._(
|
|
558
|
-
'Comma separated list of properties to use for filters (eg.: mykey,otherkey). To control label, add it after a | (eg.: mykey|My Key,otherkey|Other Key). To control input field type, add it after another | (eg.: mykey|My Key|checkbox,otherkey|Other Key|datetime). Allowed values for the input field type are checkbox (default), radio, number, date and datetime.'
|
|
559
|
-
),
|
|
560
|
-
interactive: L._(
|
|
561
|
-
'If false, the polygon or line will act as a part of the underlying map.'
|
|
562
|
-
),
|
|
563
|
-
outlink: L._('Define link to open in a new window on polygon click.'),
|
|
564
|
-
dynamicRemoteData: L._('Fetch data each time map view changes.'),
|
|
565
|
-
proxyRemoteData: L._("To use if remote server doesn't allow cross domain (slower)"),
|
|
566
|
-
browsable: L._(
|
|
567
|
-
'Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…'
|
|
568
|
-
),
|
|
569
|
-
})
|
|
570
|
-
|
|
571
248
|
L.LatLng.prototype.isValid = function () {
|
|
572
249
|
return (
|
|
573
250
|
isFinite(this.lat) &&
|
|
@@ -1,25 +1,61 @@
|
|
|
1
1
|
U.FeatureMixin = {
|
|
2
2
|
staticOptions: { mainColor: 'color' },
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
getSyncMetadata: function () {
|
|
5
|
+
return {
|
|
6
|
+
subject: 'feature',
|
|
7
|
+
metadata: {
|
|
8
|
+
id: this.id,
|
|
9
|
+
layerId: this.datalayer?.id || null,
|
|
10
|
+
featureType: this.getClassName(),
|
|
11
|
+
},
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
onCommit: function () {
|
|
16
|
+
// When the layer is a remote layer, we don't want to sync the creation of the
|
|
17
|
+
// points via the websocket, as the other peers will get them themselves.
|
|
18
|
+
if (this.datalayer.isRemoteLayer()) return
|
|
19
|
+
this.sync.upsert(this.toGeoJSON())
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
getGeometry: function () {
|
|
23
|
+
return this.toGeoJSON().geometry
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
syncDelete: function () {
|
|
27
|
+
this.sync.delete()
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
initialize: function (map, latlng, options, id) {
|
|
5
31
|
this.map = map
|
|
32
|
+
this.sync = map.sync_engine.proxy(this)
|
|
33
|
+
|
|
6
34
|
if (typeof options === 'undefined') {
|
|
7
35
|
options = {}
|
|
8
36
|
}
|
|
9
37
|
// DataLayer the marker belongs to
|
|
10
38
|
this.datalayer = options.datalayer || null
|
|
11
39
|
this.properties = { _umap_options: {} }
|
|
12
|
-
|
|
40
|
+
|
|
13
41
|
if (options.geojson) {
|
|
14
42
|
this.populate(options.geojson)
|
|
15
|
-
geojson_id = options.geojson.id
|
|
16
43
|
}
|
|
17
44
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
this.id = geojson_id
|
|
45
|
+
if (id) {
|
|
46
|
+
this.id = id
|
|
21
47
|
} else {
|
|
22
|
-
|
|
48
|
+
let geojson_id
|
|
49
|
+
if (options.geojson) {
|
|
50
|
+
geojson_id = options.geojson.id
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Each feature needs an unique identifier
|
|
54
|
+
if (U.Utils.checkId(geojson_id)) {
|
|
55
|
+
this.id = geojson_id
|
|
56
|
+
} else {
|
|
57
|
+
this.id = U.Utils.generateId()
|
|
58
|
+
}
|
|
23
59
|
}
|
|
24
60
|
let isDirty = false
|
|
25
61
|
const self = this
|
|
@@ -98,6 +134,7 @@ U.FeatureMixin = {
|
|
|
98
134
|
this.view()
|
|
99
135
|
}
|
|
100
136
|
}
|
|
137
|
+
this._redraw()
|
|
101
138
|
},
|
|
102
139
|
|
|
103
140
|
openPopup: function () {
|
|
@@ -107,7 +144,7 @@ U.FeatureMixin = {
|
|
|
107
144
|
edit: function (e) {
|
|
108
145
|
if (!this.map.editEnabled || this.isReadOnly()) return
|
|
109
146
|
const container = L.DomUtil.create('div', 'umap-feature-container')
|
|
110
|
-
L.DomUtil.createTitle(container, L._('Feature properties'), this.getClassName())
|
|
147
|
+
L.DomUtil.createTitle(container, L._('Feature properties'), `icon-${this.getClassName()}`)
|
|
111
148
|
|
|
112
149
|
let builder = new U.FormBuilder(
|
|
113
150
|
this,
|
|
@@ -134,7 +171,6 @@ U.FeatureMixin = {
|
|
|
134
171
|
properties.unshift('properties.name')
|
|
135
172
|
builder = new U.FormBuilder(this, properties, {
|
|
136
173
|
id: 'umap-feature-properties',
|
|
137
|
-
callback: this._redraw, // In case we have dynamic options…
|
|
138
174
|
})
|
|
139
175
|
container.appendChild(builder.build())
|
|
140
176
|
this.appendEditFieldsets(container)
|
|
@@ -149,7 +185,7 @@ U.FeatureMixin = {
|
|
|
149
185
|
},
|
|
150
186
|
|
|
151
187
|
getAdvancedEditActions: function (container) {
|
|
152
|
-
|
|
188
|
+
L.DomUtil.createButton(
|
|
153
189
|
'button umap-delete',
|
|
154
190
|
container,
|
|
155
191
|
L._('Delete'),
|
|
@@ -165,7 +201,6 @@ U.FeatureMixin = {
|
|
|
165
201
|
const optionsFields = this.getShapeOptions()
|
|
166
202
|
let builder = new U.FormBuilder(this, optionsFields, {
|
|
167
203
|
id: 'umap-feature-shape-properties',
|
|
168
|
-
callback: this._redraw,
|
|
169
204
|
})
|
|
170
205
|
const shapeProperties = L.DomUtil.createFieldset(container, L._('Shape properties'))
|
|
171
206
|
shapeProperties.appendChild(builder.build())
|
|
@@ -173,7 +208,6 @@ U.FeatureMixin = {
|
|
|
173
208
|
const advancedOptions = this.getAdvancedOptions()
|
|
174
209
|
builder = new U.FormBuilder(this, advancedOptions, {
|
|
175
210
|
id: 'umap-feature-advanced-properties',
|
|
176
|
-
callback: this._redraw,
|
|
177
211
|
})
|
|
178
212
|
const advancedProperties = L.DomUtil.createFieldset(
|
|
179
213
|
container,
|
|
@@ -182,9 +216,7 @@ U.FeatureMixin = {
|
|
|
182
216
|
advancedProperties.appendChild(builder.build())
|
|
183
217
|
|
|
184
218
|
const interactionOptions = this.getInteractionOptions()
|
|
185
|
-
builder = new U.FormBuilder(this, interactionOptions
|
|
186
|
-
callback: this._redraw,
|
|
187
|
-
})
|
|
219
|
+
builder = new U.FormBuilder(this, interactionOptions)
|
|
188
220
|
const popupFieldset = L.DomUtil.createFieldset(
|
|
189
221
|
container,
|
|
190
222
|
L._('Interaction options')
|
|
@@ -240,13 +272,14 @@ U.FeatureMixin = {
|
|
|
240
272
|
}
|
|
241
273
|
return false
|
|
242
274
|
},
|
|
243
|
-
|
|
244
|
-
del: function () {
|
|
275
|
+
del: function (sync) {
|
|
245
276
|
this.isDirty = true
|
|
246
277
|
this.map.closePopup()
|
|
247
278
|
if (this.datalayer) {
|
|
248
279
|
this.datalayer.removeLayer(this)
|
|
249
280
|
this.disconnectFromDataLayer(this.datalayer)
|
|
281
|
+
|
|
282
|
+
if (sync !== false) this.syncDelete()
|
|
250
283
|
}
|
|
251
284
|
},
|
|
252
285
|
|
|
@@ -549,7 +582,10 @@ U.FeatureMixin = {
|
|
|
549
582
|
},
|
|
550
583
|
|
|
551
584
|
clone: function () {
|
|
552
|
-
const
|
|
585
|
+
const geoJSON = this.toGeoJSON()
|
|
586
|
+
delete geoJSON.id
|
|
587
|
+
delete geoJSON.properties.id
|
|
588
|
+
const layer = this.datalayer.geojsonToFeatures(geoJSON)
|
|
553
589
|
layer.isDirty = true
|
|
554
590
|
layer.edit()
|
|
555
591
|
return layer
|
|
@@ -602,9 +638,11 @@ U.Marker = L.Marker.extend({
|
|
|
602
638
|
function (e) {
|
|
603
639
|
this.isDirty = true
|
|
604
640
|
this.edit(e)
|
|
641
|
+
this.sync.update('geometry', this.getGeometry())
|
|
605
642
|
},
|
|
606
643
|
this
|
|
607
644
|
)
|
|
645
|
+
this.on('editable:drawing:commit', this.onCommit)
|
|
608
646
|
if (!this.isReadOnly()) this.on('mouseover', this._enableDragging)
|
|
609
647
|
this.on('mouseout', this._onMouseOut)
|
|
610
648
|
this._popupHandlersAdded = true // prevent Leaflet from binding event on bindPopup
|
|
@@ -726,14 +764,10 @@ U.Marker = L.Marker.extend({
|
|
|
726
764
|
const builder = new U.FormBuilder(this, coordinatesOptions, {
|
|
727
765
|
callback: function () {
|
|
728
766
|
if (!this._latlng.isValid()) {
|
|
729
|
-
|
|
730
|
-
content: L._('Invalid latitude or longitude'),
|
|
731
|
-
level: 'error',
|
|
732
|
-
})
|
|
767
|
+
U.Alert.error(L._('Invalid latitude or longitude'))
|
|
733
768
|
builder.resetField('_latlng.lat')
|
|
734
769
|
builder.resetField('_latlng.lng')
|
|
735
770
|
}
|
|
736
|
-
this._redraw()
|
|
737
771
|
this.zoomTo({ easing: false })
|
|
738
772
|
},
|
|
739
773
|
callbackContext: this,
|
|
@@ -878,14 +912,15 @@ U.PathMixin = {
|
|
|
878
912
|
|
|
879
913
|
_onMouseOver: function () {
|
|
880
914
|
if (this.map.measureTools && this.map.measureTools.enabled()) {
|
|
881
|
-
this.map.
|
|
915
|
+
this.map.tooltip.open({ content: this.getMeasure(), anchor: this })
|
|
882
916
|
} else if (this.map.editEnabled && !this.map.editedFeature) {
|
|
883
|
-
this.map.
|
|
917
|
+
this.map.tooltip.open({ content: L._('Click to edit'), anchor: this })
|
|
884
918
|
}
|
|
885
919
|
},
|
|
886
920
|
|
|
887
921
|
addInteractions: function () {
|
|
888
922
|
U.FeatureMixin.addInteractions.call(this)
|
|
923
|
+
this.on('editable:disable', this.onCommit)
|
|
889
924
|
this.on('mouseover', this._onMouseOver)
|
|
890
925
|
this.on('edit', this.makeDirty)
|
|
891
926
|
this.on('drag editable:drag', this._onDrag)
|
|
@@ -928,7 +963,7 @@ U.PathMixin = {
|
|
|
928
963
|
items.push({
|
|
929
964
|
text: L._('Display measure'),
|
|
930
965
|
callback: function () {
|
|
931
|
-
|
|
966
|
+
U.Alert.info(this.getMeasure())
|
|
932
967
|
},
|
|
933
968
|
context: this,
|
|
934
969
|
})
|
|
@@ -1086,6 +1121,9 @@ U.Polyline = L.Polyline.extend({
|
|
|
1086
1121
|
geojson.geometry.coordinates = [
|
|
1087
1122
|
U.Utils.flattenCoordinates(geojson.geometry.coordinates),
|
|
1088
1123
|
]
|
|
1124
|
+
|
|
1125
|
+
delete geojson.id // delete the copied id, a new one will be generated.
|
|
1126
|
+
|
|
1089
1127
|
const polygon = this.datalayer.geojsonToFeatures(geojson)
|
|
1090
1128
|
polygon.edit()
|
|
1091
1129
|
this.del()
|
|
@@ -1093,7 +1131,7 @@ U.Polyline = L.Polyline.extend({
|
|
|
1093
1131
|
|
|
1094
1132
|
getAdvancedEditActions: function (container) {
|
|
1095
1133
|
U.FeatureMixin.getAdvancedEditActions.call(this, container)
|
|
1096
|
-
|
|
1134
|
+
L.DomUtil.createButton(
|
|
1097
1135
|
'button umap-to-polygon',
|
|
1098
1136
|
container,
|
|
1099
1137
|
L._('Transform to polygon'),
|
|
@@ -1223,6 +1261,8 @@ U.Polygon = L.Polygon.extend({
|
|
|
1223
1261
|
|
|
1224
1262
|
toPolyline: function () {
|
|
1225
1263
|
const geojson = this.toGeoJSON()
|
|
1264
|
+
delete geojson.id
|
|
1265
|
+
delete geojson.properties.id
|
|
1226
1266
|
geojson.geometry.type = 'LineString'
|
|
1227
1267
|
geojson.geometry.coordinates = U.Utils.flattenCoordinates(
|
|
1228
1268
|
geojson.geometry.coordinates
|
|
@@ -78,7 +78,7 @@ L.FormBuilder.Element.include({
|
|
|
78
78
|
info,
|
|
79
79
|
'mouseover',
|
|
80
80
|
function () {
|
|
81
|
-
this.builder.map.
|
|
81
|
+
this.builder.map.tooltip.open({
|
|
82
82
|
anchor: info,
|
|
83
83
|
content: this.options.helpTooltip,
|
|
84
84
|
position: 'top',
|
|
@@ -340,15 +340,6 @@ L.FormBuilder.TextColorPicker = L.FormBuilder.ColorPicker.extend({
|
|
|
340
340
|
],
|
|
341
341
|
})
|
|
342
342
|
|
|
343
|
-
L.FormBuilder.ProxyTTLSelect = L.FormBuilder.Select.extend({
|
|
344
|
-
selectOptions: [
|
|
345
|
-
[undefined, L._('No cache')],
|
|
346
|
-
['300', L._('5 min')],
|
|
347
|
-
['3600', L._('1 hour')],
|
|
348
|
-
['86400', L._('1 day')],
|
|
349
|
-
],
|
|
350
|
-
})
|
|
351
|
-
|
|
352
343
|
L.FormBuilder.LayerTypeChooser = L.FormBuilder.Select.extend({
|
|
353
344
|
getOptions: function () {
|
|
354
345
|
const layer_classes = [
|
|
@@ -1067,7 +1058,7 @@ L.FormBuilder.ManageOwner = L.FormBuilder.Element.extend({
|
|
|
1067
1058
|
className: 'edit-owner',
|
|
1068
1059
|
on_select: L.bind(this.onSelect, this),
|
|
1069
1060
|
}
|
|
1070
|
-
this.autocomplete = new U.
|
|
1061
|
+
this.autocomplete = new U.AjaxAutocomplete(this.parentNode, options)
|
|
1071
1062
|
const owner = this.toHTML()
|
|
1072
1063
|
if (owner)
|
|
1073
1064
|
this.autocomplete.displaySelected({
|
|
@@ -1096,7 +1087,7 @@ L.FormBuilder.ManageEditors = L.FormBuilder.Element.extend({
|
|
|
1096
1087
|
on_select: L.bind(this.onSelect, this),
|
|
1097
1088
|
on_unselect: L.bind(this.onUnselect, this),
|
|
1098
1089
|
}
|
|
1099
|
-
this.autocomplete = new U.
|
|
1090
|
+
this.autocomplete = new U.AjaxAutocompleteMultiple(this.parentNode, options)
|
|
1100
1091
|
this._values = this.toHTML()
|
|
1101
1092
|
if (this._values)
|
|
1102
1093
|
for (let i = 0; i < this._values.length; i++)
|
|
@@ -1185,7 +1176,12 @@ U.FormBuilder = L.FormBuilder.extend({
|
|
|
1185
1176
|
setter: function (field, value) {
|
|
1186
1177
|
L.FormBuilder.prototype.setter.call(this, field, value)
|
|
1187
1178
|
this.obj.isDirty = true
|
|
1188
|
-
if ('render' in this.obj)
|
|
1179
|
+
if ('render' in this.obj) {
|
|
1180
|
+
this.obj.render([field], this)
|
|
1181
|
+
}
|
|
1182
|
+
if ('sync' in this.obj) {
|
|
1183
|
+
this.obj.sync.update(field, value)
|
|
1184
|
+
}
|
|
1189
1185
|
},
|
|
1190
1186
|
|
|
1191
1187
|
finish: function () {
|