umap-project 3.3.6__py3-none-any.whl → 3.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- umap/__init__.py +1 -1
- umap/context_processors.py +4 -1
- umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- umap/locale/cs_CZ/LC_MESSAGES/django.po +43 -33
- umap/locale/da/LC_MESSAGES/django.mo +0 -0
- umap/locale/da/LC_MESSAGES/django.po +43 -33
- umap/locale/de/LC_MESSAGES/django.mo +0 -0
- umap/locale/de/LC_MESSAGES/django.po +35 -29
- umap/locale/el/LC_MESSAGES/django.mo +0 -0
- umap/locale/el/LC_MESSAGES/django.po +35 -29
- umap/locale/en/LC_MESSAGES/django.po +47 -41
- umap/locale/es/LC_MESSAGES/django.mo +0 -0
- umap/locale/es/LC_MESSAGES/django.po +43 -33
- umap/locale/et/LC_MESSAGES/django.mo +0 -0
- umap/locale/et/LC_MESSAGES/django.po +58 -54
- umap/locale/eu/LC_MESSAGES/django.mo +0 -0
- umap/locale/eu/LC_MESSAGES/django.po +43 -33
- umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
- umap/locale/fa_IR/LC_MESSAGES/django.po +43 -33
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +36 -30
- umap/locale/gl/LC_MESSAGES/django.mo +0 -0
- umap/locale/gl/LC_MESSAGES/django.po +43 -33
- umap/locale/hu/LC_MESSAGES/django.mo +0 -0
- umap/locale/hu/LC_MESSAGES/django.po +35 -29
- umap/locale/is/LC_MESSAGES/django.mo +0 -0
- umap/locale/is/LC_MESSAGES/django.po +43 -33
- umap/locale/it/LC_MESSAGES/django.mo +0 -0
- umap/locale/it/LC_MESSAGES/django.po +43 -33
- umap/locale/nl/LC_MESSAGES/django.mo +0 -0
- umap/locale/nl/LC_MESSAGES/django.po +35 -29
- umap/locale/pl/LC_MESSAGES/django.mo +0 -0
- umap/locale/pl/LC_MESSAGES/django.po +114 -103
- umap/locale/pt/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt/LC_MESSAGES/django.po +43 -33
- umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
- umap/locale/th_TH/LC_MESSAGES/django.po +310 -109
- umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
- umap/locale/zh_TW/LC_MESSAGES/django.po +80 -70
- umap/management/commands/switch_user.py +2 -2
- umap/migrations/0018_datalayer_uuid.py +1 -1
- umap/models.py +7 -3
- umap/settings/local.py.sample +1 -1
- umap/static/umap/base.css +89 -32
- umap/static/umap/content.css +129 -33
- umap/static/umap/css/bar.css +82 -20
- umap/static/umap/css/browser.css +163 -0
- umap/static/umap/css/contextmenu.css +15 -0
- umap/static/umap/css/dialog.css +36 -16
- umap/static/umap/css/form.css +123 -33
- umap/static/umap/css/icon.css +46 -3
- umap/static/umap/css/panel.css +7 -3
- umap/static/umap/css/popup.css +34 -8
- umap/static/umap/css/tooltip.css +8 -4
- umap/static/umap/img/16-white.svg +26 -8
- umap/static/umap/img/16.svg +1 -1
- umap/static/umap/img/source/16-white.svg +36 -18
- umap/static/umap/img/source/16.svg +1 -1
- umap/static/umap/js/components/alerts/alert.css +69 -31
- umap/static/umap/js/components/alerts/alert.js +20 -2
- umap/static/umap/js/components/base.js +1 -1
- umap/static/umap/js/modules/browser.js +69 -61
- umap/static/umap/js/modules/caption.js +10 -7
- umap/static/umap/js/modules/data/features.js +85 -60
- umap/static/umap/js/modules/data/fields.js +446 -0
- umap/static/umap/js/modules/data/layer.js +78 -184
- umap/static/umap/js/modules/domutils.js +109 -0
- umap/static/umap/js/modules/filters.js +780 -0
- umap/static/umap/js/modules/form/builder.js +8 -5
- umap/static/umap/js/modules/form/fields.js +111 -221
- umap/static/umap/js/modules/formatter.js +24 -1
- umap/static/umap/js/modules/help.js +4 -3
- umap/static/umap/js/modules/i18n.js +1 -1
- umap/static/umap/js/modules/importer.js +1 -1
- umap/static/umap/js/modules/importers/opendata.js +15 -0
- umap/static/umap/js/modules/importers/openrouteservice.js +6 -1
- umap/static/umap/js/modules/managers.js +2 -2
- umap/static/umap/js/modules/permissions.js +39 -31
- umap/static/umap/js/modules/rendering/controls.js +11 -9
- umap/static/umap/js/modules/rendering/icon.js +3 -8
- umap/static/umap/js/modules/rendering/layers/base.js +1 -1
- umap/static/umap/js/modules/rendering/layers/classified.js +18 -11
- umap/static/umap/js/modules/rendering/layers/cluster.js +5 -3
- umap/static/umap/js/modules/rendering/layers/heat.js +27 -21
- umap/static/umap/js/modules/rendering/template.js +50 -23
- umap/static/umap/js/modules/rendering/ui.js +29 -23
- umap/static/umap/js/modules/rules.js +38 -44
- umap/static/umap/js/modules/schema.js +3 -6
- umap/static/umap/js/modules/share.js +5 -4
- umap/static/umap/js/modules/tableeditor.js +50 -38
- umap/static/umap/js/modules/templates.js +2 -3
- umap/static/umap/js/modules/ui/bar.js +55 -23
- umap/static/umap/js/modules/ui/dialog.js +38 -27
- umap/static/umap/js/modules/ui/panel.js +23 -8
- umap/static/umap/js/modules/ui/tooltip.js +6 -5
- umap/static/umap/js/modules/umap.js +151 -56
- umap/static/umap/js/modules/utils.js +24 -2
- umap/static/umap/js/umap.core.js +1 -110
- umap/static/umap/locale/am_ET.js +52 -17
- umap/static/umap/locale/am_ET.json +52 -17
- umap/static/umap/locale/ar.js +52 -17
- umap/static/umap/locale/ar.json +52 -17
- umap/static/umap/locale/ast.js +52 -17
- umap/static/umap/locale/ast.json +52 -17
- umap/static/umap/locale/bg.js +52 -17
- umap/static/umap/locale/bg.json +52 -17
- umap/static/umap/locale/br.js +48 -22
- umap/static/umap/locale/br.json +48 -22
- umap/static/umap/locale/ca.js +52 -17
- umap/static/umap/locale/ca.json +52 -17
- umap/static/umap/locale/cs_CZ.js +52 -17
- umap/static/umap/locale/cs_CZ.json +52 -17
- umap/static/umap/locale/da.js +54 -17
- umap/static/umap/locale/da.json +54 -17
- umap/static/umap/locale/de.js +51 -16
- umap/static/umap/locale/de.json +51 -16
- umap/static/umap/locale/el.js +52 -17
- umap/static/umap/locale/el.json +52 -17
- umap/static/umap/locale/en.js +53 -16
- umap/static/umap/locale/en.json +53 -16
- umap/static/umap/locale/en_US.json +52 -17
- umap/static/umap/locale/es.js +54 -17
- umap/static/umap/locale/es.json +54 -17
- umap/static/umap/locale/et.js +91 -56
- umap/static/umap/locale/et.json +91 -56
- umap/static/umap/locale/eu.js +84 -49
- umap/static/umap/locale/eu.json +84 -49
- umap/static/umap/locale/fa_IR.js +52 -17
- umap/static/umap/locale/fa_IR.json +52 -17
- umap/static/umap/locale/fi.js +52 -17
- umap/static/umap/locale/fi.json +52 -17
- umap/static/umap/locale/fr.js +53 -16
- umap/static/umap/locale/fr.json +53 -16
- umap/static/umap/locale/gl.js +52 -17
- umap/static/umap/locale/gl.json +52 -17
- umap/static/umap/locale/he.js +52 -17
- umap/static/umap/locale/he.json +52 -17
- umap/static/umap/locale/hr.js +52 -17
- umap/static/umap/locale/hr.json +52 -17
- umap/static/umap/locale/hu.js +59 -24
- umap/static/umap/locale/hu.json +59 -24
- umap/static/umap/locale/id.js +52 -17
- umap/static/umap/locale/id.json +52 -17
- umap/static/umap/locale/is.js +52 -17
- umap/static/umap/locale/is.json +52 -17
- umap/static/umap/locale/it.js +52 -17
- umap/static/umap/locale/it.json +52 -17
- umap/static/umap/locale/ja.js +52 -17
- umap/static/umap/locale/ja.json +52 -17
- umap/static/umap/locale/ko.js +52 -17
- umap/static/umap/locale/ko.json +52 -17
- umap/static/umap/locale/lt.js +52 -17
- umap/static/umap/locale/lt.json +52 -17
- umap/static/umap/locale/ms.js +52 -17
- umap/static/umap/locale/ms.json +52 -17
- umap/static/umap/locale/nl.js +52 -17
- umap/static/umap/locale/nl.json +52 -17
- umap/static/umap/locale/no.js +52 -17
- umap/static/umap/locale/no.json +52 -17
- umap/static/umap/locale/pl.js +53 -17
- umap/static/umap/locale/pl.json +53 -17
- umap/static/umap/locale/pl_PL.json +52 -17
- umap/static/umap/locale/pt.js +52 -17
- umap/static/umap/locale/pt.json +52 -17
- umap/static/umap/locale/pt_BR.js +52 -17
- umap/static/umap/locale/pt_BR.json +52 -17
- umap/static/umap/locale/pt_PT.js +52 -17
- umap/static/umap/locale/pt_PT.json +52 -17
- umap/static/umap/locale/ro.js +52 -17
- umap/static/umap/locale/ro.json +52 -17
- umap/static/umap/locale/ru.js +52 -17
- umap/static/umap/locale/ru.json +52 -17
- umap/static/umap/locale/si.js +1 -1
- umap/static/umap/locale/si.json +1 -1
- umap/static/umap/locale/sk_SK.js +52 -17
- umap/static/umap/locale/sk_SK.json +52 -17
- umap/static/umap/locale/sl.js +52 -17
- umap/static/umap/locale/sl.json +52 -17
- umap/static/umap/locale/sr.js +52 -17
- umap/static/umap/locale/sr.json +52 -17
- umap/static/umap/locale/sv.js +52 -17
- umap/static/umap/locale/sv.json +52 -17
- umap/static/umap/locale/th_TH.js +52 -17
- umap/static/umap/locale/th_TH.json +52 -17
- umap/static/umap/locale/tr.js +52 -17
- umap/static/umap/locale/tr.json +52 -17
- umap/static/umap/locale/uk_UA.js +52 -17
- umap/static/umap/locale/uk_UA.json +52 -17
- umap/static/umap/locale/vi.js +52 -17
- umap/static/umap/locale/vi.json +52 -17
- umap/static/umap/locale/vi_VN.json +52 -17
- umap/static/umap/locale/zh.js +52 -17
- umap/static/umap/locale/zh.json +52 -17
- umap/static/umap/locale/zh_CN.json +52 -17
- umap/static/umap/locale/zh_TW.Big5.json +52 -17
- umap/static/umap/locale/zh_TW.js +52 -16
- umap/static/umap/locale/zh_TW.json +52 -16
- umap/static/umap/map.css +63 -226
- umap/static/umap/unittests/utils.js +18 -0
- umap/static/umap/vars.css +23 -5
- umap/templates/umap/components/alerts/alert.html +32 -29
- umap/templates/umap/css.html +2 -1
- umap/templates/umap/login_popup_end.html +18 -9
- umap/templates/umap/user_map_table.html +7 -2
- umap/tests/integration/conftest.py +10 -6
- umap/tests/integration/test_anonymous_owned_map.py +90 -37
- umap/tests/integration/test_basics.py +25 -1
- umap/tests/integration/test_browser.py +37 -0
- umap/tests/integration/test_conditional_rules.py +107 -52
- umap/tests/integration/test_draw_polygon.py +6 -0
- umap/tests/integration/test_draw_polyline.py +11 -0
- umap/tests/integration/test_edit_marker.py +1 -1
- umap/tests/integration/test_export_map.py +19 -0
- umap/tests/integration/test_fields.py +541 -0
- umap/tests/integration/test_filters.py +616 -0
- umap/tests/integration/test_iframe.py +1 -1
- umap/tests/integration/test_import.py +38 -42
- umap/tests/integration/test_map_preview.py +1 -1
- umap/tests/integration/test_picto.py +1 -1
- umap/tests/integration/test_popup.py +31 -0
- umap/tests/integration/test_remote_data.py +60 -4
- umap/tests/integration/test_save.py +1 -1
- umap/tests/integration/test_share.py +4 -4
- umap/tests/integration/test_tableeditor.py +31 -7
- umap/tests/integration/test_websocket_sync.py +71 -20
- umap/tests/test_dashboard.py +11 -1
- umap/tests/test_statics.py +2 -2
- umap/tests/test_utils.py +19 -2
- umap/tests/test_views.py +1 -1
- umap/urls.py +1 -0
- umap/utils.py +8 -1
- umap/views.py +5 -0
- {umap_project-3.3.6.dist-info → umap_project-3.4.0.dist-info}/METADATA +15 -15
- {umap_project-3.3.6.dist-info → umap_project-3.4.0.dist-info}/RECORD +237 -233
- umap/static/umap/js/modules/facets.js +0 -164
- umap/tests/integration/test_facets_browser.py +0 -279
- {umap_project-3.3.6.dist-info → umap_project-3.4.0.dist-info}/WHEEL +0 -0
- {umap_project-3.3.6.dist-info → umap_project-3.4.0.dist-info}/entry_points.txt +0 -0
- {umap_project-3.3.6.dist-info → umap_project-3.4.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -2,7 +2,6 @@ import { DomEvent, DomUtil, stamp } from '../../vendors/leaflet/leaflet-src.esm.
|
|
|
2
2
|
import { Form } from './form/builder.js'
|
|
3
3
|
import { EXPORT_FORMATS } from './formatter.js'
|
|
4
4
|
import { translate } from './i18n.js'
|
|
5
|
-
import * as Icon from './rendering/icon.js'
|
|
6
5
|
import ContextMenu from './ui/contextmenu.js'
|
|
7
6
|
import * as Utils from './utils.js'
|
|
8
7
|
import { SCHEMA } from './schema.js'
|
|
@@ -23,28 +22,22 @@ export default class Browser {
|
|
|
23
22
|
if (feature.isFiltered()) return
|
|
24
23
|
if (this.options.inBbox && !feature.isOnScreen(this.bounds)) return
|
|
25
24
|
const template = `
|
|
26
|
-
<li class="feature ${feature.getClassName()}">
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
<span
|
|
25
|
+
<li class="feature ${feature.getClassName()} ${feature.getUniqueClassName()} with-toolbox">
|
|
26
|
+
<span>
|
|
27
|
+
<i class="icon icon-16 icon-${feature.getClassName()} feature-color" data-ref=colorBox></i>
|
|
28
|
+
<span class="feature-title truncate" data-ref=label></span>
|
|
29
|
+
</span>
|
|
30
|
+
<span>
|
|
31
|
+
<button class="icon icon-16 icon-zoom" title="${translate('Bring feature to center')}" data-ref=zoom></button
|
|
32
|
+
><button class="icon icon-16 show-on-edit icon-edit" title="${translate('Edit this feature')}" data-ref=edit></button
|
|
33
|
+
><button class="icon icon-16 show-on-edit icon-delete" title="${translate('Delete this feature')}" data-ref=remove></button>
|
|
34
|
+
</span>
|
|
32
35
|
</li>
|
|
33
36
|
`
|
|
34
37
|
const [row, { zoom, edit, remove, colorBox, label }] =
|
|
35
38
|
Utils.loadTemplateWithRefs(template)
|
|
36
39
|
label.textContent = label.title = feature.getDisplayName() || '—'
|
|
37
|
-
|
|
38
|
-
? Icon.formatUrl(feature._getIconUrl(), feature)
|
|
39
|
-
: null
|
|
40
|
-
const bgcolor = feature.getPreviewColor()
|
|
41
|
-
colorBox.style.backgroundColor = bgcolor
|
|
42
|
-
if (symbol && symbol !== SCHEMA.iconUrl.default) {
|
|
43
|
-
const icon = Icon.makeElement(symbol, colorBox)
|
|
44
|
-
Icon.setContrast(icon, colorBox, symbol, bgcolor)
|
|
45
|
-
} else if (DomUtil.contrastedColor(colorBox, bgcolor)) {
|
|
46
|
-
colorBox.classList.add('icon-white')
|
|
47
|
-
}
|
|
40
|
+
feature.makePreview(colorBox)
|
|
48
41
|
const viewFeature = (e) => {
|
|
49
42
|
feature.zoomTo({ ...e, callback: () => feature.view() })
|
|
50
43
|
}
|
|
@@ -65,21 +58,23 @@ export default class Browser {
|
|
|
65
58
|
addDataLayer(datalayer, parent) {
|
|
66
59
|
const open = this.mode !== 'layers' ? ' open' : ''
|
|
67
60
|
const [container, { headline, toolbox, label }] = Utils.loadTemplateWithRefs(`
|
|
68
|
-
<details class="datalayer ${datalayer.
|
|
69
|
-
<summary data-ref=headline>
|
|
61
|
+
<details class="datalayer ${datalayer.cssId}" id="${this.datalayerId(datalayer)}"${open}>
|
|
62
|
+
<summary data-ref=headline class="with-toolbox">
|
|
63
|
+
<span>
|
|
64
|
+
<span class="datalayer-name truncate" data-id="${datalayer.id}" data-ref=label></span>
|
|
65
|
+
<span class="datalayer-counter"></span>
|
|
66
|
+
</span>
|
|
70
67
|
<span data-ref=toolbox></span>
|
|
71
|
-
<span class="datalayer-name" data-id="${datalayer.id}" data-ref=label></span>
|
|
72
|
-
<span class="datalayer-counter"></span>
|
|
73
68
|
</summary>
|
|
74
69
|
<ul></ul>
|
|
75
70
|
</details>
|
|
76
71
|
`)
|
|
77
72
|
datalayer.renderToolbox(toolbox)
|
|
78
73
|
parent.appendChild(container)
|
|
79
|
-
this.
|
|
74
|
+
this.updateFeaturesList(datalayer)
|
|
80
75
|
}
|
|
81
76
|
|
|
82
|
-
|
|
77
|
+
updateFeaturesList(datalayer) {
|
|
83
78
|
// Compute once, but use it for each feature later.
|
|
84
79
|
this.bounds = this._leafletMap.getBounds()
|
|
85
80
|
const id = this.datalayerId(datalayer)
|
|
@@ -102,14 +97,14 @@ export default class Browser {
|
|
|
102
97
|
}
|
|
103
98
|
|
|
104
99
|
toggleBadge() {
|
|
105
|
-
Utils.toggleBadge(this.filtersTitle, this.
|
|
106
|
-
Utils.toggleBadge('.umap-control-browse', this.
|
|
100
|
+
Utils.toggleBadge(this.filtersTitle, this.hasActiveFilters())
|
|
101
|
+
Utils.toggleBadge('.umap-control-browse', this.hasActiveFilters())
|
|
107
102
|
}
|
|
108
103
|
|
|
109
104
|
onFormChange() {
|
|
110
105
|
this._umap.datalayers.browsable().map((datalayer) => {
|
|
111
106
|
datalayer.resetLayer(true)
|
|
112
|
-
this.
|
|
107
|
+
this.updateFeaturesList(datalayer)
|
|
113
108
|
if (this._umap.fullPanel?.isOpen()) datalayer.tableEdit()
|
|
114
109
|
})
|
|
115
110
|
this.toggleBadge()
|
|
@@ -123,25 +118,24 @@ export default class Browser {
|
|
|
123
118
|
return !!document.querySelector('.on .umap-browser')
|
|
124
119
|
}
|
|
125
120
|
|
|
126
|
-
|
|
127
|
-
return !!this.options.filter || this._umap.
|
|
121
|
+
hasActiveFilters() {
|
|
122
|
+
return !!this.options.filter || this._umap.hasActiveFilters()
|
|
128
123
|
}
|
|
129
124
|
|
|
130
125
|
onMoveEnd() {
|
|
131
126
|
if (!this.isOpen()) return
|
|
132
|
-
const isListDynamic = this.options.inBbox
|
|
133
127
|
this._umap.datalayers.browsable().map((datalayer) => {
|
|
134
|
-
if (!
|
|
135
|
-
this.
|
|
128
|
+
if (!this.options.inBbox && !datalayer.hasDynamicData()) return
|
|
129
|
+
this.updateFeaturesList(datalayer)
|
|
136
130
|
})
|
|
137
131
|
}
|
|
138
132
|
|
|
139
133
|
update() {
|
|
140
134
|
if (!this.isOpen()) return
|
|
141
135
|
this.dataContainer.innerHTML = ''
|
|
142
|
-
this._umap.datalayers.browsable()
|
|
136
|
+
for (const datalayer of this._umap.datalayers.browsable()) {
|
|
143
137
|
this.addDataLayer(datalayer, this.dataContainer)
|
|
144
|
-
}
|
|
138
|
+
}
|
|
145
139
|
}
|
|
146
140
|
|
|
147
141
|
open(mode) {
|
|
@@ -151,11 +145,14 @@ export default class Browser {
|
|
|
151
145
|
<div>
|
|
152
146
|
<h3><i class="icon icon-16 icon-layers"></i>${translate('Data browser')}</h3>
|
|
153
147
|
<details class="filters" data-ref="details">
|
|
154
|
-
<summary data-ref=filtersTitle
|
|
148
|
+
<summary data-ref=filtersTitle>
|
|
149
|
+
<i class="icon icon-16 icon-filters"></i>${translate('Filters')}
|
|
150
|
+
</summary>
|
|
151
|
+
<button type="button" class="show-on-edit flat" data-ref=manageFilters>${translate('Manage filters')}</button>
|
|
155
152
|
<fieldset>
|
|
156
|
-
<div data-ref=formContainer>
|
|
153
|
+
<div data-ref="formContainer" class="formbox">
|
|
157
154
|
</div>
|
|
158
|
-
<button class="flat" type="button" data-ref=reset><i class="icon icon-16 icon-restore" title=""></i
|
|
155
|
+
<button class="flat" type="button" data-ref=reset><i class="icon icon-16 icon-restore" title=""></i> ${translate('Reset all')}</button>
|
|
159
156
|
</fieldset>
|
|
160
157
|
</details>
|
|
161
158
|
<div class="main-toolbox">
|
|
@@ -177,6 +174,7 @@ export default class Browser {
|
|
|
177
174
|
dataContainer,
|
|
178
175
|
formContainer,
|
|
179
176
|
reset,
|
|
177
|
+
manageFilters,
|
|
180
178
|
},
|
|
181
179
|
] = Utils.loadTemplateWithRefs(template)
|
|
182
180
|
// HOTFIX. Remove when this is released:
|
|
@@ -187,43 +185,53 @@ export default class Browser {
|
|
|
187
185
|
fitBounds.addEventListener('click', () => this._umap.fitDataBounds())
|
|
188
186
|
download.addEventListener('click', () => this.downloadVisible(download))
|
|
189
187
|
download.hidden = this._umap.getProperty('embedControl') === false
|
|
188
|
+
reset.addEventListener('click', () => this.resetFilters())
|
|
189
|
+
manageFilters.addEventListener('click', () => {
|
|
190
|
+
this._umap.edit().then((panel) => panel.scrollTo('details#fields-management'))
|
|
191
|
+
this._umap.filters.edit()
|
|
192
|
+
})
|
|
190
193
|
|
|
191
194
|
this.filtersTitle = filtersTitle
|
|
192
195
|
this.dataContainer = dataContainer
|
|
193
196
|
this.formContainer = formContainer
|
|
194
197
|
this.toggleBadge()
|
|
198
|
+
this.buildFilters()
|
|
199
|
+
this._umap.panel.open({
|
|
200
|
+
content: container,
|
|
201
|
+
className: 'umap-browser',
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
this.update()
|
|
205
|
+
}
|
|
195
206
|
|
|
196
|
-
|
|
207
|
+
buildFilters() {
|
|
208
|
+
this.formContainer.innerHTML = ''
|
|
209
|
+
const fields = [
|
|
197
210
|
[
|
|
198
211
|
'options.filter',
|
|
199
212
|
{ handler: 'Input', placeholder: translate('Search map features…') },
|
|
200
213
|
],
|
|
201
214
|
['options.inBbox', { handler: 'Switch', label: translate('Current map view') }],
|
|
202
215
|
]
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
window.setTimeout(builder.syncAll.bind(builder))
|
|
209
|
-
})
|
|
210
|
-
if (this._umap.properties.facetKey) {
|
|
211
|
-
fields = this._umap.facets.build()
|
|
212
|
-
filtersBuilder = new Form(this._umap.facets, fields)
|
|
213
|
-
filtersBuilder.on('set', () => this.onFormChange())
|
|
214
|
-
filtersBuilder.form.addEventListener('reset', () => {
|
|
215
|
-
window.setTimeout(filtersBuilder.syncAll.bind(filtersBuilder))
|
|
216
|
+
const searchForm = new Form(this, fields, { className: 'formbox' })
|
|
217
|
+
const listenFormChanges = (form) => {
|
|
218
|
+
form.on('set', () => this.onFormChange())
|
|
219
|
+
form.form.addEventListener('reset', () => {
|
|
220
|
+
window.setTimeout(form.syncAll.bind(form))
|
|
216
221
|
})
|
|
217
|
-
this.formContainer.appendChild(filtersBuilder.build())
|
|
218
222
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
this._umap.
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
|
|
223
|
+
this.formContainer.appendChild(searchForm.build())
|
|
224
|
+
listenFormChanges(searchForm)
|
|
225
|
+
if (this._umap.filters.size) {
|
|
226
|
+
const filtersForm = this._umap.filters.buildForm(this.formContainer)
|
|
227
|
+
listenFormChanges(filtersForm)
|
|
228
|
+
}
|
|
229
|
+
for (const datalayer of this._umap.datalayers.active()) {
|
|
230
|
+
if (datalayer.filters.size) {
|
|
231
|
+
const filtersForm = datalayer.filters.buildForm(this.formContainer)
|
|
232
|
+
listenFormChanges(filtersForm)
|
|
233
|
+
}
|
|
234
|
+
}
|
|
227
235
|
}
|
|
228
236
|
|
|
229
237
|
resetFilters() {
|
|
@@ -252,7 +260,7 @@ export default class Browser {
|
|
|
252
260
|
if (datalayer.isVisible()) allHidden = false
|
|
253
261
|
})
|
|
254
262
|
this._umap.datalayers.browsable().map((datalayer) => {
|
|
255
|
-
datalayer.
|
|
263
|
+
datalayer.autoVisibility = false
|
|
256
264
|
if (allHidden) {
|
|
257
265
|
datalayer.show()
|
|
258
266
|
} else {
|
|
@@ -5,7 +5,7 @@ import * as Utils from './utils.js'
|
|
|
5
5
|
const TEMPLATE = `
|
|
6
6
|
<div class="umap-caption">
|
|
7
7
|
<div class="header">
|
|
8
|
-
<i class="icon icon-16 icon-
|
|
8
|
+
<i class="icon icon-16 icon-info icon-block"></i>
|
|
9
9
|
<hgroup>
|
|
10
10
|
<h3><span class="map-name" data-ref="name"></span></h3>
|
|
11
11
|
<p data-ref="author"></p>
|
|
@@ -39,7 +39,7 @@ export default class Caption extends Utils.WithTemplate {
|
|
|
39
39
|
this._leafletMap = leafletMap
|
|
40
40
|
this.loadTemplate(TEMPLATE)
|
|
41
41
|
this.elements.star.addEventListener('click', async () => {
|
|
42
|
-
if (this._umap.
|
|
42
|
+
if (this._umap.permissions.userIsAuth()) {
|
|
43
43
|
await this._umap.star()
|
|
44
44
|
this.refresh()
|
|
45
45
|
} else {
|
|
@@ -96,11 +96,14 @@ export default class Caption extends Utils.WithTemplate {
|
|
|
96
96
|
addDataLayer(datalayer, parent) {
|
|
97
97
|
if (!datalayer.properties.inCaption) return
|
|
98
98
|
const template = `
|
|
99
|
-
<
|
|
100
|
-
<
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
<div class="caption-item ${datalayer.cssId}">
|
|
100
|
+
<p>
|
|
101
|
+
<span class="datalayer-legend"></span>
|
|
102
|
+
<strong data-ref="toolbox"></strong>
|
|
103
|
+
</p>
|
|
104
|
+
<p class="text" data-ref="description"></p>
|
|
105
|
+
</div>
|
|
106
|
+
`
|
|
104
107
|
const [element, { toolbox, description }] = Utils.loadTemplateWithRefs(template)
|
|
105
108
|
if (datalayer.properties.description) {
|
|
106
109
|
description.innerHTML = Utils.toHTML(datalayer.properties.description)
|
|
@@ -22,6 +22,8 @@ import {
|
|
|
22
22
|
} from '../rendering/ui.js'
|
|
23
23
|
import { SCHEMA } from '../schema.js'
|
|
24
24
|
import * as Utils from '../utils.js'
|
|
25
|
+
import * as DOMUtils from '../domutils.js'
|
|
26
|
+
import * as Icon from '../rendering/icon.js'
|
|
25
27
|
|
|
26
28
|
class Feature {
|
|
27
29
|
constructor(umap, datalayer, geojson = {}, id = null) {
|
|
@@ -91,7 +93,7 @@ class Feature {
|
|
|
91
93
|
|
|
92
94
|
get fields() {
|
|
93
95
|
// Fields are user defined properties
|
|
94
|
-
return [...this.
|
|
96
|
+
return [...this._umap.fields.all(), ...this.datalayer.fields.all()]
|
|
95
97
|
}
|
|
96
98
|
|
|
97
99
|
setter(key, value) {
|
|
@@ -136,6 +138,10 @@ class Feature {
|
|
|
136
138
|
return this.staticOptions.className
|
|
137
139
|
}
|
|
138
140
|
|
|
141
|
+
getUniqueClassName() {
|
|
142
|
+
return `feature-${this.datalayer.id}-${this.id}`
|
|
143
|
+
}
|
|
144
|
+
|
|
139
145
|
getPreviewColor() {
|
|
140
146
|
return this.getDynamicOption(this.staticOptions.mainColor)
|
|
141
147
|
}
|
|
@@ -213,10 +219,22 @@ class Feature {
|
|
|
213
219
|
return field.startsWith('properties.')
|
|
214
220
|
})
|
|
215
221
|
if (impactData) {
|
|
222
|
+
Utils.eachElement(`.${this.getUniqueClassName()} .feature-title`, (el) => {
|
|
223
|
+
el.textContent = this.getDisplayName()
|
|
224
|
+
el.title = this.getDisplayName()
|
|
225
|
+
})
|
|
216
226
|
if (this._umap.currentFeature === this) {
|
|
217
227
|
this.view()
|
|
218
228
|
}
|
|
219
229
|
}
|
|
230
|
+
const impactPreview = fields.some((field) => {
|
|
231
|
+
return field.startsWith('properties._umap_options')
|
|
232
|
+
})
|
|
233
|
+
if (impactPreview) {
|
|
234
|
+
Utils.eachElement(`.${this.getUniqueClassName()} .feature-color`, (el) => {
|
|
235
|
+
this.makePreview(el)
|
|
236
|
+
})
|
|
237
|
+
}
|
|
220
238
|
this.redraw()
|
|
221
239
|
}
|
|
222
240
|
|
|
@@ -233,7 +251,7 @@ class Feature {
|
|
|
233
251
|
)
|
|
234
252
|
|
|
235
253
|
let builder = new MutatingForm(this, [
|
|
236
|
-
['datalayer', { handler: '
|
|
254
|
+
['datalayer', { handler: 'EditableDataLayerSwitcher' }],
|
|
237
255
|
])
|
|
238
256
|
// removeLayer step will close the edit panel, let's reopen it
|
|
239
257
|
builder.on('set', () => this.edit(event))
|
|
@@ -242,9 +260,19 @@ class Feature {
|
|
|
242
260
|
const properties = []
|
|
243
261
|
for (const field of this.fields) {
|
|
244
262
|
const options = { handler: 'Input', label: field.key }
|
|
245
|
-
if (field.key === 'description' || field.
|
|
263
|
+
if (field.key === 'description' || field.TYPE === 'Text') {
|
|
246
264
|
options.handler = 'Textarea'
|
|
247
265
|
options.helpEntries = ['textFormatting']
|
|
266
|
+
} else if (field.TYPE === 'Number') {
|
|
267
|
+
options.handler = 'FloatInput'
|
|
268
|
+
} else if (field.TYPE === 'Date') {
|
|
269
|
+
options.handler = 'DateInput'
|
|
270
|
+
} else if (field.TYPE === 'Datetime') {
|
|
271
|
+
options.handler = 'DateTimeInput'
|
|
272
|
+
} else if (field.TYPE === 'Boolean') {
|
|
273
|
+
options.handler = 'Switch'
|
|
274
|
+
} else if (field.TYPE === 'Enum') {
|
|
275
|
+
options.helpText = translate('Comma separated list of values')
|
|
248
276
|
}
|
|
249
277
|
properties.push([`properties.${field.key}`, options])
|
|
250
278
|
}
|
|
@@ -257,13 +285,13 @@ class Feature {
|
|
|
257
285
|
`<button type="button"><i class="icon icon-16 icon-add"></i>${translate('Add a new field')}</button>`
|
|
258
286
|
)
|
|
259
287
|
button.addEventListener('click', () => {
|
|
260
|
-
this.datalayer.
|
|
288
|
+
this.datalayer.fields.editField().then(() => this.edit({ force: true }))
|
|
261
289
|
})
|
|
262
290
|
form.appendChild(button)
|
|
263
291
|
this.appendEditFieldsets(container)
|
|
264
292
|
const [details, { fieldset }] = Utils.loadTemplateWithRefs(`
|
|
265
293
|
<details>
|
|
266
|
-
<summary>${translate('Advanced actions')}</summary>
|
|
294
|
+
<summary><h4>${translate('Advanced actions')}</h4></summary>
|
|
267
295
|
<fieldset class="button-bar by2" data-ref=fieldset></fieldset>
|
|
268
296
|
</details>
|
|
269
297
|
`)
|
|
@@ -298,7 +326,7 @@ class Feature {
|
|
|
298
326
|
container.appendChild(button)
|
|
299
327
|
}
|
|
300
328
|
|
|
301
|
-
addExtraEditFieldset() {}
|
|
329
|
+
addExtraEditFieldset(container) {}
|
|
302
330
|
|
|
303
331
|
appendEditFieldsets(container) {
|
|
304
332
|
const optionsFields = this.getShapeOptions()
|
|
@@ -498,16 +526,16 @@ class Feature {
|
|
|
498
526
|
return properties
|
|
499
527
|
}
|
|
500
528
|
|
|
501
|
-
|
|
502
|
-
const oldValue = this.properties[
|
|
503
|
-
delete this.properties[
|
|
504
|
-
this.sync.update(`properties.${
|
|
529
|
+
deleteField(name) {
|
|
530
|
+
const oldValue = this.properties[name]
|
|
531
|
+
delete this.properties[name]
|
|
532
|
+
this.sync.update(`properties.${name}`, undefined, oldValue)
|
|
505
533
|
}
|
|
506
534
|
|
|
507
|
-
|
|
535
|
+
renameField(from, to) {
|
|
508
536
|
const oldValue = this.properties[from]
|
|
509
537
|
this.properties[to] = this.properties[from]
|
|
510
|
-
this.
|
|
538
|
+
this.deleteField(from)
|
|
511
539
|
this.sync.update(`properties.${to}`, oldValue, undefined)
|
|
512
540
|
}
|
|
513
541
|
|
|
@@ -523,12 +551,13 @@ class Feature {
|
|
|
523
551
|
isFiltered() {
|
|
524
552
|
const filterKeys = this.datalayer.getFilterKeys()
|
|
525
553
|
const filter = this._umap.browser.options.filter
|
|
526
|
-
if (filter && !this.
|
|
527
|
-
if (
|
|
554
|
+
if (filter && !this.matchFullTextFilter(filter, filterKeys)) return true
|
|
555
|
+
if (this._umap.filters.matchFeature(this)) return true
|
|
556
|
+
if (this.datalayer.filters.matchFeature(this)) return true
|
|
528
557
|
return false
|
|
529
558
|
}
|
|
530
559
|
|
|
531
|
-
|
|
560
|
+
matchFullTextFilter(filter, keys) {
|
|
532
561
|
filter = filter.toLowerCase()
|
|
533
562
|
// When user hasn't touched settings, when a feature has no name
|
|
534
563
|
// it will use the datalayer's name, so let's make the filtering
|
|
@@ -546,28 +575,6 @@ class Feature {
|
|
|
546
575
|
return false
|
|
547
576
|
}
|
|
548
577
|
|
|
549
|
-
matchFacets() {
|
|
550
|
-
const selected = this._umap.facets.selected
|
|
551
|
-
for (const [name, { type, min, max, choices }] of Object.entries(selected)) {
|
|
552
|
-
let value = this.properties[name]
|
|
553
|
-
const parser = this._umap.facets.getParser(type)
|
|
554
|
-
value = parser(value)
|
|
555
|
-
switch (type) {
|
|
556
|
-
case 'date':
|
|
557
|
-
case 'datetime':
|
|
558
|
-
case 'number':
|
|
559
|
-
if (!Number.isNaN(min) && !Number.isNaN(value) && min > value) return false
|
|
560
|
-
if (!Number.isNaN(max) && !Number.isNaN(value) && max < value) return false
|
|
561
|
-
break
|
|
562
|
-
default:
|
|
563
|
-
value = value || translate('<empty value>')
|
|
564
|
-
if (choices?.length && !choices.includes(value)) return false
|
|
565
|
-
break
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
return true
|
|
569
|
-
}
|
|
570
|
-
|
|
571
578
|
isMulti() {
|
|
572
579
|
return false
|
|
573
580
|
}
|
|
@@ -593,6 +600,7 @@ class Feature {
|
|
|
593
600
|
if (U.lang) properties.lang = U.lang
|
|
594
601
|
properties.rank = this.getRank() + 1
|
|
595
602
|
properties.layer = this.datalayer.getName()
|
|
603
|
+
properties.id = this.id
|
|
596
604
|
if (this.ui._map && this.hasGeom()) {
|
|
597
605
|
const center = this.center
|
|
598
606
|
properties.lat = center.lat
|
|
@@ -611,7 +619,7 @@ class Feature {
|
|
|
611
619
|
}
|
|
612
620
|
|
|
613
621
|
redraw() {
|
|
614
|
-
if (this.datalayer?.isVisible()) {
|
|
622
|
+
if (this.datalayer?.isVisible() && this.ui?.isVisible()) {
|
|
615
623
|
if (this.getUIClass() !== this.ui.getClass()) {
|
|
616
624
|
this.datalayer.hideFeature(this)
|
|
617
625
|
this.makeUI()
|
|
@@ -647,8 +655,7 @@ class Feature {
|
|
|
647
655
|
items.push({
|
|
648
656
|
label: translate('Copy as GeoJSON'),
|
|
649
657
|
action: () => {
|
|
650
|
-
|
|
651
|
-
this._umap.tooltip.open({ content: L._('✅ Copied!') })
|
|
658
|
+
DOMUtils.copyToClipboard(JSON.stringify(this.toGeoJSON()))
|
|
652
659
|
},
|
|
653
660
|
})
|
|
654
661
|
return items
|
|
@@ -707,6 +714,19 @@ class Feature {
|
|
|
707
714
|
this.ui.closePopup()
|
|
708
715
|
}
|
|
709
716
|
}
|
|
717
|
+
|
|
718
|
+
makePreview(element) {
|
|
719
|
+
element.innerHTML = ''
|
|
720
|
+
const symbol = this._getIconUrl ? Icon.formatUrl(this._getIconUrl(), this) : null
|
|
721
|
+
const bgcolor = this.getPreviewColor()
|
|
722
|
+
element.style.backgroundColor = bgcolor
|
|
723
|
+
if (symbol && symbol !== SCHEMA.iconUrl.default) {
|
|
724
|
+
const icon = Icon.makeElement(symbol, element)
|
|
725
|
+
Icon.setContrast(icon, element, symbol, bgcolor)
|
|
726
|
+
} else if (DOMUtils.contrastedColor(element, bgcolor)) {
|
|
727
|
+
element.classList.add('icon-white')
|
|
728
|
+
}
|
|
729
|
+
}
|
|
710
730
|
}
|
|
711
731
|
|
|
712
732
|
export class Point extends Feature {
|
|
@@ -932,6 +952,23 @@ class Path extends Feature {
|
|
|
932
952
|
}
|
|
933
953
|
return items
|
|
934
954
|
}
|
|
955
|
+
|
|
956
|
+
addExtraEditFieldset(container) {
|
|
957
|
+
const options = [
|
|
958
|
+
'properties._umap_options.textPath',
|
|
959
|
+
'properties._umap_options.textPathColor',
|
|
960
|
+
'properties._umap_options.textPathRepeat',
|
|
961
|
+
'properties._umap_options.textPathRotate',
|
|
962
|
+
'properties._umap_options.textPathSize',
|
|
963
|
+
'properties._umap_options.textPathOffset',
|
|
964
|
+
'properties._umap_options.textPathPosition',
|
|
965
|
+
]
|
|
966
|
+
const builder = new MutatingForm(this, options, {
|
|
967
|
+
id: 'umap-feature-line-decoration',
|
|
968
|
+
})
|
|
969
|
+
const fieldset = DomUtil.createFieldset(container, translate('Line decoration'))
|
|
970
|
+
fieldset.appendChild(builder.build())
|
|
971
|
+
}
|
|
935
972
|
}
|
|
936
973
|
|
|
937
974
|
export class LineString extends Path {
|
|
@@ -1230,26 +1267,6 @@ export class LineString extends Path {
|
|
|
1230
1267
|
button.addEventListener('click', async () => this.computeRoute())
|
|
1231
1268
|
}
|
|
1232
1269
|
|
|
1233
|
-
addExtraEditFieldset(container) {
|
|
1234
|
-
const options = [
|
|
1235
|
-
'properties._umap_options.textPath',
|
|
1236
|
-
'properties._umap_options.textPathColor',
|
|
1237
|
-
'properties._umap_options.textPathRepeat',
|
|
1238
|
-
'properties._umap_options.textPathRotate',
|
|
1239
|
-
'properties._umap_options.textPathSize',
|
|
1240
|
-
'properties._umap_options.textPathOffset',
|
|
1241
|
-
'properties._umap_options.textPathPosition',
|
|
1242
|
-
]
|
|
1243
|
-
const builder = new MutatingForm(this, options, {
|
|
1244
|
-
id: 'umap-feature-line-decoration',
|
|
1245
|
-
})
|
|
1246
|
-
const fieldset = DomUtil.createFieldset(container, translate('Line decoration'))
|
|
1247
|
-
fieldset.appendChild(builder.build())
|
|
1248
|
-
if (this._umap.properties.ORSAPIKey && this.isRoute()) {
|
|
1249
|
-
this._editRoute(container)
|
|
1250
|
-
}
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
1270
|
async computeElevation() {
|
|
1254
1271
|
if (!this._umap.properties.ORSAPIKey) return
|
|
1255
1272
|
const importer = new OpenRouteService(this._umap)
|
|
@@ -1259,6 +1276,7 @@ export class LineString extends Path {
|
|
|
1259
1276
|
this.geometry = geometry
|
|
1260
1277
|
this.ui.resetTooltip()
|
|
1261
1278
|
this.sync.update('geometry', this.geometry, oldGeometry)
|
|
1279
|
+
Alert.success(translate('Elevation has been added!'))
|
|
1262
1280
|
}
|
|
1263
1281
|
}
|
|
1264
1282
|
|
|
@@ -1274,6 +1292,13 @@ export class LineString extends Path {
|
|
|
1274
1292
|
}
|
|
1275
1293
|
})
|
|
1276
1294
|
}
|
|
1295
|
+
|
|
1296
|
+
addExtraEditFieldset(container) {
|
|
1297
|
+
super.addExtraEditFieldset(container)
|
|
1298
|
+
if (this._umap.properties.ORSAPIKey && this.isRoute()) {
|
|
1299
|
+
this._editRoute(container)
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1277
1302
|
}
|
|
1278
1303
|
|
|
1279
1304
|
export class Polygon extends Path {
|