umap-project 2.1.3__py3-none-any.whl → 2.2.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/context_processors.py +1 -0
- umap/locale/br/LC_MESSAGES/django.mo +0 -0
- umap/locale/en/LC_MESSAGES/django.po +32 -32
- umap/locale/hu/LC_MESSAGES/django.mo +0 -0
- umap/locale/it/LC_MESSAGES/django.mo +0 -0
- umap/locale/ms/LC_MESSAGES/django.mo +0 -0
- umap/migrations/0020_alter_tilelayer_url_template.py +19 -0
- umap/migrations/0021_remove_map_description.py +16 -0
- umap/models.py +8 -6
- umap/settings/base.py +1 -0
- umap/static/umap/base.css +29 -151
- umap/static/umap/content.css +7 -25
- umap/static/umap/css/icon.css +112 -0
- umap/static/umap/css/panel.css +140 -0
- umap/static/umap/img/16-white.svg +5 -1
- umap/static/umap/img/16.svg +7 -4
- umap/static/umap/img/24-white.svg +3 -1
- umap/static/umap/img/24.svg +3 -4
- umap/static/umap/img/source/16-white.svg +176 -940
- umap/static/umap/img/source/16.svg +8 -5
- umap/static/umap/img/source/24-white.svg +5 -3
- umap/static/umap/img/source/24.svg +6 -7
- umap/static/umap/js/modules/browser.js +82 -73
- umap/static/umap/js/modules/dompurify.js +12 -0
- umap/static/umap/js/modules/facets.js +148 -0
- umap/static/umap/js/modules/global.js +9 -1
- umap/static/umap/js/modules/i18n.js +7 -0
- umap/static/umap/js/modules/orderable.js +84 -0
- umap/static/umap/js/modules/panel.js +76 -0
- umap/static/umap/js/modules/request.js +0 -1
- umap/static/umap/js/modules/schema.js +324 -223
- umap/static/umap/js/modules/urls.js +1 -16
- umap/static/umap/js/modules/utils.js +340 -0
- umap/static/umap/js/umap.controls.js +183 -330
- umap/static/umap/js/umap.core.js +60 -364
- umap/static/umap/js/umap.datalayer.permissions.js +1 -1
- umap/static/umap/js/umap.features.js +60 -40
- umap/static/umap/js/umap.forms.js +111 -25
- umap/static/umap/js/umap.icon.js +11 -4
- umap/static/umap/js/umap.importer.js +24 -17
- umap/static/umap/js/umap.js +170 -145
- umap/static/umap/js/umap.layer.js +71 -40
- umap/static/umap/js/umap.permissions.js +9 -11
- umap/static/umap/js/umap.popup.js +10 -21
- umap/static/umap/js/umap.share.js +11 -8
- umap/static/umap/js/umap.tableeditor.js +4 -6
- umap/static/umap/js/umap.ui.js +0 -51
- umap/static/umap/locale/am_ET.js +242 -227
- umap/static/umap/locale/am_ET.json +18 -7
- umap/static/umap/locale/ar.js +242 -227
- umap/static/umap/locale/ar.json +18 -7
- umap/static/umap/locale/ast.js +242 -227
- umap/static/umap/locale/ast.json +18 -7
- umap/static/umap/locale/bg.js +242 -227
- umap/static/umap/locale/bg.json +18 -7
- umap/static/umap/locale/br.js +252 -237
- umap/static/umap/locale/br.json +22 -11
- umap/static/umap/locale/ca.js +242 -227
- umap/static/umap/locale/ca.json +18 -7
- umap/static/umap/locale/cs_CZ.js +242 -227
- umap/static/umap/locale/cs_CZ.json +18 -7
- umap/static/umap/locale/da.js +242 -227
- umap/static/umap/locale/da.json +18 -7
- umap/static/umap/locale/de.js +242 -227
- umap/static/umap/locale/de.json +18 -7
- umap/static/umap/locale/el.js +242 -227
- umap/static/umap/locale/el.json +18 -7
- umap/static/umap/locale/en.js +242 -234
- umap/static/umap/locale/en.json +19 -8
- umap/static/umap/locale/en_US.json +18 -7
- umap/static/umap/locale/es.js +242 -227
- umap/static/umap/locale/es.json +18 -7
- umap/static/umap/locale/et.js +242 -227
- umap/static/umap/locale/et.json +18 -7
- umap/static/umap/locale/eu.js +227 -199
- umap/static/umap/locale/eu.json +1 -1
- umap/static/umap/locale/fa_IR.js +242 -227
- umap/static/umap/locale/fa_IR.json +18 -7
- umap/static/umap/locale/fi.js +242 -227
- umap/static/umap/locale/fi.json +18 -7
- umap/static/umap/locale/fr.js +242 -234
- umap/static/umap/locale/fr.json +18 -7
- umap/static/umap/locale/gl.js +242 -227
- umap/static/umap/locale/gl.json +18 -7
- umap/static/umap/locale/he.js +242 -227
- umap/static/umap/locale/he.json +18 -7
- umap/static/umap/locale/hr.js +242 -227
- umap/static/umap/locale/hr.json +18 -7
- umap/static/umap/locale/hu.js +242 -234
- umap/static/umap/locale/hu.json +18 -7
- umap/static/umap/locale/id.js +242 -227
- umap/static/umap/locale/id.json +18 -7
- umap/static/umap/locale/is.js +242 -227
- umap/static/umap/locale/is.json +18 -7
- umap/static/umap/locale/it.js +242 -234
- umap/static/umap/locale/it.json +18 -7
- umap/static/umap/locale/ja.js +242 -227
- umap/static/umap/locale/ja.json +18 -7
- umap/static/umap/locale/ko.js +242 -227
- umap/static/umap/locale/ko.json +18 -7
- umap/static/umap/locale/lt.js +242 -227
- umap/static/umap/locale/lt.json +18 -7
- umap/static/umap/locale/ms.js +242 -234
- umap/static/umap/locale/ms.json +19 -8
- umap/static/umap/locale/nl.js +245 -230
- umap/static/umap/locale/nl.json +18 -7
- umap/static/umap/locale/no.js +242 -227
- umap/static/umap/locale/no.json +18 -7
- umap/static/umap/locale/pl.js +242 -227
- umap/static/umap/locale/pl.json +18 -7
- umap/static/umap/locale/pl_PL.json +18 -7
- umap/static/umap/locale/pt.js +242 -227
- umap/static/umap/locale/pt.json +18 -7
- umap/static/umap/locale/pt_BR.js +242 -227
- umap/static/umap/locale/pt_BR.json +18 -7
- umap/static/umap/locale/pt_PT.js +242 -227
- umap/static/umap/locale/pt_PT.json +18 -7
- umap/static/umap/locale/ro.js +242 -227
- umap/static/umap/locale/ro.json +18 -7
- umap/static/umap/locale/ru.js +242 -227
- umap/static/umap/locale/ru.json +18 -7
- umap/static/umap/locale/si.js +1 -1
- umap/static/umap/locale/si.json +1 -1
- umap/static/umap/locale/sk_SK.js +242 -227
- umap/static/umap/locale/sk_SK.json +18 -7
- umap/static/umap/locale/sl.js +242 -227
- umap/static/umap/locale/sl.json +18 -7
- umap/static/umap/locale/sr.js +242 -227
- umap/static/umap/locale/sr.json +18 -7
- umap/static/umap/locale/sv.js +242 -227
- umap/static/umap/locale/sv.json +18 -7
- umap/static/umap/locale/th_TH.js +242 -227
- umap/static/umap/locale/th_TH.json +18 -7
- umap/static/umap/locale/tr.js +242 -227
- umap/static/umap/locale/tr.json +18 -7
- umap/static/umap/locale/uk_UA.js +242 -227
- umap/static/umap/locale/uk_UA.json +18 -7
- umap/static/umap/locale/vi.js +242 -227
- umap/static/umap/locale/vi.json +18 -7
- umap/static/umap/locale/vi_VN.json +18 -7
- umap/static/umap/locale/zh.js +242 -227
- umap/static/umap/locale/zh.json +18 -7
- umap/static/umap/locale/zh_CN.json +18 -7
- umap/static/umap/locale/zh_TW.Big5.json +18 -7
- umap/static/umap/locale/zh_TW.js +242 -234
- umap/static/umap/locale/zh_TW.json +18 -7
- umap/static/umap/map.css +114 -265
- umap/static/umap/test/DataLayer.js +463 -0
- umap/static/umap/test/Feature.js +0 -226
- umap/static/umap/test/TableEditor.js +104 -0
- umap/static/umap/test/Util.js +0 -521
- umap/static/umap/test/index.html +0 -1
- umap/static/umap/unittests/URLs.js +1 -1
- umap/static/umap/unittests/utils.js +610 -0
- umap/static/umap/vars.css +9 -0
- umap/static/umap/vendors/dompurify/purify.es.mjs +1525 -0
- umap/static/umap/vendors/iconlayers/iconLayers.js +1 -1
- umap/templates/umap/css.html +2 -0
- umap/templates/umap/js.html +0 -1
- umap/templates/umap/map_detail.html +4 -0
- umap/templates/umap/map_table.html +12 -10
- umap/templatetags/umap_tags.py +5 -0
- umap/tests/integration/conftest.py +12 -1
- umap/tests/integration/test_anonymous_owned_map.py +6 -5
- umap/tests/integration/test_browser.py +12 -25
- umap/tests/integration/test_choropleth.py +1 -1
- umap/tests/integration/test_dashboard.py +10 -0
- umap/tests/integration/test_datalayer.py +8 -6
- umap/tests/integration/test_edit_datalayer.py +24 -19
- umap/tests/integration/test_edit_map.py +182 -2
- umap/tests/integration/test_edit_marker.py +120 -0
- umap/tests/integration/test_edit_polygon.py +122 -0
- umap/tests/integration/test_facets_browser.py +104 -14
- umap/tests/integration/test_import.py +70 -20
- umap/tests/integration/test_map.py +19 -17
- umap/tests/integration/test_map_list.py +28 -0
- umap/tests/integration/test_owned_map.py +10 -10
- umap/tests/integration/test_picto.py +5 -5
- umap/tests/integration/test_querystring.py +9 -15
- umap/tests/integration/test_slideshow.py +0 -5
- umap/tests/integration/test_statics.py +3 -2
- umap/tests/integration/test_tableeditor.py +1 -5
- umap/tests/integration/test_view_marker.py +64 -0
- umap/tests/integration/test_view_polygon.py +59 -0
- umap/tests/integration/test_view_polyline.py +51 -0
- umap/tests/test_map_views.py +13 -0
- {umap_project-2.1.3.dist-info → umap_project-2.2.0b0.dist-info}/METADATA +8 -8
- {umap_project-2.1.3.dist-info → umap_project-2.2.0b0.dist-info}/RECORD +194 -178
- umap/static/umap/vendors/dompurify/purify.min.js +0 -3
- umap/static/umap/vendors/dompurify/purify.min.js.map +0 -1
- /umap/tests/integration/{test_polygon.py → test_draw_polygon.py} +0 -0
- /umap/tests/integration/{test_polyline.py → test_draw_polyline.py} +0 -0
- {umap_project-2.1.3.dist-info → umap_project-2.2.0b0.dist-info}/WHEEL +0 -0
- {umap_project-2.1.3.dist-info → umap_project-2.2.0b0.dist-info}/entry_points.txt +0 -0
- {umap_project-2.1.3.dist-info → umap_project-2.2.0b0.dist-info}/licenses/LICENSE +0 -0
|
@@ -59,15 +59,14 @@ U.FeatureMixin = {
|
|
|
59
59
|
getPermalink: function () {
|
|
60
60
|
const slug = this.getSlug()
|
|
61
61
|
if (slug)
|
|
62
|
-
return `${
|
|
62
|
+
return `${U.Utils.getBaseUrl()}?${U.Utils.buildQueryString({ feature: slug })}${
|
|
63
63
|
window.location.hash
|
|
64
64
|
}`
|
|
65
65
|
},
|
|
66
66
|
|
|
67
67
|
view: function (e) {
|
|
68
|
-
|
|
69
|
-
const
|
|
70
|
-
target = this.getOption('outlinkTarget')
|
|
68
|
+
const outlink = this.getOption('outlink')
|
|
69
|
+
const target = this.getOption('outlinkTarget')
|
|
71
70
|
if (outlink) {
|
|
72
71
|
switch (target) {
|
|
73
72
|
case 'self':
|
|
@@ -77,31 +76,38 @@ U.FeatureMixin = {
|
|
|
77
76
|
window.top.location = outlink
|
|
78
77
|
break
|
|
79
78
|
default:
|
|
80
|
-
|
|
79
|
+
window.open(this.properties._umap_options.outlink)
|
|
81
80
|
}
|
|
82
81
|
return
|
|
83
82
|
}
|
|
84
83
|
// TODO deal with an event instead?
|
|
85
|
-
if (this.map.slideshow)
|
|
84
|
+
if (this.map.slideshow) {
|
|
85
|
+
this.map.slideshow.current = this
|
|
86
|
+
}
|
|
86
87
|
this.map.currentFeature = this
|
|
87
88
|
this.attachPopup()
|
|
88
|
-
this.openPopup(
|
|
89
|
+
this.openPopup(e?.latlng || this.getCenter())
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
render: function (fields) {
|
|
93
|
+
const impactData = fields.some((field) => {
|
|
94
|
+
return field.startsWith('properties.')
|
|
95
|
+
})
|
|
96
|
+
if (impactData) {
|
|
97
|
+
if (this.map.currentFeature === this) {
|
|
98
|
+
this.view()
|
|
99
|
+
}
|
|
100
|
+
}
|
|
89
101
|
},
|
|
90
102
|
|
|
91
103
|
openPopup: function () {
|
|
92
|
-
if (this.map.editEnabled) return
|
|
93
104
|
this.parentClass.prototype.openPopup.apply(this, arguments)
|
|
94
105
|
},
|
|
95
106
|
|
|
96
107
|
edit: function (e) {
|
|
97
108
|
if (!this.map.editEnabled || this.isReadOnly()) return
|
|
98
109
|
const container = L.DomUtil.create('div', 'umap-feature-container')
|
|
99
|
-
L.DomUtil.
|
|
100
|
-
'h3',
|
|
101
|
-
`umap-feature-properties ${this.getClassName()}`,
|
|
102
|
-
container,
|
|
103
|
-
L._('Feature properties')
|
|
104
|
-
)
|
|
110
|
+
L.DomUtil.createTitle(container, L._('Feature properties'), this.getClassName())
|
|
105
111
|
|
|
106
112
|
let builder = new U.FormBuilder(
|
|
107
113
|
this,
|
|
@@ -131,13 +137,13 @@ U.FeatureMixin = {
|
|
|
131
137
|
callback: this._redraw, // In case we have dynamic options…
|
|
132
138
|
})
|
|
133
139
|
container.appendChild(builder.build())
|
|
134
|
-
this.map.ui.once('panel:ready', () => {
|
|
135
|
-
builder.helpers['properties.name'].input.focus()
|
|
136
|
-
})
|
|
137
140
|
this.appendEditFieldsets(container)
|
|
138
141
|
const advancedActions = L.DomUtil.createFieldset(container, L._('Advanced actions'))
|
|
139
142
|
this.getAdvancedEditActions(advancedActions)
|
|
140
|
-
this.map.
|
|
143
|
+
const onLoad = this.map.editPanel.open({ content: container })
|
|
144
|
+
onLoad.then(() => {
|
|
145
|
+
builder.helpers['properties.name'].input.focus()
|
|
146
|
+
})
|
|
141
147
|
this.map.editedFeature = this
|
|
142
148
|
if (!this.isOnScreen()) this.zoomTo(e)
|
|
143
149
|
},
|
|
@@ -149,7 +155,7 @@ U.FeatureMixin = {
|
|
|
149
155
|
L._('Delete'),
|
|
150
156
|
function (e) {
|
|
151
157
|
L.DomEvent.stop(e)
|
|
152
|
-
if (this.confirmDelete()) this.map.
|
|
158
|
+
if (this.confirmDelete()) this.map.editPanel.close()
|
|
153
159
|
},
|
|
154
160
|
this
|
|
155
161
|
)
|
|
@@ -204,7 +210,8 @@ U.FeatureMixin = {
|
|
|
204
210
|
if (fallback === undefined) fallback = this.datalayer.options.name
|
|
205
211
|
const key = this.getOption('labelKey') || 'name'
|
|
206
212
|
// Variables mode.
|
|
207
|
-
if (
|
|
213
|
+
if (U.Utils.hasVar(key))
|
|
214
|
+
return U.Utils.greedyTemplate(key, this.extendedProperties())
|
|
208
215
|
// Simple mode.
|
|
209
216
|
return this.properties[key] || this.properties.title || fallback
|
|
210
217
|
},
|
|
@@ -291,7 +298,7 @@ U.FeatureMixin = {
|
|
|
291
298
|
let value = fallback
|
|
292
299
|
if (typeof this.staticOptions[option] !== 'undefined') {
|
|
293
300
|
value = this.staticOptions[option]
|
|
294
|
-
} else if (
|
|
301
|
+
} else if (U.Utils.usableOption(this.properties._umap_options, option)) {
|
|
295
302
|
value = this.properties._umap_options[option]
|
|
296
303
|
} else if (this.datalayer) {
|
|
297
304
|
value = this.datalayer.getOption(option, this)
|
|
@@ -304,23 +311,22 @@ U.FeatureMixin = {
|
|
|
304
311
|
getDynamicOption: function (option, fallback) {
|
|
305
312
|
let value = this.getOption(option, fallback)
|
|
306
313
|
// There is a variable inside.
|
|
307
|
-
if (
|
|
308
|
-
value =
|
|
309
|
-
if (
|
|
314
|
+
if (U.Utils.hasVar(value)) {
|
|
315
|
+
value = U.Utils.greedyTemplate(value, this.properties, true)
|
|
316
|
+
if (U.Utils.hasVar(value)) value = this.map.getDefaultOption(option)
|
|
310
317
|
}
|
|
311
318
|
return value
|
|
312
319
|
},
|
|
313
320
|
|
|
314
|
-
zoomTo: function (
|
|
315
|
-
|
|
316
|
-
|
|
321
|
+
zoomTo: function ({ easing, latlng, callback } = {}) {
|
|
322
|
+
if (easing === undefined) easing = this.map.getOption('easing')
|
|
323
|
+
if (callback) this.map.once('moveend', callback.call(this))
|
|
317
324
|
if (easing) {
|
|
318
325
|
this.map.flyTo(this.getCenter(), this.getBestZoom())
|
|
319
326
|
} else {
|
|
320
|
-
|
|
327
|
+
latlng = latlng || this.getCenter()
|
|
321
328
|
this.map.setView(latlng, this.getBestZoom() || this.map.getZoom())
|
|
322
329
|
}
|
|
323
|
-
if (e.callback) e.callback.call(this)
|
|
324
330
|
},
|
|
325
331
|
|
|
326
332
|
getBestZoom: function () {
|
|
@@ -466,7 +472,7 @@ U.FeatureMixin = {
|
|
|
466
472
|
this.parentClass.prototype.onRemove.call(this, map)
|
|
467
473
|
if (this.map.editedFeature === this) {
|
|
468
474
|
this.endEdit()
|
|
469
|
-
this.map.
|
|
475
|
+
this.map.editPanel.close()
|
|
470
476
|
}
|
|
471
477
|
},
|
|
472
478
|
|
|
@@ -485,7 +491,7 @@ U.FeatureMixin = {
|
|
|
485
491
|
options.permanent = showLabel === true
|
|
486
492
|
this.unbindTooltip()
|
|
487
493
|
if ((showLabel === true || showLabel === null) && displayName)
|
|
488
|
-
this.bindTooltip(
|
|
494
|
+
this.bindTooltip(U.Utils.escapeHTML(displayName), options)
|
|
489
495
|
},
|
|
490
496
|
|
|
491
497
|
matchFilter: function (filter, keys) {
|
|
@@ -498,11 +504,24 @@ U.FeatureMixin = {
|
|
|
498
504
|
},
|
|
499
505
|
|
|
500
506
|
matchFacets: function () {
|
|
501
|
-
const
|
|
502
|
-
for (
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
507
|
+
const selected = this.map.facets.selected
|
|
508
|
+
for (let [name, { type, min, max, choices }] of Object.entries(selected)) {
|
|
509
|
+
let value = this.properties[name]
|
|
510
|
+
let parser = this.map.facets.getParser(type)
|
|
511
|
+
value = parser(value)
|
|
512
|
+
switch (type) {
|
|
513
|
+
case 'date':
|
|
514
|
+
case 'datetime':
|
|
515
|
+
case 'number':
|
|
516
|
+
min = parser(min)
|
|
517
|
+
max = parser(max)
|
|
518
|
+
if (!isNaN(min) && !isNaN(value) && min > value) return false
|
|
519
|
+
if (!isNaN(max) && !isNaN(value) && max < value) return false
|
|
520
|
+
break
|
|
521
|
+
default:
|
|
522
|
+
value = value || L._('<empty value>')
|
|
523
|
+
if (choices?.length && !choices.includes(value)) return false
|
|
524
|
+
break
|
|
506
525
|
}
|
|
507
526
|
}
|
|
508
527
|
return true
|
|
@@ -533,7 +552,8 @@ U.FeatureMixin = {
|
|
|
533
552
|
extendedProperties: function () {
|
|
534
553
|
// Include context properties
|
|
535
554
|
properties = this.map.getGeoContext()
|
|
536
|
-
|
|
555
|
+
const locale = L.getLocale()
|
|
556
|
+
if (locale) properties.locale = locale
|
|
537
557
|
if (L.lang) properties.lang = L.lang
|
|
538
558
|
properties.rank = this.getRank() + 1
|
|
539
559
|
if (this.hasGeom()) {
|
|
@@ -757,7 +777,7 @@ U.PathMixin = {
|
|
|
757
777
|
if (this.map.editEnabled) {
|
|
758
778
|
if (this.editEnabled()) {
|
|
759
779
|
this.endEdit()
|
|
760
|
-
this.map.
|
|
780
|
+
this.map.editPanel.close()
|
|
761
781
|
} else {
|
|
762
782
|
this.edit(e)
|
|
763
783
|
}
|
|
@@ -1058,7 +1078,7 @@ U.Polyline = L.Polyline.extend({
|
|
|
1058
1078
|
const geojson = this.toGeoJSON()
|
|
1059
1079
|
geojson.geometry.type = 'Polygon'
|
|
1060
1080
|
geojson.geometry.coordinates = [
|
|
1061
|
-
|
|
1081
|
+
U.Utils.flattenCoordinates(geojson.geometry.coordinates),
|
|
1062
1082
|
]
|
|
1063
1083
|
const polygon = this.datalayer.geojsonToFeatures(geojson)
|
|
1064
1084
|
polygon.edit()
|
|
@@ -1198,7 +1218,7 @@ U.Polygon = L.Polygon.extend({
|
|
|
1198
1218
|
toPolyline: function () {
|
|
1199
1219
|
const geojson = this.toGeoJSON()
|
|
1200
1220
|
geojson.geometry.type = 'LineString'
|
|
1201
|
-
geojson.geometry.coordinates =
|
|
1221
|
+
geojson.geometry.coordinates = U.Utils.flattenCoordinates(
|
|
1202
1222
|
geojson.geometry.coordinates
|
|
1203
1223
|
)
|
|
1204
1224
|
const polyline = this.datalayer.geojsonToFeatures(geojson)
|
|
@@ -492,8 +492,8 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
|
|
492
492
|
this.buildTabs()
|
|
493
493
|
const value = this.value()
|
|
494
494
|
if (U.Icon.RECENT.length) this.showRecentTab()
|
|
495
|
-
else if (!value ||
|
|
496
|
-
else if (
|
|
495
|
+
else if (!value || U.Utils.isPath(value)) this.showSymbolsTab()
|
|
496
|
+
else if (U.Utils.isRemoteUrl(value) || U.Utils.isDataImage(value)) this.showURLTab()
|
|
497
497
|
else this.showCharsTab()
|
|
498
498
|
const closeButton = L.DomUtil.createButton(
|
|
499
499
|
'button action-button',
|
|
@@ -567,7 +567,7 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
|
|
567
567
|
updatePreview: function () {
|
|
568
568
|
this.buttons.innerHTML = ''
|
|
569
569
|
if (this.isDefault()) return
|
|
570
|
-
if (!
|
|
570
|
+
if (!U.Utils.hasVar(this.value())) {
|
|
571
571
|
// Do not try to render URL with variables
|
|
572
572
|
const box = L.DomUtil.create('div', 'umap-pictogram-choice', this.buttons)
|
|
573
573
|
L.DomEvent.on(box, 'click', this.onDefine, this)
|
|
@@ -585,11 +585,11 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
|
|
585
585
|
addIconPreview: function (pictogram, parent) {
|
|
586
586
|
const baseClass = 'umap-pictogram-choice',
|
|
587
587
|
value = pictogram.src,
|
|
588
|
-
search =
|
|
588
|
+
search = U.Utils.normalize(this.searchInput.value),
|
|
589
589
|
title = pictogram.attribution
|
|
590
590
|
? `${pictogram.name} — © ${pictogram.attribution}`
|
|
591
591
|
: pictogram.name || pictogram.src
|
|
592
|
-
if (search &&
|
|
592
|
+
if (search && U.Utils.normalize(title).indexOf(search) === -1) return
|
|
593
593
|
const className = value === this.value() ? `${baseClass} selected` : baseClass,
|
|
594
594
|
container = L.DomUtil.create('div', className, parent)
|
|
595
595
|
U.Icon.makeIconElement(value, container)
|
|
@@ -637,7 +637,7 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
|
|
637
637
|
categories[category].push(props)
|
|
638
638
|
}
|
|
639
639
|
const sorted = Object.entries(categories).toSorted(([a], [b]) =>
|
|
640
|
-
|
|
640
|
+
U.Utils.naturalSort(a, b, L.lang)
|
|
641
641
|
)
|
|
642
642
|
for (let [name, items] of sorted) {
|
|
643
643
|
this.addCategory(items, name)
|
|
@@ -688,7 +688,7 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
|
|
688
688
|
showURLTab: function () {
|
|
689
689
|
this.openTab('url')
|
|
690
690
|
const value =
|
|
691
|
-
|
|
691
|
+
U.Utils.isRemoteUrl(this.value()) || U.Utils.isDataImage(this.value())
|
|
692
692
|
? this.value()
|
|
693
693
|
: null
|
|
694
694
|
const input = this.buildInput(this.body, value)
|
|
@@ -744,34 +744,122 @@ L.FormBuilder.Switch = L.FormBuilder.CheckBox.extend({
|
|
|
744
744
|
},
|
|
745
745
|
})
|
|
746
746
|
|
|
747
|
-
L.FormBuilder.
|
|
747
|
+
L.FormBuilder.FacetSearchChoices = L.FormBuilder.Element.extend({
|
|
748
748
|
build: function () {
|
|
749
|
-
this.container = L.DomUtil.create('
|
|
749
|
+
this.container = L.DomUtil.create('fieldset', 'umap-facet', this.parentNode)
|
|
750
|
+
this.container.appendChild(this.label)
|
|
750
751
|
this.ul = L.DomUtil.create('ul', '', this.container)
|
|
751
|
-
|
|
752
|
+
this.type = this.options.criteria['type']
|
|
753
|
+
|
|
754
|
+
const choices = this.options.criteria['choices']
|
|
752
755
|
choices.sort()
|
|
753
756
|
choices.forEach((value) => this.buildLi(value))
|
|
754
757
|
},
|
|
755
758
|
|
|
756
759
|
buildLabel: function () {
|
|
757
|
-
this.label = L.DomUtil.
|
|
760
|
+
this.label = L.DomUtil.element('legend', {textContent: this.options.label})
|
|
758
761
|
},
|
|
759
762
|
|
|
760
763
|
buildLi: function (value) {
|
|
761
|
-
const property_li = L.DomUtil.create('li', '', this.ul)
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
input.
|
|
764
|
+
const property_li = L.DomUtil.create('li', '', this.ul)
|
|
765
|
+
const label = L.DomUtil.add('label', '', property_li)
|
|
766
|
+
const input = L.DomUtil.create('input', '', label)
|
|
767
|
+
L.DomUtil.add('span', '', label, value)
|
|
768
|
+
|
|
769
|
+
input.type = this.type
|
|
770
|
+
input.name = `${this.type}_${this.name}`
|
|
771
|
+
input.checked = this.get()['choices'].includes(value)
|
|
767
772
|
input.dataset.value = value
|
|
768
|
-
|
|
769
|
-
label.innerHTML = value
|
|
773
|
+
|
|
770
774
|
L.DomEvent.on(input, 'change', (e) => this.sync())
|
|
771
775
|
},
|
|
772
776
|
|
|
773
777
|
toJS: function () {
|
|
774
|
-
return
|
|
778
|
+
return {
|
|
779
|
+
type: this.type,
|
|
780
|
+
choices: [...this.ul.querySelectorAll('input:checked')].map(
|
|
781
|
+
(i) => i.dataset.value
|
|
782
|
+
),
|
|
783
|
+
}
|
|
784
|
+
},
|
|
785
|
+
})
|
|
786
|
+
|
|
787
|
+
L.FormBuilder.MinMaxBase = L.FormBuilder.Element.extend({
|
|
788
|
+
getInputType: function (type) {
|
|
789
|
+
return type
|
|
790
|
+
},
|
|
791
|
+
|
|
792
|
+
getLabels: function () {
|
|
793
|
+
return [L._('Min'), L._('Max')]
|
|
794
|
+
},
|
|
795
|
+
|
|
796
|
+
castValue: function (value) {
|
|
797
|
+
return value.valueOf()
|
|
798
|
+
},
|
|
799
|
+
|
|
800
|
+
build: function () {
|
|
801
|
+
this.container = L.DomUtil.create('fieldset', 'umap-facet', this.parentNode)
|
|
802
|
+
this.container.appendChild(this.label)
|
|
803
|
+
const {min, max, type} = this.options.criteria
|
|
804
|
+
this.type = type
|
|
805
|
+
this.inputType = this.getInputType(this.type)
|
|
806
|
+
|
|
807
|
+
const [minLabel, maxLabel] = this.getLabels()
|
|
808
|
+
|
|
809
|
+
this.minLabel = L.DomUtil.create('label', '', this.container)
|
|
810
|
+
this.minLabel.innerHTML = minLabel
|
|
811
|
+
|
|
812
|
+
this.minInput = L.DomUtil.create('input', '', this.minLabel)
|
|
813
|
+
this.minInput.type = this.inputType
|
|
814
|
+
this.minInput.step = 'any'
|
|
815
|
+
if (min != null) {
|
|
816
|
+
this.minInput.valueAsNumber = this.castValue(min)
|
|
817
|
+
this.minInput.dataset.value = min
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
|
|
821
|
+
this.maxLabel = L.DomUtil.create('label', '', this.container)
|
|
822
|
+
this.maxLabel.innerHTML = maxLabel
|
|
823
|
+
|
|
824
|
+
this.maxInput = L.DomUtil.create('input', '', this.maxLabel)
|
|
825
|
+
this.maxInput.type = this.inputType
|
|
826
|
+
this.maxInput.step = 'any'
|
|
827
|
+
if (max != null) {
|
|
828
|
+
this.maxInput.valueAsNumber = this.castValue(max)
|
|
829
|
+
this.maxInput.dataset.value = max
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
L.DomEvent.on(this.minInput, 'change', (e) => this.sync())
|
|
833
|
+
L.DomEvent.on(this.maxInput, 'change', (e) => this.sync())
|
|
834
|
+
},
|
|
835
|
+
|
|
836
|
+
buildLabel: function () {
|
|
837
|
+
this.label = L.DomUtil.element('legend', {textContent: this.options.label})
|
|
838
|
+
},
|
|
839
|
+
|
|
840
|
+
toJS: function () {
|
|
841
|
+
return {
|
|
842
|
+
type: this.type,
|
|
843
|
+
min: this.minInput.value,
|
|
844
|
+
max: this.maxInput.value,
|
|
845
|
+
}
|
|
846
|
+
},
|
|
847
|
+
})
|
|
848
|
+
|
|
849
|
+
L.FormBuilder.FacetSearchNumber = L.FormBuilder.MinMaxBase.extend({})
|
|
850
|
+
|
|
851
|
+
L.FormBuilder.FacetSearchDate = L.FormBuilder.MinMaxBase.extend({
|
|
852
|
+
castValue: function (value) {
|
|
853
|
+
return value.valueOf() - value.getTimezoneOffset() * 60000
|
|
854
|
+
},
|
|
855
|
+
getLabels: function () {
|
|
856
|
+
return [L._('From'), L._('Until')]
|
|
857
|
+
},
|
|
858
|
+
})
|
|
859
|
+
|
|
860
|
+
L.FormBuilder.FacetSearchDateTime = L.FormBuilder.FacetSearchDate.extend({
|
|
861
|
+
getInputType: function (type) {
|
|
862
|
+
return 'datetime-local'
|
|
775
863
|
},
|
|
776
864
|
})
|
|
777
865
|
|
|
@@ -1009,9 +1097,6 @@ U.FormBuilder = L.FormBuilder.extend({
|
|
|
1009
1097
|
case 'iconUrl':
|
|
1010
1098
|
schema.handler = 'IconUrl'
|
|
1011
1099
|
break
|
|
1012
|
-
case 'datalayersControl':
|
|
1013
|
-
schema.handler = 'DataLayersControl'
|
|
1014
|
-
break
|
|
1015
1100
|
case 'licence':
|
|
1016
1101
|
schema.handler = 'LicenceChooser'
|
|
1017
1102
|
break
|
|
@@ -1032,10 +1117,11 @@ U.FormBuilder = L.FormBuilder.extend({
|
|
|
1032
1117
|
|
|
1033
1118
|
setter: function (field, value) {
|
|
1034
1119
|
L.FormBuilder.prototype.setter.call(this, field, value)
|
|
1035
|
-
|
|
1120
|
+
this.obj.isDirty = true
|
|
1121
|
+
if ('render' in this.obj) this.obj.render([field], this)
|
|
1036
1122
|
},
|
|
1037
1123
|
|
|
1038
1124
|
finish: function () {
|
|
1039
|
-
this.map.
|
|
1125
|
+
this.map.editPanel.close()
|
|
1040
1126
|
},
|
|
1041
1127
|
})
|
umap/static/umap/js/umap.icon.js
CHANGED
|
@@ -18,7 +18,7 @@ U.Icon = L.DivIcon.extend({
|
|
|
18
18
|
},
|
|
19
19
|
|
|
20
20
|
_setRecent: function (url) {
|
|
21
|
-
if (
|
|
21
|
+
if (U.Utils.hasVar(url)) return
|
|
22
22
|
if (url === U.SCHEMA.iconUrl.default) return
|
|
23
23
|
if (U.Icon.RECENT.indexOf(url) === -1) {
|
|
24
24
|
U.Icon.RECENT.push(url)
|
|
@@ -50,7 +50,10 @@ U.Icon = L.DivIcon.extend({
|
|
|
50
50
|
},
|
|
51
51
|
|
|
52
52
|
formatUrl: function (url, feature) {
|
|
53
|
-
return
|
|
53
|
+
return U.Utils.greedyTemplate(
|
|
54
|
+
url || '',
|
|
55
|
+
feature ? feature.extendedProperties() : {}
|
|
56
|
+
)
|
|
54
57
|
},
|
|
55
58
|
|
|
56
59
|
onAdd: function () {},
|
|
@@ -206,7 +209,7 @@ U.Icon.Cluster = L.DivIcon.extend({
|
|
|
206
209
|
})
|
|
207
210
|
|
|
208
211
|
U.Icon.isImg = function (src) {
|
|
209
|
-
return
|
|
212
|
+
return U.Utils.isPath(src) || U.Utils.isRemoteUrl(src) || U.Utils.isDataImage(src)
|
|
210
213
|
}
|
|
211
214
|
|
|
212
215
|
U.Icon.makeIconElement = function (src, parent) {
|
|
@@ -236,7 +239,11 @@ U.Icon.setIconContrast = function (icon, parent, src, bgcolor) {
|
|
|
236
239
|
if (L.DomUtil.contrastedColor(parent, bgcolor)) {
|
|
237
240
|
// Decide whether to switch svg to white or not, but do it
|
|
238
241
|
// only for internal SVG, as invert could do weird things
|
|
239
|
-
if (
|
|
242
|
+
if (
|
|
243
|
+
U.Utils.isPath(src) &&
|
|
244
|
+
src.endsWith('.svg') &&
|
|
245
|
+
src !== U.SCHEMA.iconUrl.default
|
|
246
|
+
) {
|
|
240
247
|
// Must be called after icon container is added to the DOM
|
|
241
248
|
// An image
|
|
242
249
|
icon.style.filter = 'invert(1)'
|
|
@@ -7,7 +7,11 @@ U.Importer = L.Class.extend({
|
|
|
7
7
|
|
|
8
8
|
build: function () {
|
|
9
9
|
this.container = L.DomUtil.create('div', 'umap-upload')
|
|
10
|
-
this.title = L.DomUtil.
|
|
10
|
+
this.title = L.DomUtil.createTitle(
|
|
11
|
+
this.container,
|
|
12
|
+
L._('Import data'),
|
|
13
|
+
'icon-upload'
|
|
14
|
+
)
|
|
11
15
|
this.presetBox = L.DomUtil.create('div', 'formbox', this.container)
|
|
12
16
|
this.presetSelect = L.DomUtil.create('select', '', this.presetBox)
|
|
13
17
|
this.fileBox = L.DomUtil.create('div', 'formbox', this.container)
|
|
@@ -16,7 +20,6 @@ U.Importer = L.Class.extend({
|
|
|
16
20
|
{ type: 'file', multiple: 'multiple', autofocus: true },
|
|
17
21
|
this.fileBox
|
|
18
22
|
)
|
|
19
|
-
this.map.ui.once('panel:closed', () => (this.fileInput.value = null))
|
|
20
23
|
this.urlInput = L.DomUtil.element(
|
|
21
24
|
'input',
|
|
22
25
|
{ type: 'text', placeholder: L._('Provide an URL here') },
|
|
@@ -61,19 +64,6 @@ U.Importer = L.Class.extend({
|
|
|
61
64
|
{ type: 'checkbox', name: 'clear', id: 'datalayer-clear-check' },
|
|
62
65
|
this.clearLabel
|
|
63
66
|
)
|
|
64
|
-
let option
|
|
65
|
-
this.map.eachDataLayerReverse((datalayer) => {
|
|
66
|
-
if (datalayer.isLoaded() && !datalayer.isRemoteLayer()) {
|
|
67
|
-
const id = L.stamp(datalayer)
|
|
68
|
-
option = L.DomUtil.add('option', '', this.layerInput, datalayer.options.name)
|
|
69
|
-
option.value = id
|
|
70
|
-
}
|
|
71
|
-
})
|
|
72
|
-
L.DomUtil.element(
|
|
73
|
-
'option',
|
|
74
|
-
{ value: '', textContent: L._('Import in a new layer') },
|
|
75
|
-
this.layerInput
|
|
76
|
-
)
|
|
77
67
|
L.DomUtil.element(
|
|
78
68
|
'option',
|
|
79
69
|
{ value: '', textContent: L._('Choose the data format') },
|
|
@@ -102,7 +92,7 @@ U.Importer = L.Class.extend({
|
|
|
102
92
|
let type = '',
|
|
103
93
|
newType
|
|
104
94
|
for (let i = 0; i < e.target.files.length; i++) {
|
|
105
|
-
newType =
|
|
95
|
+
newType = U.Utils.detectFileType(e.target.files[i])
|
|
106
96
|
if (!type && newType) type = newType
|
|
107
97
|
if (type && newType !== type) {
|
|
108
98
|
type = ''
|
|
@@ -117,7 +107,24 @@ U.Importer = L.Class.extend({
|
|
|
117
107
|
|
|
118
108
|
open: function () {
|
|
119
109
|
if (!this.container) this.build()
|
|
120
|
-
this.map.
|
|
110
|
+
const onLoad = this.map.editPanel.open({ content: this.container })
|
|
111
|
+
onLoad.then(() => {
|
|
112
|
+
this.fileInput.value = null
|
|
113
|
+
this.layerInput.innerHTML = ''
|
|
114
|
+
let option
|
|
115
|
+
this.map.eachDataLayerReverse((datalayer) => {
|
|
116
|
+
if (datalayer.isLoaded() && !datalayer.isRemoteLayer()) {
|
|
117
|
+
const id = L.stamp(datalayer)
|
|
118
|
+
option = L.DomUtil.add('option', '', this.layerInput, datalayer.options.name)
|
|
119
|
+
option.value = id
|
|
120
|
+
}
|
|
121
|
+
})
|
|
122
|
+
L.DomUtil.element(
|
|
123
|
+
'option',
|
|
124
|
+
{ value: '', textContent: L._('Import in a new layer') },
|
|
125
|
+
this.layerInput
|
|
126
|
+
)
|
|
127
|
+
})
|
|
121
128
|
},
|
|
122
129
|
|
|
123
130
|
openFiles: function () {
|