umap-project 3.4.0b3__py3-none-any.whl → 3.6.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.
- umap/__init__.py +1 -1
- umap/locale/br/LC_MESSAGES/django.mo +0 -0
- umap/locale/br/LC_MESSAGES/django.po +71 -57
- umap/locale/da/LC_MESSAGES/django.mo +0 -0
- umap/locale/da/LC_MESSAGES/django.po +18 -14
- umap/locale/de/LC_MESSAGES/django.mo +0 -0
- umap/locale/de/LC_MESSAGES/django.po +20 -16
- umap/locale/en/LC_MESSAGES/django.po +18 -14
- umap/locale/es/LC_MESSAGES/django.mo +0 -0
- umap/locale/es/LC_MESSAGES/django.po +20 -16
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +18 -14
- umap/locale/hu/LC_MESSAGES/django.mo +0 -0
- umap/locale/hu/LC_MESSAGES/django.po +20 -16
- umap/locale/pl/LC_MESSAGES/django.mo +0 -0
- umap/locale/pl/LC_MESSAGES/django.po +101 -95
- umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
- umap/locale/zh_TW/LC_MESSAGES/django.po +20 -16
- umap/management/commands/clean_tilelayer.py +0 -1
- umap/management/commands/search_maps.py +95 -0
- umap/settings/__init__.py +9 -1
- umap/settings/base.py +7 -6
- umap/static/umap/content.css +0 -3
- umap/static/umap/css/bar.css +9 -6
- umap/static/umap/css/form.css +25 -9
- umap/static/umap/css/icon.css +8 -0
- umap/static/umap/css/popup.css +1 -0
- umap/static/umap/img/16-white.svg +5 -2
- umap/static/umap/img/16.svg +1 -1
- umap/static/umap/img/source/16-white.svg +7 -4
- umap/static/umap/img/source/16.svg +1 -1
- umap/static/umap/js/components/copiable.js +47 -0
- umap/static/umap/js/modules/autocomplete.js +32 -67
- umap/static/umap/js/modules/browser.js +31 -14
- umap/static/umap/js/modules/data/features.js +34 -36
- umap/static/umap/js/modules/data/fields.js +199 -23
- umap/static/umap/js/modules/data/layer.js +85 -96
- umap/static/umap/js/modules/domutils.js +25 -1
- umap/static/umap/js/modules/filters.js +24 -50
- umap/static/umap/js/modules/form/builder.js +17 -16
- umap/static/umap/js/modules/form/fields.js +20 -20
- umap/static/umap/js/modules/formatter.js +9 -1
- umap/static/umap/js/modules/help.js +12 -13
- umap/static/umap/js/modules/importer.js +17 -26
- umap/static/umap/js/modules/importers/banfr.js +0 -1
- umap/static/umap/js/modules/importers/cadastrefr.js +19 -19
- umap/static/umap/js/modules/importers/communesfr.js +7 -8
- umap/static/umap/js/modules/importers/datasets.js +14 -14
- umap/static/umap/js/modules/importers/geodatamine.js +20 -22
- umap/static/umap/js/modules/importers/opendata.js +10 -0
- umap/static/umap/js/modules/importers/overpass.js +19 -18
- umap/static/umap/js/modules/managers.js +1 -1
- umap/static/umap/js/modules/permissions.js +15 -5
- umap/static/umap/js/modules/rendering/controls.js +203 -10
- umap/static/umap/js/modules/rendering/icon.js +5 -9
- umap/static/umap/js/modules/rendering/layers/base.js +1 -1
- umap/static/umap/js/modules/rendering/layers/classified.js +16 -11
- umap/static/umap/js/modules/rendering/layers/heat.js +1 -0
- umap/static/umap/js/modules/rendering/map.js +67 -57
- umap/static/umap/js/modules/rendering/popup.js +6 -3
- umap/static/umap/js/modules/rendering/template.js +40 -40
- umap/static/umap/js/modules/rendering/ui.js +1 -2
- umap/static/umap/js/modules/rules.js +34 -41
- umap/static/umap/js/modules/schema.js +0 -7
- umap/static/umap/js/modules/share.js +36 -69
- umap/static/umap/js/modules/slideshow.js +3 -3
- umap/static/umap/js/modules/tableeditor.js +0 -1
- umap/static/umap/js/modules/ui/bar.js +53 -33
- umap/static/umap/js/modules/ui/hash.js +36 -0
- umap/static/umap/js/modules/ui/loader.js +26 -0
- umap/static/umap/js/modules/ui/panel.js +33 -21
- umap/static/umap/js/modules/ui/tooltip.js +1 -1
- umap/static/umap/js/modules/umap.js +81 -80
- umap/static/umap/js/modules/utils.js +13 -3
- umap/static/umap/js/umap.controls.js +16 -179
- umap/static/umap/locale/am_ET.js +7 -8
- umap/static/umap/locale/am_ET.json +7 -8
- umap/static/umap/locale/ar.js +7 -8
- umap/static/umap/locale/ar.json +7 -8
- umap/static/umap/locale/ast.js +7 -8
- umap/static/umap/locale/ast.json +7 -8
- umap/static/umap/locale/bg.js +7 -8
- umap/static/umap/locale/bg.json +7 -8
- umap/static/umap/locale/br.js +44 -36
- umap/static/umap/locale/br.json +44 -36
- umap/static/umap/locale/ca.js +7 -8
- umap/static/umap/locale/ca.json +7 -8
- umap/static/umap/locale/cs_CZ.js +7 -8
- umap/static/umap/locale/cs_CZ.json +7 -8
- umap/static/umap/locale/da.js +8 -9
- umap/static/umap/locale/da.json +8 -9
- umap/static/umap/locale/de.js +62 -63
- umap/static/umap/locale/de.json +62 -63
- umap/static/umap/locale/el.js +7 -8
- umap/static/umap/locale/el.json +7 -8
- umap/static/umap/locale/en.js +7 -8
- umap/static/umap/locale/en.json +7 -8
- umap/static/umap/locale/en_US.json +7 -8
- umap/static/umap/locale/es.js +19 -20
- umap/static/umap/locale/es.json +19 -20
- umap/static/umap/locale/et.js +7 -8
- umap/static/umap/locale/et.json +7 -8
- umap/static/umap/locale/eu.js +23 -24
- umap/static/umap/locale/eu.json +23 -24
- umap/static/umap/locale/fa_IR.js +7 -8
- umap/static/umap/locale/fa_IR.json +7 -8
- umap/static/umap/locale/fi.js +7 -8
- umap/static/umap/locale/fi.json +7 -8
- umap/static/umap/locale/fr.js +11 -12
- umap/static/umap/locale/fr.json +11 -12
- umap/static/umap/locale/gl.js +147 -148
- umap/static/umap/locale/gl.json +147 -148
- umap/static/umap/locale/he.js +7 -8
- umap/static/umap/locale/he.json +7 -8
- umap/static/umap/locale/hr.js +7 -8
- umap/static/umap/locale/hr.json +7 -8
- umap/static/umap/locale/hu.js +8 -9
- umap/static/umap/locale/hu.json +8 -9
- umap/static/umap/locale/id.js +7 -8
- umap/static/umap/locale/id.json +7 -8
- umap/static/umap/locale/is.js +7 -8
- umap/static/umap/locale/is.json +7 -8
- umap/static/umap/locale/it.js +7 -8
- umap/static/umap/locale/it.json +7 -8
- umap/static/umap/locale/ja.js +7 -8
- umap/static/umap/locale/ja.json +7 -8
- umap/static/umap/locale/ko.js +7 -8
- umap/static/umap/locale/ko.json +7 -8
- umap/static/umap/locale/lt.js +7 -8
- umap/static/umap/locale/lt.json +7 -8
- umap/static/umap/locale/ms.js +7 -8
- umap/static/umap/locale/ms.json +7 -8
- umap/static/umap/locale/nl.js +7 -8
- umap/static/umap/locale/nl.json +7 -8
- umap/static/umap/locale/no.js +7 -8
- umap/static/umap/locale/no.json +7 -8
- umap/static/umap/locale/pl.js +53 -54
- umap/static/umap/locale/pl.json +53 -54
- umap/static/umap/locale/pl_PL.json +7 -8
- umap/static/umap/locale/pt.js +7 -8
- umap/static/umap/locale/pt.json +7 -8
- umap/static/umap/locale/pt_BR.js +7 -8
- umap/static/umap/locale/pt_BR.json +7 -8
- umap/static/umap/locale/pt_PT.js +7 -8
- umap/static/umap/locale/pt_PT.json +7 -8
- umap/static/umap/locale/ro.js +7 -8
- umap/static/umap/locale/ro.json +7 -8
- umap/static/umap/locale/ru.js +7 -8
- umap/static/umap/locale/ru.json +7 -8
- umap/static/umap/locale/sk_SK.js +7 -8
- umap/static/umap/locale/sk_SK.json +7 -8
- umap/static/umap/locale/sl.js +7 -8
- umap/static/umap/locale/sl.json +7 -8
- umap/static/umap/locale/sr.js +7 -8
- umap/static/umap/locale/sr.json +7 -8
- umap/static/umap/locale/sv.js +7 -8
- umap/static/umap/locale/sv.json +7 -8
- umap/static/umap/locale/th_TH.js +7 -8
- umap/static/umap/locale/th_TH.json +7 -8
- umap/static/umap/locale/tr.js +7 -8
- umap/static/umap/locale/tr.json +7 -8
- umap/static/umap/locale/uk_UA.js +7 -8
- umap/static/umap/locale/uk_UA.json +7 -8
- umap/static/umap/locale/vi.js +7 -8
- umap/static/umap/locale/vi.json +7 -8
- umap/static/umap/locale/vi_VN.json +7 -8
- umap/static/umap/locale/zh.js +7 -8
- umap/static/umap/locale/zh.json +7 -8
- umap/static/umap/locale/zh_CN.json +7 -8
- umap/static/umap/locale/zh_TW.Big5.json +7 -8
- umap/static/umap/locale/zh_TW.js +20 -21
- umap/static/umap/locale/zh_TW.json +20 -21
- umap/static/umap/map.css +6 -21
- umap/static/umap/unittests/utils.js +7 -7
- umap/static/umap/vendors/locatecontrol/L.Control.Locate.esm.js +942 -0
- umap/static/umap/vendors/photon/leaflet.photon.esm.js +472 -0
- umap/sync/app.py +4 -1
- umap/templates/umap/content_footer.html +1 -0
- umap/templates/umap/css.html +0 -4
- umap/templates/umap/js.html +1 -8
- umap/templates/umap/team_form.html +2 -1
- umap/tests/integration/conftest.py +3 -2
- umap/tests/integration/test_anonymous_owned_map.py +1 -1
- umap/tests/integration/test_conditional_rules.py +106 -51
- umap/tests/integration/test_draw_polygon.py +4 -0
- umap/tests/integration/test_draw_polyline.py +11 -0
- umap/tests/integration/test_edit_datalayer.py +1 -1
- umap/tests/integration/test_edit_map.py +2 -0
- umap/tests/integration/test_fields.py +19 -0
- umap/tests/integration/test_filters.py +24 -0
- umap/tests/integration/test_iframe.py +1 -1
- umap/tests/integration/test_import.py +26 -0
- umap/tests/integration/test_map.py +3 -3
- umap/tests/integration/test_optimistic_merge.py +7 -1
- umap/tests/integration/test_owned_map.py +2 -2
- umap/tests/integration/test_popup.py +31 -0
- umap/tests/integration/test_remote_data.py +5 -5
- umap/tests/integration/test_search.py +41 -0
- umap/tests/integration/test_share.py +2 -2
- umap/tests/integration/test_team.py +1 -1
- umap/tests/integration/test_websocket_sync.py +6 -1
- umap/tests/test_search_maps_command.py +44 -0
- umap/tests/test_utils.py +4 -1
- umap/utils.py +10 -3
- umap/views.py +17 -4
- {umap_project-3.4.0b3.dist-info → umap_project-3.6.0.dist-info}/METADATA +29 -23
- {umap_project-3.4.0b3.dist-info → umap_project-3.6.0.dist-info}/RECORD +210 -214
- {umap_project-3.4.0b3.dist-info → umap_project-3.6.0.dist-info}/WHEEL +1 -1
- umap/static/umap/js/umap.core.js +0 -93
- umap/static/umap/vendors/editinosm/Leaflet.EditInOSM.css +0 -46
- umap/static/umap/vendors/editinosm/Leaflet.EditInOSM.js +0 -240
- umap/static/umap/vendors/editinosm/edit-in-osm.png +0 -0
- umap/static/umap/vendors/hash/leaflet-hash.js +0 -162
- umap/static/umap/vendors/loading/Control.Loading.css +0 -26
- umap/static/umap/vendors/loading/Control.Loading.js +0 -351
- umap/static/umap/vendors/locatecontrol/L.Control.Locate.min.css +0 -1
- umap/static/umap/vendors/locatecontrol/L.Control.Locate.min.css.map +0 -1
- umap/static/umap/vendors/locatecontrol/L.Control.Locate.min.js +0 -4
- umap/static/umap/vendors/locatecontrol/L.Control.Locate.min.js.map +0 -1
- umap/static/umap/vendors/photon/leaflet.photon.js +0 -487
- {umap_project-3.4.0b3.dist-info → umap_project-3.6.0.dist-info}/entry_points.txt +0 -0
- {umap_project-3.4.0b3.dist-info → umap_project-3.6.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -32,7 +32,7 @@ export const copyToClipboard = (textToCopy) => {
|
|
|
32
32
|
tooltip.open({ content: translate('✅ Copied!'), duration: 5000 })
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
export const copiableInput = (parent, label, value) => {
|
|
35
|
+
export const copiableInput = (parent, label, value = '') => {
|
|
36
36
|
const [container, { input, button }] = Utils.loadTemplateWithRefs(`
|
|
37
37
|
<div class="copiable-input">
|
|
38
38
|
<label>${label}<input type="text" readOnly value="${value}" data-ref=input /></label>
|
|
@@ -82,6 +82,10 @@ export const hexToRGB = (hex) => {
|
|
|
82
82
|
.match(/.{2}/g)
|
|
83
83
|
.map((x) => Number.parseInt(x, 16))
|
|
84
84
|
}
|
|
85
|
+
export const colorToRGB = (color) => {
|
|
86
|
+
if (!color.startsWith('#')) color = colorNameToHex(color)
|
|
87
|
+
return hexToRGB(color)
|
|
88
|
+
}
|
|
85
89
|
|
|
86
90
|
const CACHE_CONTRAST = {}
|
|
87
91
|
export const contrastedColor = (el, bgcolor) => {
|
|
@@ -107,3 +111,23 @@ export const contrastedColor = (el, bgcolor) => {
|
|
|
107
111
|
if (bgcolor) CACHE_CONTRAST[bgcolor] = out
|
|
108
112
|
return out
|
|
109
113
|
}
|
|
114
|
+
|
|
115
|
+
export const createFieldset = (parent, title, options) => {
|
|
116
|
+
options = options || {}
|
|
117
|
+
const [details, { summary, fieldset }] = loadTemplateWithRefs(`
|
|
118
|
+
<details class="${options.className || ''}">
|
|
119
|
+
<summary data-ref="summary"><h4>${title}</h4></summary>
|
|
120
|
+
<fieldset data-ref="fieldset"></fieldset>
|
|
121
|
+
</details>
|
|
122
|
+
`)
|
|
123
|
+
details.open = options.on === true
|
|
124
|
+
parent.appendChild(details)
|
|
125
|
+
if (options.icon) {
|
|
126
|
+
const icon = loadTemplate(`<i class="icon icon-16 ${options.icon}"></i>`)
|
|
127
|
+
summary.insertBefore(icon, summary.firstChild)
|
|
128
|
+
}
|
|
129
|
+
return fieldset
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export const loadTemplateWithRefs = Utils.loadTemplateWithRefs
|
|
133
|
+
export const loadTemplate = Utils.loadTemplate
|
|
@@ -6,27 +6,6 @@ import { Fields } from './form/fields.js'
|
|
|
6
6
|
|
|
7
7
|
const EMPTY_VALUE = translate('<empty value>')
|
|
8
8
|
|
|
9
|
-
const getParser = (type) => {
|
|
10
|
-
switch (type) {
|
|
11
|
-
case 'Number':
|
|
12
|
-
return Number.parseFloat
|
|
13
|
-
case 'Datetime':
|
|
14
|
-
return (v) => new Date(v)
|
|
15
|
-
case 'Date':
|
|
16
|
-
return Utils.parseNaiveDate
|
|
17
|
-
case 'Boolean':
|
|
18
|
-
return Boolean
|
|
19
|
-
case 'Enum':
|
|
20
|
-
return (v) => {
|
|
21
|
-
if (!v) return [EMPTY_VALUE]
|
|
22
|
-
return String(v || '')
|
|
23
|
-
.split(',')
|
|
24
|
-
.map((s) => s.trim())
|
|
25
|
-
}
|
|
26
|
-
default:
|
|
27
|
-
return (v) => String(v || '')
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
9
|
const Widgets = {}
|
|
31
10
|
|
|
32
11
|
class BaseWidget {
|
|
@@ -73,13 +52,13 @@ Widgets.MinMax = class extends BaseWidget {
|
|
|
73
52
|
return this.userData.min !== undefined || this.userData.max !== undefined
|
|
74
53
|
}
|
|
75
54
|
getFormField(field) {
|
|
76
|
-
if (field.
|
|
55
|
+
if (field.TYPE === 'Number') {
|
|
77
56
|
return 'FilterByNumber'
|
|
78
57
|
}
|
|
79
|
-
if (field.
|
|
58
|
+
if (field.TYPE === 'Date') {
|
|
80
59
|
return 'FilterByDate'
|
|
81
60
|
}
|
|
82
|
-
if (field.
|
|
61
|
+
if (field.TYPE === 'Datetime') {
|
|
83
62
|
return 'FilterByDateTime'
|
|
84
63
|
}
|
|
85
64
|
return super.getFormField(field)
|
|
@@ -186,16 +165,15 @@ export class Filters {
|
|
|
186
165
|
// and max values.
|
|
187
166
|
computeInitialData() {
|
|
188
167
|
const initialData = Object.fromEntries(
|
|
189
|
-
this.available.keys().map((name) => [name, {}])
|
|
168
|
+
Array.from(this.available.keys()).map((name) => [name, {}])
|
|
190
169
|
)
|
|
191
170
|
|
|
192
171
|
for (const [name, filter] of this.available.entries()) {
|
|
193
172
|
const field = this._parent.fields.get(name)
|
|
194
173
|
if (!field) continue
|
|
195
|
-
const parser = getParser(field.type)
|
|
196
174
|
this._parent.eachFeature((feature) => {
|
|
197
175
|
let value = feature.properties[name]
|
|
198
|
-
value =
|
|
176
|
+
value = field.parse(value)
|
|
199
177
|
filter.computeInitialData(initialData[name], value)
|
|
200
178
|
})
|
|
201
179
|
}
|
|
@@ -214,6 +192,7 @@ export class Filters {
|
|
|
214
192
|
{
|
|
215
193
|
initialData: initialData[name] || {},
|
|
216
194
|
handler: filter.getFormField(field),
|
|
195
|
+
dataField: field,
|
|
217
196
|
label: Utils.escapeHTML(this.available.get(name).label || field.key),
|
|
218
197
|
onClick: () => {
|
|
219
198
|
this._parent
|
|
@@ -228,14 +207,8 @@ export class Filters {
|
|
|
228
207
|
}
|
|
229
208
|
|
|
230
209
|
load() {
|
|
231
|
-
let filters = this._parent.properties.filters
|
|
232
|
-
|
|
233
|
-
// filters to be an array
|
|
234
|
-
if (typeof filters === 'object' && !Array.isArray(filters) && filters !== null) {
|
|
235
|
-
filters = Object.entries(filters).map(([fieldKey, props]) => {
|
|
236
|
-
return { fieldKey, ...props }
|
|
237
|
-
})
|
|
238
|
-
}
|
|
210
|
+
let filters = this._parent.properties.filters
|
|
211
|
+
if (!Array.isArray(filters)) filters = []
|
|
239
212
|
for (const filter of filters) {
|
|
240
213
|
this._add({ ...filter })
|
|
241
214
|
}
|
|
@@ -377,9 +350,9 @@ export class Filters {
|
|
|
377
350
|
createFilterForm(fieldKey) {
|
|
378
351
|
let widget = 'Checkbox'
|
|
379
352
|
const field = this._parent.fields.get(fieldKey)
|
|
380
|
-
if (['Number', 'Date', 'Datetime'].includes(field?.
|
|
353
|
+
if (['Number', 'Date', 'Datetime'].includes(field?.TYPE)) {
|
|
381
354
|
widget = 'MinMax'
|
|
382
|
-
} else if (field?.
|
|
355
|
+
} else if (field?.TYPE === 'Boolean') {
|
|
383
356
|
widget = 'Switch'
|
|
384
357
|
}
|
|
385
358
|
const properties = {
|
|
@@ -392,7 +365,9 @@ export class Filters {
|
|
|
392
365
|
? [fieldKey]
|
|
393
366
|
: [
|
|
394
367
|
'',
|
|
395
|
-
...this._parent.
|
|
368
|
+
...Array.from(this._parent.fields.keys()).filter(
|
|
369
|
+
(fieldKey) => !this.available.has(fieldKey)
|
|
370
|
+
),
|
|
396
371
|
]
|
|
397
372
|
const metadata = [
|
|
398
373
|
[
|
|
@@ -474,8 +449,7 @@ export class Filters {
|
|
|
474
449
|
// This field may only exist on another layer.
|
|
475
450
|
if (!field) continue
|
|
476
451
|
let value = feature.properties[fieldKey]
|
|
477
|
-
|
|
478
|
-
value = parser(value)
|
|
452
|
+
value = field.parse(value)
|
|
479
453
|
if (obj.match(value)) return true
|
|
480
454
|
}
|
|
481
455
|
return false
|
|
@@ -510,6 +484,10 @@ class FiltersForm extends Form {
|
|
|
510
484
|
|
|
511
485
|
const FilterBase = class extends Fields.Base {
|
|
512
486
|
buildLabel() {}
|
|
487
|
+
|
|
488
|
+
cast(value) {
|
|
489
|
+
return this.properties.dataField.cast(value) || EMPTY_VALUE
|
|
490
|
+
}
|
|
513
491
|
}
|
|
514
492
|
|
|
515
493
|
const FilterByChoices = class extends FilterBase {
|
|
@@ -545,8 +523,8 @@ const FilterByChoices = class extends FilterBase {
|
|
|
545
523
|
|
|
546
524
|
toJS() {
|
|
547
525
|
return {
|
|
548
|
-
selected: [...this.elements.ul.querySelectorAll('input:checked')].map(
|
|
549
|
-
(i
|
|
526
|
+
selected: [...this.elements.ul.querySelectorAll('input:checked')].map((i) =>
|
|
527
|
+
this.cast(i.dataset.value)
|
|
550
528
|
),
|
|
551
529
|
}
|
|
552
530
|
}
|
|
@@ -573,6 +551,10 @@ Fields.MinMaxBase = class extends FilterBase {
|
|
|
573
551
|
return value?.valueOf() ?? null
|
|
574
552
|
}
|
|
575
553
|
|
|
554
|
+
prepareForJS(value) {
|
|
555
|
+
return this.cast(value)
|
|
556
|
+
}
|
|
557
|
+
|
|
576
558
|
getTemplate() {
|
|
577
559
|
const [minLabel, maxLabel] = this.getLabels()
|
|
578
560
|
const { min, max } = this.properties.initialData
|
|
@@ -654,10 +636,6 @@ Fields.FilterByNumber = class extends Fields.MinMaxBase {
|
|
|
654
636
|
getInputType(type) {
|
|
655
637
|
return 'number'
|
|
656
638
|
}
|
|
657
|
-
|
|
658
|
-
prepareForJS(value) {
|
|
659
|
-
return new Number(value)
|
|
660
|
-
}
|
|
661
639
|
}
|
|
662
640
|
|
|
663
641
|
Fields.FilterByDate = class extends Fields.MinMaxBase {
|
|
@@ -665,10 +643,6 @@ Fields.FilterByDate = class extends Fields.MinMaxBase {
|
|
|
665
643
|
return 'date'
|
|
666
644
|
}
|
|
667
645
|
|
|
668
|
-
prepareForJS(value) {
|
|
669
|
-
return new Date(value)
|
|
670
|
-
}
|
|
671
|
-
|
|
672
646
|
toLocaleDateTime(dt) {
|
|
673
647
|
return new Date(dt.valueOf() - dt.getTimezoneOffset() * 60000)
|
|
674
648
|
}
|
|
@@ -56,30 +56,31 @@ export class Form extends Utils.WithEvents {
|
|
|
56
56
|
return this.helpers[field]
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
getter(
|
|
60
|
-
const path = field.split('.')
|
|
59
|
+
getter(helper) {
|
|
60
|
+
const path = helper.field.split('.')
|
|
61
61
|
let value = this.obj
|
|
62
62
|
for (const sub of path) {
|
|
63
63
|
try {
|
|
64
64
|
value = value[sub]
|
|
65
65
|
} catch {
|
|
66
|
-
console.debug(field)
|
|
66
|
+
console.debug(helper.field)
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
return value
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
setter(
|
|
72
|
+
setter(helper, value) {
|
|
73
73
|
if ('setter' in this.obj) {
|
|
74
|
-
this.obj.setter(field, value)
|
|
74
|
+
this.obj.setter(helper.field, value)
|
|
75
75
|
} else {
|
|
76
|
-
Utils.setObjectValue(this.obj, field, value)
|
|
76
|
+
Utils.setObjectValue(this.obj, helper.field, value)
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
restoreField(field) {
|
|
81
|
-
const
|
|
82
|
-
|
|
81
|
+
const helper = this.helpers[field]
|
|
82
|
+
const initial = helper.initial
|
|
83
|
+
this.setter(helper, initial)
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
getName(field) {
|
|
@@ -127,9 +128,9 @@ export class Form extends Utils.WithEvents {
|
|
|
127
128
|
export class MutatingForm extends Form {
|
|
128
129
|
constructor(obj, fields, properties) {
|
|
129
130
|
super(obj, fields, properties)
|
|
131
|
+
this.debounce = true
|
|
130
132
|
this._umap = obj._umap || properties.umap
|
|
131
133
|
this.computeDefaultProperties()
|
|
132
|
-
// this.on('finish', this.finish)
|
|
133
134
|
}
|
|
134
135
|
|
|
135
136
|
computeDefaultProperties() {
|
|
@@ -180,21 +181,21 @@ export class MutatingForm extends Form {
|
|
|
180
181
|
}
|
|
181
182
|
}
|
|
182
183
|
|
|
183
|
-
setter(
|
|
184
|
-
const oldValue = this.getter(
|
|
185
|
-
super.setter(
|
|
184
|
+
setter(helper, value) {
|
|
185
|
+
const oldValue = this.getter(helper)
|
|
186
|
+
super.setter(helper, value)
|
|
186
187
|
if ('render' in this.obj) {
|
|
187
|
-
this.obj.render([field], this)
|
|
188
|
+
this.obj.render([helper.field], this)
|
|
188
189
|
}
|
|
189
|
-
if ('sync' in this.obj) {
|
|
190
|
-
this.obj.sync.update(field, value, oldValue)
|
|
190
|
+
if ('sync' in this.obj && helper.properties.sync !== false) {
|
|
191
|
+
this.obj.sync.update(helper.field, value, oldValue)
|
|
191
192
|
}
|
|
192
193
|
}
|
|
193
194
|
|
|
194
195
|
getTemplate(helper) {
|
|
195
196
|
let template
|
|
196
197
|
if (helper.properties.inheritable) {
|
|
197
|
-
const extraClassName = this.getter(helper
|
|
198
|
+
const extraClassName = this.getter(helper) === undefined ? ' undefined' : ''
|
|
198
199
|
template = `
|
|
199
200
|
<div class="umap-field-${helper.name} formbox inheritable${extraClassName}">
|
|
200
201
|
<div class="header" data-ref=header>
|
|
@@ -87,7 +87,7 @@ Fields.Base = class {
|
|
|
87
87
|
const path = this.field.split('.')
|
|
88
88
|
const key = path[path.length - 1]
|
|
89
89
|
if (!this.properties.inheritable) {
|
|
90
|
-
value = this.builder.getter(this
|
|
90
|
+
value = this.builder.getter(this)
|
|
91
91
|
} else {
|
|
92
92
|
value = this.obj.getOption(key)
|
|
93
93
|
}
|
|
@@ -108,8 +108,16 @@ Fields.Base = class {
|
|
|
108
108
|
this.builder.fire('set', { helper: this })
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
listenForSync(element) {
|
|
112
|
+
let callback = () => this.sync()
|
|
113
|
+
if (this.builder.form.debounce) {
|
|
114
|
+
callback = Utils.debounce(callback, 300)
|
|
115
|
+
}
|
|
116
|
+
element.addEventListener('input', callback)
|
|
117
|
+
}
|
|
118
|
+
|
|
111
119
|
set() {
|
|
112
|
-
this.builder.setter(this
|
|
120
|
+
this.builder.setter(this, this.toJS())
|
|
113
121
|
}
|
|
114
122
|
|
|
115
123
|
getLabelTemplate() {
|
|
@@ -139,10 +147,7 @@ Fields.Textarea = class extends Fields.Base {
|
|
|
139
147
|
this.textarea = this.elements.textarea
|
|
140
148
|
this.input = this.textarea
|
|
141
149
|
this.fetch()
|
|
142
|
-
this.textarea
|
|
143
|
-
'input',
|
|
144
|
-
Utils.debounce(() => this.sync(), 300)
|
|
145
|
-
)
|
|
150
|
+
this.listenForSync(this.textarea)
|
|
146
151
|
this.textarea.addEventListener('keypress', (event) => this.onKeyPress(event))
|
|
147
152
|
}
|
|
148
153
|
|
|
@@ -194,7 +199,7 @@ Fields.Input = class extends Fields.Base {
|
|
|
194
199
|
this.input.disabled = true
|
|
195
200
|
}
|
|
196
201
|
this.fetch()
|
|
197
|
-
this.listenForSync()
|
|
202
|
+
this.listenForSync(this.input)
|
|
198
203
|
this.input.addEventListener('keydown', (event) => this.onKeyDown(event))
|
|
199
204
|
}
|
|
200
205
|
|
|
@@ -204,13 +209,6 @@ Fields.Input = class extends Fields.Base {
|
|
|
204
209
|
this.input.value = value
|
|
205
210
|
}
|
|
206
211
|
|
|
207
|
-
listenForSync() {
|
|
208
|
-
this.input.addEventListener(
|
|
209
|
-
'input',
|
|
210
|
-
Utils.debounce(() => this.sync(), 300)
|
|
211
|
-
)
|
|
212
|
-
}
|
|
213
|
-
|
|
214
212
|
type() {
|
|
215
213
|
return this.properties.type || 'text'
|
|
216
214
|
}
|
|
@@ -644,7 +642,7 @@ const BaseDataLayerSwitcher = class extends Fields.Select {
|
|
|
644
642
|
|
|
645
643
|
set() {
|
|
646
644
|
this.builder._umap.lastUsedDataLayer = this.toJS()
|
|
647
|
-
this.builder.setter(this
|
|
645
|
+
this.builder.setter(this, this.toJS())
|
|
648
646
|
}
|
|
649
647
|
}
|
|
650
648
|
|
|
@@ -746,7 +744,7 @@ Fields.PropertyInput = class extends Fields.BlurInput {
|
|
|
746
744
|
super.build()
|
|
747
745
|
const autocomplete = new AutocompleteDatalist(this.input)
|
|
748
746
|
// Will be used on Umap and DataLayer
|
|
749
|
-
const properties = this.builder.obj.
|
|
747
|
+
const properties = Array.from(this.builder.obj.fields.keys())
|
|
750
748
|
autocomplete.suggestions = properties
|
|
751
749
|
}
|
|
752
750
|
}
|
|
@@ -762,7 +760,7 @@ Fields.IconUrl = class extends Fields.BlurInput {
|
|
|
762
760
|
// in the super method, maybe it's useless for all fields.
|
|
763
761
|
const path = this.field.split('.')
|
|
764
762
|
const key = path[path.length - 1]
|
|
765
|
-
return this.builder.getter(this
|
|
763
|
+
return this.builder.getter(this)
|
|
766
764
|
}
|
|
767
765
|
|
|
768
766
|
getTemplate() {
|
|
@@ -1217,8 +1215,9 @@ Fields.ManageOwner = class extends Fields.Base {
|
|
|
1217
1215
|
super.build()
|
|
1218
1216
|
const options = {
|
|
1219
1217
|
className: 'edit-owner',
|
|
1220
|
-
on_select:
|
|
1218
|
+
on_select: (choice) => this.onSelect(choice),
|
|
1221
1219
|
placeholder: translate("Type new owner's username"),
|
|
1220
|
+
url: this.properties.url,
|
|
1222
1221
|
}
|
|
1223
1222
|
this.autocomplete = new AjaxAutocomplete(this.container, options)
|
|
1224
1223
|
const owner = this.toHTML()
|
|
@@ -1248,9 +1247,10 @@ Fields.ManageEditors = class extends Fields.Base {
|
|
|
1248
1247
|
super.build()
|
|
1249
1248
|
const options = {
|
|
1250
1249
|
className: 'edit-editors',
|
|
1251
|
-
on_select:
|
|
1252
|
-
on_unselect:
|
|
1250
|
+
on_select: (choice) => this.onSelect(choice),
|
|
1251
|
+
on_unselect: (choice) => this.onUnselect(choice),
|
|
1253
1252
|
placeholder: translate("Type editor's username"),
|
|
1253
|
+
url: this.properties.url,
|
|
1254
1254
|
}
|
|
1255
1255
|
this.autocomplete = new AjaxAutocompleteMultiple(this.container, options)
|
|
1256
1256
|
this._values = this.toHTML() || []
|
|
@@ -71,7 +71,15 @@ export class Formatter {
|
|
|
71
71
|
} catch (e) {
|
|
72
72
|
src = this.toDom(str)
|
|
73
73
|
}
|
|
74
|
-
|
|
74
|
+
const data = osmtogeojson(src, { flatProperties: true })
|
|
75
|
+
// FIXME: make a PR to osmtogeojson when it's more active
|
|
76
|
+
// cf https://github.com/umap-project/umap/issues/3072
|
|
77
|
+
for (const feature of data.features || []) {
|
|
78
|
+
const [osm_type, osm_id] = feature.properties.id.split('/')
|
|
79
|
+
feature.properties.osm_id = osm_id
|
|
80
|
+
feature.properties.osm_type = osm_type
|
|
81
|
+
}
|
|
82
|
+
return data
|
|
75
83
|
}
|
|
76
84
|
|
|
77
85
|
fromCSV(str, callback) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { DomEvent, DomUtil } from '../../vendors/leaflet/leaflet-src.esm.js'
|
|
2
1
|
import { translate } from './i18n.js'
|
|
3
2
|
import Dialog from './ui/dialog.js'
|
|
4
3
|
import * as Utils from './utils.js'
|
|
4
|
+
import * as DOMUtils from './domutils.js'
|
|
5
5
|
|
|
6
6
|
const SHORTCUTS = {
|
|
7
7
|
DRAW_MARKER: {
|
|
@@ -209,15 +209,15 @@ export default class Help {
|
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
show(entries) {
|
|
212
|
-
const container =
|
|
213
|
-
|
|
212
|
+
const container = DOMUtils.loadTemplate(`
|
|
213
|
+
<div>
|
|
214
|
+
<h3><i class="icon icon-16 icon-help"></i> ${translate('Help')}</h3>
|
|
215
|
+
</div>
|
|
216
|
+
`)
|
|
214
217
|
for (const name of entries) {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
parent: container,
|
|
219
|
-
innerHTML: ENTRIES[name],
|
|
220
|
-
})
|
|
218
|
+
container.appendChild(
|
|
219
|
+
DOMUtils.loadTemplate(`<div class="umap-help-entry">${ENTRIES[name]}</div>`)
|
|
220
|
+
)
|
|
221
221
|
}
|
|
222
222
|
this.dialog.open({ template: container })
|
|
223
223
|
}
|
|
@@ -253,11 +253,10 @@ export default class Help {
|
|
|
253
253
|
}
|
|
254
254
|
|
|
255
255
|
button(container, entries) {
|
|
256
|
-
const button =
|
|
257
|
-
|
|
258
|
-
container,
|
|
259
|
-
translate('Help')
|
|
256
|
+
const button = DOMUtils.loadTemplate(
|
|
257
|
+
`<button class="umap-help-button" type="button">${translate('Help')}</button>`
|
|
260
258
|
)
|
|
259
|
+
container.appendChild(button)
|
|
261
260
|
button.addEventListener('click', () => this.show(entries))
|
|
262
261
|
return button
|
|
263
262
|
}
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DomEvent,
|
|
3
|
-
DomUtil,
|
|
4
|
-
LatLngBounds,
|
|
5
|
-
} from '../../vendors/leaflet/leaflet-src.esm.js'
|
|
1
|
+
import { LatLngBounds } from '../../vendors/leaflet/leaflet-src.esm.js'
|
|
6
2
|
import { uMapAlert as Alert } from '../components/alerts/alert.js'
|
|
7
3
|
import { translate } from './i18n.js'
|
|
8
4
|
import { SCHEMA } from './schema.js'
|
|
9
5
|
import Dialog from './ui/dialog.js'
|
|
10
6
|
import * as Utils from './utils.js'
|
|
7
|
+
import * as DOMUtils from './domutils.js'
|
|
11
8
|
|
|
12
9
|
const TEMPLATE = `
|
|
13
10
|
<div class="umap-import">
|
|
@@ -203,18 +200,15 @@ export default class Importer extends Utils.WithTemplate {
|
|
|
203
200
|
button.toggleAttribute('hidden', false)
|
|
204
201
|
}
|
|
205
202
|
for (const type of this.TYPES) {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
value: type,
|
|
210
|
-
textContent: type,
|
|
211
|
-
})
|
|
203
|
+
this.qs('[name=format]').appendChild(
|
|
204
|
+
DOMUtils.loadTemplate(`<option value="${type}">${type}</option>`)
|
|
205
|
+
)
|
|
212
206
|
}
|
|
213
207
|
this._umap.help.parse(this.container)
|
|
214
208
|
this.qs('[name=submit]').addEventListener('click', () => this.submit())
|
|
215
|
-
|
|
209
|
+
this.qs('[type=file]').addEventListener('change', () => this.onFileChange())
|
|
216
210
|
for (const element of this.container.querySelectorAll('[onchange]')) {
|
|
217
|
-
|
|
211
|
+
element.addEventListener('change', () => this.onChange())
|
|
218
212
|
}
|
|
219
213
|
}
|
|
220
214
|
|
|
@@ -253,21 +247,18 @@ export default class Importer extends Utils.WithTemplate {
|
|
|
253
247
|
layerSelect.innerHTML = ''
|
|
254
248
|
this._umap.datalayers.reverse().map((datalayer) => {
|
|
255
249
|
if (datalayer.isLoaded() && !datalayer.isRemoteLayer()) {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
})
|
|
250
|
+
layerSelect.appendChild(
|
|
251
|
+
DOMUtils.loadTemplate(
|
|
252
|
+
`<option value="${datalayer.id}">${datalayer.getName()}</option>`
|
|
253
|
+
)
|
|
254
|
+
)
|
|
262
255
|
}
|
|
263
256
|
})
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
selected: true,
|
|
270
|
-
})
|
|
257
|
+
layerSelect.appendChild(
|
|
258
|
+
DOMUtils.loadTemplate(
|
|
259
|
+
`<option value="" selected>${translate('Import in a new layer')}</option>`
|
|
260
|
+
)
|
|
261
|
+
)
|
|
271
262
|
}
|
|
272
263
|
|
|
273
264
|
open() {
|
|
@@ -1,26 +1,28 @@
|
|
|
1
|
-
import { DomUtil } from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
2
1
|
import { uMapAlert as Alert } from '../../components/alerts/alert.js'
|
|
3
2
|
import { BaseAjax, SingleMixin } from '../autocomplete.js'
|
|
4
3
|
import { translate } from '../i18n.js'
|
|
5
4
|
import * as Util from '../utils.js'
|
|
5
|
+
import * as DOMUtils from '../domutils.js'
|
|
6
6
|
import { AutocompleteCommunes } from './communesfr.js'
|
|
7
7
|
|
|
8
8
|
const TEMPLATE = `
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
<
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
9
|
+
<div>
|
|
10
|
+
<h3>Cadastre</h3>
|
|
11
|
+
<p>Importer les données cadastrales d’une commune française.</p>
|
|
12
|
+
<div class="formbox">
|
|
13
|
+
<select name="theme" data-ref="select">
|
|
14
|
+
<option value="batiments">Bâtiments</option>
|
|
15
|
+
<option value="communes">Communes</option>
|
|
16
|
+
<option value="feuilles">Feuilles</option>
|
|
17
|
+
<option value="lieux_dits">Lieux dits</option>
|
|
18
|
+
<option value="parcelles" selected>Parcelles</option>
|
|
19
|
+
<option value="prefixes_sections">Préfixes sections</option>
|
|
20
|
+
<option value="sections">Sections</option>
|
|
21
|
+
<option value="subdivisions_fiscales">Subdivisions fiscales</option>
|
|
22
|
+
</select>
|
|
23
|
+
<label id="boundary">
|
|
24
|
+
</label>
|
|
25
|
+
</div>
|
|
24
26
|
</div>
|
|
25
27
|
`
|
|
26
28
|
|
|
@@ -33,9 +35,7 @@ export class Importer {
|
|
|
33
35
|
async open(importer) {
|
|
34
36
|
let boundary = null
|
|
35
37
|
let boundaryName = null
|
|
36
|
-
const container =
|
|
37
|
-
container.innerHTML = TEMPLATE
|
|
38
|
-
const select = container.querySelector('select')
|
|
38
|
+
const [container, { select }] = DOMUtils.loadTemplateWithRefs(TEMPLATE)
|
|
39
39
|
const options = {
|
|
40
40
|
placeholder: 'Nom ou code INSEE…',
|
|
41
41
|
url: 'https://geo.api.gouv.fr/communes?nom={q}&limit=5',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { DomUtil } from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
2
1
|
import { BaseAjax, SingleMixin } from '../autocomplete.js'
|
|
3
2
|
import * as Util from '../utils.js'
|
|
3
|
+
import * as DOMUtils from '../domutils.js'
|
|
4
4
|
|
|
5
5
|
export class AutocompleteCommunes extends SingleMixin(BaseAjax) {
|
|
6
6
|
createResult(item) {
|
|
@@ -29,13 +29,12 @@ export class Importer {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
async open(importer) {
|
|
32
|
-
const container =
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
})
|
|
32
|
+
const container = DOMUtils.loadTemplate(`
|
|
33
|
+
<div>
|
|
34
|
+
<h3>${this.name}</h3>
|
|
35
|
+
<p>Importer les contours d'une commune française.</p>
|
|
36
|
+
</div>
|
|
37
|
+
`)
|
|
39
38
|
const options = {
|
|
40
39
|
placeholder: 'Nom ou code INSEE…',
|
|
41
40
|
url: 'https://geo.api.gouv.fr/communes?nom={q}&limit=5',
|