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
|
@@ -9,6 +9,190 @@ export const getDefaultFields = () => [
|
|
|
9
9
|
{ key: 'description', type: 'Text' },
|
|
10
10
|
]
|
|
11
11
|
|
|
12
|
+
export const Registry = {}
|
|
13
|
+
|
|
14
|
+
class BaseField {
|
|
15
|
+
constructor(key) {
|
|
16
|
+
this.key = key
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
values(features) {
|
|
20
|
+
return features
|
|
21
|
+
.map((feature) => this.parse(feature.properties[this.key]))
|
|
22
|
+
.filter((val, idx, arr) => arr.indexOf(val) === idx)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
equal(expected, other) {
|
|
26
|
+
return expected === other
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
not_equal(expected, other) {
|
|
30
|
+
return expected !== other
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
gt(expected, other) {
|
|
34
|
+
return other > expected
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
lt(expected, other) {
|
|
38
|
+
return other < expected
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
render(value) {
|
|
42
|
+
return Utils.escapeHTML(value).trim()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
cast(value) {
|
|
46
|
+
return this.parse(value)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
dumps() {
|
|
50
|
+
return {
|
|
51
|
+
key: this.key,
|
|
52
|
+
type: this.TYPE,
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
Registry.String = class extends BaseField {
|
|
58
|
+
constructor(key) {
|
|
59
|
+
super(key)
|
|
60
|
+
// FIXME make it dynamic from class name
|
|
61
|
+
this.TYPE = 'String'
|
|
62
|
+
this.LABEL = translate('Short text')
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
parse(value) {
|
|
66
|
+
return String(value ?? '')
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
render(value) {
|
|
70
|
+
value = super.render(value)
|
|
71
|
+
// TODO, manage links (url, mailto, wikipedia...)
|
|
72
|
+
if (value.indexOf('http') === 0) {
|
|
73
|
+
value = `<a href="${value}" target="_blank">${value}</a>`
|
|
74
|
+
}
|
|
75
|
+
return value
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
Registry.Text = class extends Registry.String {
|
|
80
|
+
constructor(key) {
|
|
81
|
+
super(key)
|
|
82
|
+
// FIXME make it dynamic from class name
|
|
83
|
+
this.TYPE = 'Text'
|
|
84
|
+
this.LABEL = translate('Text')
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
render(value) {
|
|
88
|
+
return Utils.toHTML(value)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
Registry.Number = class extends BaseField {
|
|
93
|
+
constructor(key) {
|
|
94
|
+
super(key)
|
|
95
|
+
// FIXME make it dynamic from class name
|
|
96
|
+
this.TYPE = 'Number'
|
|
97
|
+
this.LABEL = translate('Number')
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
parse(value) {
|
|
101
|
+
const parsed = Number.parseFloat(value)
|
|
102
|
+
if (Number.isNaN(parsed)) return null
|
|
103
|
+
return parsed
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
Registry.Datetime = class extends BaseField {
|
|
108
|
+
constructor(key) {
|
|
109
|
+
super(key)
|
|
110
|
+
// FIXME make it dynamic from class name
|
|
111
|
+
this.TYPE = 'Datetime'
|
|
112
|
+
this.LABEL = translate('Date and time')
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
parse(value) {
|
|
116
|
+
return new Date(value)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
Registry.Date = class extends BaseField {
|
|
121
|
+
constructor(key) {
|
|
122
|
+
super(key)
|
|
123
|
+
// FIXME make it dynamic from class name
|
|
124
|
+
this.TYPE = 'Date'
|
|
125
|
+
this.LABEL = translate('Date')
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
parse(value) {
|
|
129
|
+
return Utils.parseNaiveDate(value)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
Registry.Boolean = class extends BaseField {
|
|
134
|
+
constructor(key) {
|
|
135
|
+
super(key)
|
|
136
|
+
// FIXME make it dynamic from class name
|
|
137
|
+
this.TYPE = 'Boolean'
|
|
138
|
+
this.LABEL = translate('Yes / No')
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
parse(value) {
|
|
142
|
+
// 'yes' is used in OpenStreetMap data
|
|
143
|
+
return ['true', '1', 'yes'].includes(`${value}`.toLowerCase())
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
Registry.Enum = class extends BaseField {
|
|
148
|
+
constructor(key) {
|
|
149
|
+
super(key)
|
|
150
|
+
// FIXME make it dynamic from class name
|
|
151
|
+
this.TYPE = 'Enum'
|
|
152
|
+
this.LABEL = translate('List of values')
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
cast(value) {
|
|
156
|
+
return String(value || '')
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
parse(value) {
|
|
160
|
+
return this.cast(value)
|
|
161
|
+
.split(',')
|
|
162
|
+
.map((s) => s.trim())
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
values(features) {
|
|
166
|
+
return features
|
|
167
|
+
.reduce(
|
|
168
|
+
(acc, feature) => acc.concat(this.parse(feature.properties[this.key])),
|
|
169
|
+
[]
|
|
170
|
+
)
|
|
171
|
+
.filter((val, idx, arr) => arr.indexOf(val) === idx)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
equal(expected, other) {
|
|
175
|
+
return Boolean(new Set(other).intersection(new Set(expected)).size)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
not_equal(expected, other) {
|
|
179
|
+
return !new Set(other).intersection(new Set(expected)).size
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
gt(expected, other) {
|
|
183
|
+
return false
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
lt(expected, other) {
|
|
187
|
+
return false
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const FIELD_TYPES = Object.entries(Registry).map(([name, klass]) => [
|
|
192
|
+
name,
|
|
193
|
+
new klass().LABEL,
|
|
194
|
+
])
|
|
195
|
+
|
|
12
196
|
export class Fields extends Map {
|
|
13
197
|
constructor(parent, dialog) {
|
|
14
198
|
super()
|
|
@@ -38,7 +222,7 @@ export class Fields extends Map {
|
|
|
38
222
|
this.parent.properties.fields = this.all().map((field) => {
|
|
39
223
|
// We don't want to keep the reference, otherwise editing
|
|
40
224
|
// it will also change the old value
|
|
41
|
-
return { ...field }
|
|
225
|
+
return { ...field.dumps() }
|
|
42
226
|
})
|
|
43
227
|
}
|
|
44
228
|
|
|
@@ -60,10 +244,8 @@ export class Fields extends Map {
|
|
|
60
244
|
console.error('Invalid field', field)
|
|
61
245
|
return
|
|
62
246
|
}
|
|
63
|
-
field.type
|
|
64
|
-
|
|
65
|
-
// when edited.
|
|
66
|
-
this.set(field.key, { ...field })
|
|
247
|
+
const klass = Registry[field.type] || Registry.String
|
|
248
|
+
this.set(field.key, new klass(field.key))
|
|
67
249
|
this.push()
|
|
68
250
|
}
|
|
69
251
|
|
|
@@ -103,7 +285,7 @@ export class Fields extends Map {
|
|
|
103
285
|
const [row, { edit, del, addFilter, editFilter }] = Utils.loadTemplateWithRefs(
|
|
104
286
|
`<li class="orderable with-toolbox" data-key="${field.key}">
|
|
105
287
|
<span>
|
|
106
|
-
<i class="icon icon-16 icon-field-${field.
|
|
288
|
+
<i class="icon icon-16 icon-field-${field.TYPE}" title="${field.LABEL}"></i>
|
|
107
289
|
${field.key}
|
|
108
290
|
</span>
|
|
109
291
|
<span>
|
|
@@ -161,16 +343,8 @@ export class Fields extends Map {
|
|
|
161
343
|
|
|
162
344
|
async editField(name) {
|
|
163
345
|
if (!name && this.parent.isRemoteLayer?.()) return
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
['Text', translate('Text')],
|
|
167
|
-
['Number', translate('Number')],
|
|
168
|
-
['Date', translate('Date')],
|
|
169
|
-
['Datetime', translate('Date and time')],
|
|
170
|
-
['Enum', translate('List of values')],
|
|
171
|
-
['Boolean', translate('Yes / No')],
|
|
172
|
-
]
|
|
173
|
-
const field = this.get(name) || {}
|
|
346
|
+
const field = this.get(name)
|
|
347
|
+
const data = field?.dumps() || {}
|
|
174
348
|
const metadatas = [
|
|
175
349
|
[
|
|
176
350
|
'key',
|
|
@@ -189,7 +363,7 @@ export class Fields extends Map {
|
|
|
189
363
|
},
|
|
190
364
|
],
|
|
191
365
|
]
|
|
192
|
-
const form = new Form(
|
|
366
|
+
const form = new Form(data, metadatas)
|
|
193
367
|
|
|
194
368
|
const [container, { body, addFilter }] = Utils.loadTemplateWithRefs(`
|
|
195
369
|
<div>
|
|
@@ -202,32 +376,34 @@ export class Fields extends Map {
|
|
|
202
376
|
if (this.parent.filters) {
|
|
203
377
|
addFilter.addEventListener('click', () => {
|
|
204
378
|
this.dialog.accept().then(() => {
|
|
205
|
-
this.parent.filters.createFilterForm(
|
|
379
|
+
this.parent.filters.createFilterForm(data.key)
|
|
206
380
|
})
|
|
207
381
|
})
|
|
208
382
|
addFilter.hidden = false
|
|
209
383
|
}
|
|
210
384
|
|
|
211
385
|
return this.dialog.open({ template: container }).then(() => {
|
|
212
|
-
if (!this.validateName(
|
|
386
|
+
if (!this.validateName(data.key, data.key !== name)) {
|
|
213
387
|
this.pull()
|
|
214
388
|
return
|
|
215
389
|
}
|
|
216
390
|
this.parent.sync.startBatch()
|
|
217
391
|
const oldFields = Utils.CopyJSON(this.parent.properties.fields)
|
|
218
392
|
if (!name) {
|
|
219
|
-
this.add(
|
|
220
|
-
} else if (name !== field.
|
|
393
|
+
this.add(data)
|
|
394
|
+
} else if (name !== data.key || field.TYPE !== data.type) {
|
|
221
395
|
this.clear()
|
|
222
396
|
// Keep order on rename
|
|
223
397
|
for (const old of oldFields) {
|
|
224
398
|
if (old.key === name) {
|
|
225
|
-
this.add(
|
|
399
|
+
this.add(data)
|
|
226
400
|
} else {
|
|
227
401
|
this.add(old)
|
|
228
402
|
}
|
|
229
403
|
}
|
|
230
|
-
|
|
404
|
+
if (name !== data.key) {
|
|
405
|
+
this.parent.renameField(name, data.key)
|
|
406
|
+
}
|
|
231
407
|
} else {
|
|
232
408
|
this.push()
|
|
233
409
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// FIXME: this module should not depend on Leaflet
|
|
2
2
|
import {
|
|
3
3
|
DomEvent,
|
|
4
|
-
DomUtil,
|
|
5
4
|
GeoJSON,
|
|
6
5
|
stamp,
|
|
6
|
+
SVG,
|
|
7
7
|
} from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
8
8
|
import {
|
|
9
9
|
uMapAlert as Alert,
|
|
@@ -19,6 +19,7 @@ import { Heat } from '../rendering/layers/heat.js'
|
|
|
19
19
|
import * as Schema from '../schema.js'
|
|
20
20
|
import TableEditor from '../tableeditor.js'
|
|
21
21
|
import * as Utils from '../utils.js'
|
|
22
|
+
import * as DOMUtils from '../domutils.js'
|
|
22
23
|
import { LineString, Point, Polygon } from './features.js'
|
|
23
24
|
import Rules from '../rules.js'
|
|
24
25
|
import { FeatureManager } from '../managers.js'
|
|
@@ -50,7 +51,7 @@ export class DataLayer {
|
|
|
50
51
|
this.parentPane = this._leafletMap.getPane('overlayPane')
|
|
51
52
|
this.pane = this._leafletMap.createPane(`datalayer${stamp(this)}`, this.parentPane)
|
|
52
53
|
// FIXME: should be on layer
|
|
53
|
-
this.renderer =
|
|
54
|
+
this.renderer = new SVG({ pane: this.pane })
|
|
54
55
|
this.defaultProperties = {
|
|
55
56
|
displayOnLoad: true,
|
|
56
57
|
inCaption: true,
|
|
@@ -69,6 +70,7 @@ export class DataLayer {
|
|
|
69
70
|
if (this.properties.rank === undefined) {
|
|
70
71
|
this.properties.rank = this._umap.datalayers.count()
|
|
71
72
|
}
|
|
73
|
+
this._umap.datalayers.add(this)
|
|
72
74
|
|
|
73
75
|
if (!Utils.isObject(this.properties.remoteData)) {
|
|
74
76
|
this.properties.remoteData = {}
|
|
@@ -82,19 +84,17 @@ export class DataLayer {
|
|
|
82
84
|
this.properties.toZoom = this.properties.remoteData.to
|
|
83
85
|
delete this.properties.remoteData.to
|
|
84
86
|
}
|
|
85
|
-
this.connectToMap()
|
|
86
87
|
this.permissions = new DataLayerPermissions(this._umap, this)
|
|
87
|
-
this.rules = new Rules(umap, this)
|
|
88
88
|
|
|
89
89
|
this._needsFetch = this.createdOnServer || this.isRemoteLayer()
|
|
90
|
+
this.fields = new Fields(this, this._umap.dialog)
|
|
91
|
+
this.filters = new Filters(this, this._umap)
|
|
92
|
+
this.rules = new Rules(umap, this)
|
|
93
|
+
this._umap.onDataLayersChanged()
|
|
94
|
+
|
|
90
95
|
if (!this.createdOnServer) {
|
|
91
96
|
if (this.showAtLoad()) this.show()
|
|
92
97
|
}
|
|
93
|
-
if (!this._needsFetch && !this._umap.fields.size) {
|
|
94
|
-
this.properties.fields = getDefaultFields()
|
|
95
|
-
}
|
|
96
|
-
this.fields = new Fields(this, this._umap.dialog)
|
|
97
|
-
this.filters = new Filters(this, this._umap)
|
|
98
98
|
|
|
99
99
|
// Only layers that are displayed on load must be hidden/shown
|
|
100
100
|
// Automatically, others will be shown manually, and thus will
|
|
@@ -146,12 +146,6 @@ export class DataLayer {
|
|
|
146
146
|
this.properties.rank = value
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
get fieldKeys() {
|
|
150
|
-
// Needed to get a similar API from layer and uMap, but
|
|
151
|
-
// uMap would return concat of all datalayers fields
|
|
152
|
-
return Array.from(this.fields.keys())
|
|
153
|
-
}
|
|
154
|
-
|
|
155
149
|
get sortKey() {
|
|
156
150
|
return this.getProperty('sortKey') || U.DEFAULT_LABEL_KEY
|
|
157
151
|
}
|
|
@@ -230,27 +224,28 @@ export class DataLayer {
|
|
|
230
224
|
}
|
|
231
225
|
|
|
232
226
|
showAtLoad() {
|
|
233
|
-
return this.
|
|
227
|
+
return this.autoVisibility && this.showAtZoom()
|
|
234
228
|
}
|
|
235
229
|
|
|
236
|
-
get
|
|
237
|
-
if (this.
|
|
230
|
+
get autoVisibility() {
|
|
231
|
+
if (this._autoVisibility === undefined) {
|
|
238
232
|
if (this._umap.datalayersFromQueryString) {
|
|
239
233
|
const datalayerIds = this._umap.datalayersFromQueryString
|
|
240
|
-
this.
|
|
234
|
+
this._autoVisibility = datalayerIds.includes(this.id.toString())
|
|
241
235
|
if (this.properties.old_id) {
|
|
242
|
-
this.
|
|
243
|
-
this.
|
|
236
|
+
this._autoVisibility =
|
|
237
|
+
this._autoVisibility ||
|
|
238
|
+
datalayerIds.includes(this.properties.old_id.toString())
|
|
244
239
|
}
|
|
245
240
|
} else {
|
|
246
|
-
this.
|
|
241
|
+
this._autoVisibility = this.properties.displayOnLoad
|
|
247
242
|
}
|
|
248
243
|
}
|
|
249
|
-
return this.
|
|
244
|
+
return this._autoVisibility
|
|
250
245
|
}
|
|
251
246
|
|
|
252
|
-
set
|
|
253
|
-
this.
|
|
247
|
+
set autoVisibility(value) {
|
|
248
|
+
this._autoVisibility = value
|
|
254
249
|
}
|
|
255
250
|
|
|
256
251
|
insertBefore(other) {
|
|
@@ -356,10 +351,15 @@ export class DataLayer {
|
|
|
356
351
|
|
|
357
352
|
async getUrl(url, initialUrl) {
|
|
358
353
|
const response = await this._umap.request.get(url)
|
|
359
|
-
return new Promise((resolve) => {
|
|
354
|
+
return new Promise(async (resolve) => {
|
|
360
355
|
if (response?.ok) {
|
|
361
356
|
this._umap.modifiedAt = response.headers.get('last-modified')
|
|
362
|
-
|
|
357
|
+
const id = Math.random()
|
|
358
|
+
this._umap.loader.start(id)
|
|
359
|
+
const raw = await response.text()
|
|
360
|
+
const promise = resolve(raw)
|
|
361
|
+
this._umap.loader.stop(id)
|
|
362
|
+
return promise
|
|
363
363
|
}
|
|
364
364
|
Alert.error(
|
|
365
365
|
translate('Cannot load remote data for layer "{layer}" with url "{url}"', {
|
|
@@ -412,11 +412,6 @@ export class DataLayer {
|
|
|
412
412
|
this.resetLayer()
|
|
413
413
|
}
|
|
414
414
|
|
|
415
|
-
connectToMap() {
|
|
416
|
-
this._umap.datalayers.add(this)
|
|
417
|
-
this._umap.onDataLayersChanged()
|
|
418
|
-
}
|
|
419
|
-
|
|
420
415
|
_dataUrl() {
|
|
421
416
|
let url = this._umap.urls.get('datalayer_view', {
|
|
422
417
|
pk: this.id,
|
|
@@ -451,6 +446,10 @@ export class DataLayer {
|
|
|
451
446
|
this._umap.featuresIndex[feature.getSlug()] = feature
|
|
452
447
|
// TODO: quid for remote data ?
|
|
453
448
|
this.inferFields(feature)
|
|
449
|
+
if (!this.fields.size && !this._umap.fields.size) {
|
|
450
|
+
this.properties.fields = getDefaultFields()
|
|
451
|
+
this.fields.pull()
|
|
452
|
+
}
|
|
454
453
|
try {
|
|
455
454
|
this.showFeature(feature)
|
|
456
455
|
} catch (error) {
|
|
@@ -527,15 +526,15 @@ export class DataLayer {
|
|
|
527
526
|
this.features.forEach((feature) => callback(feature))
|
|
528
527
|
}
|
|
529
528
|
|
|
530
|
-
sortedValues(
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
.filter((val, idx, arr) => arr.indexOf(val) === idx)
|
|
535
|
-
.sort(Utils.naturalSort)
|
|
529
|
+
sortedValues(key) {
|
|
530
|
+
const field = this.fields.get(key) || this._umap.fields.get(key)
|
|
531
|
+
if (!field) return []
|
|
532
|
+
return field.values(this.features.all()).sort(Utils.naturalSort)
|
|
536
533
|
}
|
|
537
534
|
|
|
538
535
|
addData(geojson, sync) {
|
|
536
|
+
const id = Math.random()
|
|
537
|
+
this._umap.loader.start(id)
|
|
539
538
|
let data = []
|
|
540
539
|
this._batch = true
|
|
541
540
|
try {
|
|
@@ -548,6 +547,7 @@ export class DataLayer {
|
|
|
548
547
|
}
|
|
549
548
|
this._batch = false
|
|
550
549
|
this.dataChanged()
|
|
550
|
+
this._umap.loader.stop(id)
|
|
551
551
|
return data
|
|
552
552
|
}
|
|
553
553
|
|
|
@@ -777,7 +777,11 @@ export class DataLayer {
|
|
|
777
777
|
},
|
|
778
778
|
],
|
|
779
779
|
]
|
|
780
|
-
|
|
780
|
+
container.appendChild(
|
|
781
|
+
DOMUtils.loadTemplate(`
|
|
782
|
+
<h3><i class="icon icon-16 icon-layers"></i>${translate('Layer properties')}</h3>
|
|
783
|
+
`)
|
|
784
|
+
)
|
|
781
785
|
const builder = new MutatingForm(this, metadataFields)
|
|
782
786
|
builder.on('set', ({ detail }) => {
|
|
783
787
|
this._umap.onDataLayersChanged()
|
|
@@ -823,7 +827,7 @@ export class DataLayer {
|
|
|
823
827
|
const builder = new MutatingForm(this, fields, {
|
|
824
828
|
id: 'datalayer-advanced-properties',
|
|
825
829
|
})
|
|
826
|
-
const shapeFieldset =
|
|
830
|
+
const shapeFieldset = DOMUtils.createFieldset(
|
|
827
831
|
container,
|
|
828
832
|
translate('Shape properties')
|
|
829
833
|
)
|
|
@@ -848,7 +852,7 @@ export class DataLayer {
|
|
|
848
852
|
this.reindex()
|
|
849
853
|
}
|
|
850
854
|
})
|
|
851
|
-
const advancedFieldset =
|
|
855
|
+
const advancedFieldset = DOMUtils.createFieldset(
|
|
852
856
|
container,
|
|
853
857
|
translate('Advanced properties')
|
|
854
858
|
)
|
|
@@ -867,7 +871,7 @@ export class DataLayer {
|
|
|
867
871
|
'properties.interactive',
|
|
868
872
|
]
|
|
869
873
|
const builder = new MutatingForm(this, fields)
|
|
870
|
-
const popupFieldset =
|
|
874
|
+
const popupFieldset = DOMUtils.createFieldset(
|
|
871
875
|
container,
|
|
872
876
|
translate('Interaction options')
|
|
873
877
|
)
|
|
@@ -885,7 +889,7 @@ export class DataLayer {
|
|
|
885
889
|
'properties.textPathPosition',
|
|
886
890
|
]
|
|
887
891
|
const builder = new MutatingForm(this, fields)
|
|
888
|
-
const fieldset =
|
|
892
|
+
const fieldset = DOMUtils.createFieldset(container, translate('Line decoration'))
|
|
889
893
|
fieldset.appendChild(builder.build())
|
|
890
894
|
}
|
|
891
895
|
|
|
@@ -935,23 +939,21 @@ export class DataLayer {
|
|
|
935
939
|
fields.push('properties.remoteData.ttl')
|
|
936
940
|
}
|
|
937
941
|
|
|
938
|
-
const remoteDataContainer =
|
|
942
|
+
const remoteDataContainer = DOMUtils.createFieldset(
|
|
939
943
|
container,
|
|
940
944
|
translate('Remote data')
|
|
941
945
|
)
|
|
942
946
|
const builder = new MutatingForm(this, fields)
|
|
943
947
|
remoteDataContainer.appendChild(builder.build())
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
this
|
|
950
|
-
)
|
|
948
|
+
const button = DOMUtils.loadTemplate(`
|
|
949
|
+
<button class="umap-verify" type="button">${translate('Verify remote URL')}</button>
|
|
950
|
+
`)
|
|
951
|
+
button.addEventListener('click', () => this.fetchRemoteData(true))
|
|
952
|
+
remoteDataContainer.appendChild(button)
|
|
951
953
|
}
|
|
952
954
|
|
|
953
955
|
_buildAdvancedActions(container) {
|
|
954
|
-
const advancedActions =
|
|
956
|
+
const advancedActions = DOMUtils.createFieldset(
|
|
955
957
|
container,
|
|
956
958
|
translate('Advanced actions')
|
|
957
959
|
)
|
|
@@ -991,7 +993,7 @@ export class DataLayer {
|
|
|
991
993
|
if (!this._umap.editEnabled) {
|
|
992
994
|
return
|
|
993
995
|
}
|
|
994
|
-
const container =
|
|
996
|
+
const container = document.createElement('div')
|
|
995
997
|
this._editMetadata(container)
|
|
996
998
|
this._editLayerProperties(container)
|
|
997
999
|
this._editShapeProperties(container)
|
|
@@ -1008,15 +1010,13 @@ export class DataLayer {
|
|
|
1008
1010
|
|
|
1009
1011
|
this._buildAdvancedActions(container)
|
|
1010
1012
|
|
|
1011
|
-
const backButton =
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
translate('Back to layers')
|
|
1015
|
-
)
|
|
1013
|
+
const backButton = DOMUtils.loadTemplate(`
|
|
1014
|
+
<button class="icon icon-16 icon-back" type="button" title="${translate('Back to layers')}"></button>
|
|
1015
|
+
`)
|
|
1016
1016
|
// Fixme: remove me when this is merged and released
|
|
1017
1017
|
// https://github.com/Leaflet/Leaflet/pull/9052
|
|
1018
1018
|
DomEvent.disableClickPropagation(backButton)
|
|
1019
|
-
|
|
1019
|
+
backButton.addEventListener('click', () => this._umap.editDatalayers())
|
|
1020
1020
|
|
|
1021
1021
|
return this._umap.editPanel.open({
|
|
1022
1022
|
content: container,
|
|
@@ -1067,14 +1067,14 @@ export class DataLayer {
|
|
|
1067
1067
|
button.addEventListener('click', () => this.restore(data.ref))
|
|
1068
1068
|
}
|
|
1069
1069
|
|
|
1070
|
-
const versionsContainer =
|
|
1071
|
-
|
|
1070
|
+
const versionsContainer = DOMUtils.createFieldset(container, translate('Versions'))
|
|
1071
|
+
versionsContainer.closest('details').addEventListener('toggle', async (event) => {
|
|
1072
|
+
if (event.target.open) {
|
|
1072
1073
|
const [{ versions }, response, error] = await this._umap.server.get(
|
|
1073
1074
|
this.getVersionsUrl()
|
|
1074
1075
|
)
|
|
1075
1076
|
if (!error) versions.forEach(appendVersion)
|
|
1076
|
-
}
|
|
1077
|
-
context: this,
|
|
1077
|
+
}
|
|
1078
1078
|
})
|
|
1079
1079
|
}
|
|
1080
1080
|
|
|
@@ -1124,7 +1124,7 @@ export class DataLayer {
|
|
|
1124
1124
|
// From now on, do not try to how/hide
|
|
1125
1125
|
// automatically this layer, as user
|
|
1126
1126
|
// has taken control on this.
|
|
1127
|
-
this.
|
|
1127
|
+
this.autoVisibility = false
|
|
1128
1128
|
let display = force
|
|
1129
1129
|
if (force === undefined) {
|
|
1130
1130
|
if (!this.isVisible()) display = true
|
|
@@ -1290,7 +1290,7 @@ export class DataLayer {
|
|
|
1290
1290
|
|
|
1291
1291
|
this.setReferenceVersion({ response, sync: true })
|
|
1292
1292
|
|
|
1293
|
-
this.
|
|
1293
|
+
this._umap.onDataLayersChanged()
|
|
1294
1294
|
this.redraw() // Needed for reordering features
|
|
1295
1295
|
return true
|
|
1296
1296
|
}
|
|
@@ -1345,7 +1345,10 @@ export class DataLayer {
|
|
|
1345
1345
|
rules.set(rule.condition, rule)
|
|
1346
1346
|
}
|
|
1347
1347
|
for (const rule of this._umap.rules) {
|
|
1348
|
-
if (
|
|
1348
|
+
if (
|
|
1349
|
+
!rules.has(rule.condition) &&
|
|
1350
|
+
(this.fields.has(rule.field.key) || this._umap.fields.has(rule.field.key))
|
|
1351
|
+
) {
|
|
1349
1352
|
rules.set(rule.condition, rule)
|
|
1350
1353
|
}
|
|
1351
1354
|
}
|
|
@@ -1364,31 +1367,17 @@ export class DataLayer {
|
|
|
1364
1367
|
}
|
|
1365
1368
|
|
|
1366
1369
|
renderToolbox(container) {
|
|
1367
|
-
const toggle =
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
)
|
|
1377
|
-
|
|
1378
|
-
container,
|
|
1379
|
-
'icon-zoom',
|
|
1380
|
-
translate('Zoom to layer extent')
|
|
1381
|
-
)
|
|
1382
|
-
const edit = DomUtil.createButtonIcon(
|
|
1383
|
-
container,
|
|
1384
|
-
'icon-edit show-on-edit',
|
|
1385
|
-
translate('Edit')
|
|
1386
|
-
)
|
|
1387
|
-
const remove = DomUtil.createButtonIcon(
|
|
1388
|
-
container,
|
|
1389
|
-
'icon-delete show-on-edit',
|
|
1390
|
-
translate('Delete layer')
|
|
1391
|
-
)
|
|
1370
|
+
const [span, { toggle, table, zoomTo, edit, remove }] =
|
|
1371
|
+
DOMUtils.loadTemplateWithRefs(`
|
|
1372
|
+
<span>
|
|
1373
|
+
<button class="icon icon-16 icon-eye" title="${translate('Show/hide layer')}" type="button" data-ref="toggle"></button>
|
|
1374
|
+
<button class="icon icon-16 icon-table show-on-edit" title="${translate('Edit properties in a table')}" type="button" data-ref="table"></button>
|
|
1375
|
+
<button class="icon icon-16 icon-zoom" title="${translate('Zoom to layer extent')}" type="button" data-ref="zoomTo"></button>
|
|
1376
|
+
<button class="icon icon-16 icon-edit show-on-edit" title="${translate('Edit')}" type="button" data-ref="edit"></button>
|
|
1377
|
+
<button class="icon icon-16 icon-delete show-on-edit" title="${translate('Delete layer')}" type="button" data-ref="remove"></button>
|
|
1378
|
+
</span>
|
|
1379
|
+
`)
|
|
1380
|
+
container.appendChild(span)
|
|
1392
1381
|
if (this.isReadOnly()) {
|
|
1393
1382
|
container.classList.add('readonly')
|
|
1394
1383
|
} else {
|
|
@@ -1412,7 +1401,7 @@ export class DataLayer {
|
|
|
1412
1401
|
propagateDelete() {
|
|
1413
1402
|
const els = this.getHidableElements()
|
|
1414
1403
|
for (const el of els) {
|
|
1415
|
-
|
|
1404
|
+
el.remove()
|
|
1416
1405
|
}
|
|
1417
1406
|
}
|
|
1418
1407
|
|
|
@@ -1425,15 +1414,15 @@ export class DataLayer {
|
|
|
1425
1414
|
|
|
1426
1415
|
propagateHide() {
|
|
1427
1416
|
const els = this.getHidableElements()
|
|
1428
|
-
for (
|
|
1429
|
-
|
|
1417
|
+
for (const el of els) {
|
|
1418
|
+
el.classList.add('off')
|
|
1430
1419
|
}
|
|
1431
1420
|
}
|
|
1432
1421
|
|
|
1433
1422
|
propagateShow() {
|
|
1434
1423
|
const els = this.getHidableElements()
|
|
1435
|
-
for (
|
|
1436
|
-
|
|
1424
|
+
for (const el of els) {
|
|
1425
|
+
el.classList.remove('off')
|
|
1437
1426
|
}
|
|
1438
1427
|
}
|
|
1439
1428
|
}
|