umap-project 3.4.0b1__py3-none-any.whl → 3.4.2__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 +1 -1
- umap/locale/da/LC_MESSAGES/django.mo +0 -0
- umap/locale/da/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/pl/LC_MESSAGES/django.mo +0 -0
- umap/locale/pl/LC_MESSAGES/django.po +72 -71
- umap/migrations/0018_datalayer_uuid.py +1 -1
- umap/models.py +7 -3
- umap/settings/local.py.sample +1 -1
- umap/static/umap/content.css +0 -3
- umap/static/umap/css/bar.css +9 -6
- umap/static/umap/css/form.css +27 -11
- umap/static/umap/css/popup.css +1 -0
- umap/static/umap/js/components/base.js +1 -1
- umap/static/umap/js/components/copiable.js +47 -0
- umap/static/umap/js/modules/autocomplete.js +31 -58
- umap/static/umap/js/modules/browser.js +8 -8
- umap/static/umap/js/modules/data/features.js +33 -36
- umap/static/umap/js/modules/data/fields.js +446 -0
- umap/static/umap/js/modules/data/layer.js +76 -93
- umap/static/umap/js/modules/domutils.js +24 -4
- umap/static/umap/js/modules/filters.js +20 -47
- umap/static/umap/js/modules/form/fields.js +4 -4
- umap/static/umap/js/modules/formatter.js +9 -1
- umap/static/umap/js/modules/help.js +13 -14
- umap/static/umap/js/modules/i18n.js +1 -1
- umap/static/umap/js/modules/importer.js +18 -27
- 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 -265
- umap/static/umap/js/modules/permissions.js +5 -3
- umap/static/umap/js/modules/rendering/controls.js +6 -4
- 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 +27 -21
- umap/static/umap/js/modules/rendering/map.js +22 -22
- umap/static/umap/js/modules/rendering/popup.js +6 -3
- umap/static/umap/js/modules/rendering/template.js +31 -37
- 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 +51 -32
- umap/static/umap/js/modules/ui/dialog.js +10 -1
- umap/static/umap/js/modules/ui/panel.js +28 -23
- umap/static/umap/js/modules/ui/tooltip.js +1 -1
- umap/static/umap/js/modules/umap.js +84 -84
- umap/static/umap/js/modules/utils.js +13 -4
- umap/static/umap/js/umap.controls.js +33 -14
- umap/static/umap/locale/am_ET.js +19 -8
- umap/static/umap/locale/am_ET.json +19 -8
- umap/static/umap/locale/ar.js +19 -8
- umap/static/umap/locale/ar.json +19 -8
- umap/static/umap/locale/ast.js +19 -8
- umap/static/umap/locale/ast.json +19 -8
- umap/static/umap/locale/bg.js +19 -8
- umap/static/umap/locale/bg.json +19 -8
- umap/static/umap/locale/br.js +20 -9
- umap/static/umap/locale/br.json +20 -9
- umap/static/umap/locale/ca.js +19 -8
- umap/static/umap/locale/ca.json +19 -8
- umap/static/umap/locale/cs_CZ.js +20 -9
- umap/static/umap/locale/cs_CZ.json +20 -9
- umap/static/umap/locale/da.js +54 -43
- umap/static/umap/locale/da.json +54 -43
- umap/static/umap/locale/de.js +44 -33
- umap/static/umap/locale/de.json +44 -33
- umap/static/umap/locale/el.js +20 -9
- umap/static/umap/locale/el.json +20 -9
- umap/static/umap/locale/en.js +20 -9
- umap/static/umap/locale/en.json +20 -9
- umap/static/umap/locale/en_US.json +19 -8
- umap/static/umap/locale/es.js +55 -44
- umap/static/umap/locale/es.json +55 -44
- umap/static/umap/locale/et.js +20 -9
- umap/static/umap/locale/et.json +20 -9
- umap/static/umap/locale/eu.js +25 -14
- umap/static/umap/locale/eu.json +25 -14
- umap/static/umap/locale/fa_IR.js +20 -9
- umap/static/umap/locale/fa_IR.json +20 -9
- umap/static/umap/locale/fi.js +19 -8
- umap/static/umap/locale/fi.json +19 -8
- umap/static/umap/locale/fr.js +21 -10
- umap/static/umap/locale/fr.json +21 -10
- umap/static/umap/locale/gl.js +147 -136
- umap/static/umap/locale/gl.json +147 -136
- umap/static/umap/locale/he.js +19 -8
- umap/static/umap/locale/he.json +19 -8
- umap/static/umap/locale/hr.js +19 -8
- umap/static/umap/locale/hr.json +19 -8
- umap/static/umap/locale/hu.js +62 -51
- umap/static/umap/locale/hu.json +62 -51
- umap/static/umap/locale/id.js +19 -8
- umap/static/umap/locale/id.json +19 -8
- umap/static/umap/locale/is.js +20 -9
- umap/static/umap/locale/is.json +20 -9
- umap/static/umap/locale/it.js +20 -9
- umap/static/umap/locale/it.json +20 -9
- umap/static/umap/locale/ja.js +19 -8
- umap/static/umap/locale/ja.json +19 -8
- umap/static/umap/locale/ko.js +19 -8
- umap/static/umap/locale/ko.json +19 -8
- umap/static/umap/locale/lt.js +19 -8
- umap/static/umap/locale/lt.json +19 -8
- umap/static/umap/locale/ms.js +20 -9
- umap/static/umap/locale/ms.json +20 -9
- umap/static/umap/locale/nl.js +20 -9
- umap/static/umap/locale/nl.json +20 -9
- umap/static/umap/locale/no.js +19 -8
- umap/static/umap/locale/no.json +19 -8
- umap/static/umap/locale/pl.js +56 -45
- umap/static/umap/locale/pl.json +56 -45
- umap/static/umap/locale/pl_PL.json +19 -8
- umap/static/umap/locale/pt.js +20 -9
- umap/static/umap/locale/pt.json +20 -9
- umap/static/umap/locale/pt_BR.js +19 -8
- umap/static/umap/locale/pt_BR.json +19 -8
- umap/static/umap/locale/pt_PT.js +19 -8
- umap/static/umap/locale/pt_PT.json +19 -8
- umap/static/umap/locale/ro.js +19 -8
- umap/static/umap/locale/ro.json +19 -8
- umap/static/umap/locale/ru.js +19 -8
- umap/static/umap/locale/ru.json +19 -8
- umap/static/umap/locale/si.js +1 -1
- umap/static/umap/locale/si.json +1 -1
- umap/static/umap/locale/sk_SK.js +19 -8
- umap/static/umap/locale/sk_SK.json +19 -8
- umap/static/umap/locale/sl.js +19 -8
- umap/static/umap/locale/sl.json +19 -8
- umap/static/umap/locale/sr.js +19 -8
- umap/static/umap/locale/sr.json +19 -8
- umap/static/umap/locale/sv.js +19 -8
- umap/static/umap/locale/sv.json +19 -8
- umap/static/umap/locale/th_TH.js +19 -8
- umap/static/umap/locale/th_TH.json +19 -8
- umap/static/umap/locale/tr.js +19 -8
- umap/static/umap/locale/tr.json +19 -8
- umap/static/umap/locale/uk_UA.js +19 -8
- umap/static/umap/locale/uk_UA.json +19 -8
- umap/static/umap/locale/vi.js +19 -8
- umap/static/umap/locale/vi.json +19 -8
- umap/static/umap/locale/vi_VN.json +19 -8
- umap/static/umap/locale/zh.js +19 -8
- umap/static/umap/locale/zh.json +19 -8
- umap/static/umap/locale/zh_CN.json +19 -8
- umap/static/umap/locale/zh_TW.Big5.json +19 -8
- umap/static/umap/locale/zh_TW.js +53 -42
- umap/static/umap/locale/zh_TW.json +53 -42
- umap/static/umap/map.css +8 -7
- umap/static/umap/unittests/utils.js +7 -7
- umap/templates/umap/content_footer.html +1 -0
- umap/templates/umap/css.html +0 -2
- umap/templates/umap/js.html +1 -3
- umap/templates/umap/login_popup_end.html +2 -2
- umap/tests/integration/conftest.py +11 -2
- umap/tests/integration/test_anonymous_owned_map.py +2 -2
- umap/tests/integration/test_conditional_rules.py +107 -52
- 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_fields.py +19 -0
- umap/tests/integration/test_filters.py +6 -7
- umap/tests/integration/test_iframe.py +1 -1
- umap/tests/integration/test_import.py +23 -0
- umap/tests/integration/test_map.py +2 -2
- umap/tests/integration/test_map_preview.py +1 -1
- umap/tests/integration/test_owned_map.py +2 -2
- umap/tests/integration/test_picto.py +1 -1
- umap/tests/integration/test_popup.py +31 -0
- umap/tests/integration/test_remote_data.py +4 -4
- umap/tests/integration/test_save.py +1 -1
- 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 +69 -20
- umap/tests/test_dashboard.py +1 -1
- umap/tests/test_statics.py +2 -2
- umap/tests/test_utils.py +4 -1
- umap/tests/test_views.py +1 -1
- umap/utils.py +3 -2
- {umap_project-3.4.0b1.dist-info → umap_project-3.4.2.dist-info}/METADATA +17 -17
- {umap_project-3.4.0b1.dist-info → umap_project-3.4.2.dist-info}/RECORD +198 -199
- 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_project-3.4.0b1.dist-info → umap_project-3.4.2.dist-info}/WHEEL +0 -0
- {umap_project-3.4.0b1.dist-info → umap_project-3.4.2.dist-info}/entry_points.txt +0 -0
- {umap_project-3.4.0b1.dist-info → umap_project-3.4.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Control } from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
1
|
+
import { Control, LayerGroup } from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
2
2
|
import * as Utils from '../utils.js'
|
|
3
3
|
import { translate } from '../i18n.js'
|
|
4
4
|
|
|
@@ -112,7 +112,9 @@ export const PermanentCreditsControl = Control.extend({
|
|
|
112
112
|
const container = Utils.loadTemplate(
|
|
113
113
|
`<div class="umap-permanent-credits-container text">${Utils.toHTML(map.options.permanentCredit)}</div>`
|
|
114
114
|
)
|
|
115
|
-
const background = map.
|
|
115
|
+
const background = map._umap.getProperty('permanentCreditBackground')
|
|
116
|
+
? '#FFFFFFB0'
|
|
117
|
+
: ''
|
|
116
118
|
container.style.backgroundColor = background
|
|
117
119
|
return container
|
|
118
120
|
},
|
|
@@ -164,7 +166,7 @@ export const DataLayersControl = BaseButton.extend({
|
|
|
164
166
|
},
|
|
165
167
|
|
|
166
168
|
afterAdd: function (container) {
|
|
167
|
-
Utils.toggleBadge(container, this._umap.browser?.
|
|
169
|
+
Utils.toggleBadge(container, this._umap.browser?.hasActiveFilters())
|
|
168
170
|
},
|
|
169
171
|
|
|
170
172
|
onClick: function () {
|
|
@@ -219,7 +221,7 @@ export const SearchControl = BaseButton.extend({
|
|
|
219
221
|
},
|
|
220
222
|
|
|
221
223
|
afterAdd(container, map) {
|
|
222
|
-
this.layer =
|
|
224
|
+
this.layer = new LayerGroup().addTo(map)
|
|
223
225
|
this.photonOptions = {
|
|
224
226
|
limit: 10,
|
|
225
227
|
noResultLabel: translate('No results'),
|
|
@@ -237,14 +237,7 @@ const Ball = DefaultIcon.extend({
|
|
|
237
237
|
_setIconStyles: function (img, name) {
|
|
238
238
|
BaseIcon.prototype._setIconStyles.call(this, img, name)
|
|
239
239
|
const color = this._getColor('color')
|
|
240
|
-
|
|
241
|
-
if (L.Browser.ielt9) {
|
|
242
|
-
background = color
|
|
243
|
-
} else if (L.Browser.webkit) {
|
|
244
|
-
background = `-webkit-gradient( radial, 6 38%, 0, 6 38%, 8, from(white), to(${color}) )`
|
|
245
|
-
} else {
|
|
246
|
-
background = `radial-gradient(circle at 6px 38% , white -4px, ${color} 8px) repeat scroll 0 0 transparent`
|
|
247
|
-
}
|
|
240
|
+
const background = `radial-gradient(circle at 6px 38% , white -4px, ${color} 8px) repeat scroll 0 0 transparent`
|
|
248
241
|
this.elements.ball.style.background = background
|
|
249
242
|
this.elements.ball.style.opacity = this._getOpacity()
|
|
250
243
|
},
|
|
@@ -309,5 +302,8 @@ export function setContrast(icon, parent, src, bgcolor) {
|
|
|
309
302
|
}
|
|
310
303
|
|
|
311
304
|
export function formatUrl(url, feature) {
|
|
312
|
-
|
|
305
|
+
if (Utils.hasVar(url)) {
|
|
306
|
+
return Utils.greedyTemplate(url || '', feature ? feature.extendedProperties() : {})
|
|
307
|
+
}
|
|
308
|
+
return url
|
|
313
309
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import colorbrewer from '../../../../vendors/colorbrewer/colorbrewer.js'
|
|
2
|
-
import {
|
|
2
|
+
import { FeatureGroup } from '../../../../vendors/leaflet/leaflet-src.esm.js'
|
|
3
3
|
import { translate } from '../../i18n.js'
|
|
4
4
|
import * as Utils from '../../utils.js'
|
|
5
5
|
import * as DOMUtils from '../../domutils.js'
|
|
@@ -7,7 +7,7 @@ import { CircleMarker } from '../ui.js'
|
|
|
7
7
|
import { LayerMixin } from './base.js'
|
|
8
8
|
|
|
9
9
|
// Layer where each feature color is relative to the others,
|
|
10
|
-
// so we need all features before
|
|
10
|
+
// so we need all features before being able to set one
|
|
11
11
|
// feature layer
|
|
12
12
|
const ClassifiedMixin = {
|
|
13
13
|
initialize: function (datalayer) {
|
|
@@ -346,7 +346,8 @@ export const Circles = FeatureGroup.extend({
|
|
|
346
346
|
},
|
|
347
347
|
|
|
348
348
|
renderLegend: function (container) {
|
|
349
|
-
const parent =
|
|
349
|
+
const parent = DOMUtils.loadTemplate('<ul class="circles-layer-legend"></ul>')
|
|
350
|
+
container.appendChild(parent)
|
|
350
351
|
const color = this.datalayer.getProperty('color')
|
|
351
352
|
const values = this.getValues()
|
|
352
353
|
if (!values.length) return
|
|
@@ -360,14 +361,18 @@ export const Circles = FeatureGroup.extend({
|
|
|
360
361
|
[this.options.maxPX, maxValue],
|
|
361
362
|
]
|
|
362
363
|
for (const [size, label] of items) {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
364
|
+
parent.appendChild(
|
|
365
|
+
DOMUtils.loadTemplate(`
|
|
366
|
+
<li>
|
|
367
|
+
<span class="circle"
|
|
368
|
+
style="background-color: ${color};
|
|
369
|
+
height: ${size * 2}px;
|
|
370
|
+
width: ${size * 2}px;
|
|
371
|
+
opacity: ${this.datalayer.getProperty('fillOpacity')};"></span>
|
|
372
|
+
<span class="label">${label}</span>
|
|
373
|
+
</li>
|
|
374
|
+
`)
|
|
375
|
+
)
|
|
371
376
|
}
|
|
372
377
|
},
|
|
373
378
|
})
|
|
@@ -68,27 +68,32 @@ export const Heat = L.HeatLayer.extend({
|
|
|
68
68
|
return latLngBounds(this._latlngs)
|
|
69
69
|
},
|
|
70
70
|
|
|
71
|
-
getEditableProperties: ()
|
|
72
|
-
[
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
71
|
+
getEditableProperties: function () {
|
|
72
|
+
return [
|
|
73
|
+
[
|
|
74
|
+
'properties.heat.radius',
|
|
75
|
+
{
|
|
76
|
+
handler: 'Range',
|
|
77
|
+
min: 10,
|
|
78
|
+
max: 100,
|
|
79
|
+
step: 5,
|
|
80
|
+
label: translate('Heatmap radius'),
|
|
81
|
+
helpText: translate('Override heatmap radius (default 25)'),
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
[
|
|
85
|
+
'properties.heat.intensityProperty',
|
|
86
|
+
{
|
|
87
|
+
handler: 'Select',
|
|
88
|
+
selectOptions: [
|
|
89
|
+
['', translate('Select field to compute intensity')],
|
|
90
|
+
...this.datalayer.fields.keys(),
|
|
91
|
+
],
|
|
92
|
+
helpText: translate('Optional intensity field to compute heatmap'),
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
]
|
|
96
|
+
},
|
|
92
97
|
|
|
93
98
|
onEdit: function (field, builder) {
|
|
94
99
|
if (field === 'properties.heat.intensityProperty') {
|
|
@@ -97,6 +102,7 @@ export const Heat = L.HeatLayer.extend({
|
|
|
97
102
|
}
|
|
98
103
|
if (field === 'properties.heat.radius') {
|
|
99
104
|
this.options.radius = this.datalayer.properties.heat.radius
|
|
105
|
+
this.redraw()
|
|
100
106
|
}
|
|
101
107
|
this._updateOptions()
|
|
102
108
|
},
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
// Goes here all code related to Leaflet, DOM and user interactions.
|
|
2
2
|
import {
|
|
3
3
|
Map as BaseMap,
|
|
4
|
+
Browser,
|
|
4
5
|
Control,
|
|
5
6
|
DomEvent,
|
|
6
|
-
DomUtil,
|
|
7
7
|
latLng,
|
|
8
|
-
|
|
8
|
+
LatLng,
|
|
9
|
+
LatLngBounds,
|
|
9
10
|
setOptions,
|
|
11
|
+
TileLayer,
|
|
10
12
|
} from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
11
13
|
import { uMapAlert as Alert } from '../../components/alerts/alert.js'
|
|
12
14
|
import DropControl from '../drop.js'
|
|
@@ -46,7 +48,6 @@ const ControlsMixin = {
|
|
|
46
48
|
'caption',
|
|
47
49
|
'locate',
|
|
48
50
|
'measure',
|
|
49
|
-
'editinosm',
|
|
50
51
|
'print',
|
|
51
52
|
'tilelayers',
|
|
52
53
|
],
|
|
@@ -91,17 +92,9 @@ const ControlsMixin = {
|
|
|
91
92
|
this._controls.embed = new EmbedControl(this._umap)
|
|
92
93
|
this._controls.print = new PrintControl(this._umap)
|
|
93
94
|
this._controls.tilelayersChooser = new TileLayerChooser(this._umap)
|
|
94
|
-
this._controls.editinosm = new Control.EditInOSM({
|
|
95
|
-
position: 'topleft',
|
|
96
|
-
widgetOptions: {
|
|
97
|
-
helpText: translate(
|
|
98
|
-
'Open this map extent in a map editor to provide more accurate data to OpenStreetMap'
|
|
99
|
-
),
|
|
100
|
-
},
|
|
101
|
-
})
|
|
102
95
|
this._controls.measure = new L.MeasureControl().initHandler(this)
|
|
103
96
|
this._controls.more = new MoreControl()
|
|
104
|
-
this._controls.scale =
|
|
97
|
+
this._controls.scale = new Control.Scale()
|
|
105
98
|
this._controls.permanentCredit = new PermanentCreditsControl(this)
|
|
106
99
|
this._umap.drop = new DropControl(this._umap, this, this._container)
|
|
107
100
|
this._controls.tilelayers = new U.TileLayerControl(this)
|
|
@@ -138,11 +131,10 @@ const ControlsMixin = {
|
|
|
138
131
|
const control = this._controls[name]
|
|
139
132
|
if (!control) continue
|
|
140
133
|
control.addTo(this)
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
134
|
+
control._container.classList.toggle(
|
|
135
|
+
'display-on-more',
|
|
136
|
+
status === undefined || status === null
|
|
137
|
+
)
|
|
146
138
|
}
|
|
147
139
|
if (this._umap.getProperty('permanentCredit'))
|
|
148
140
|
this._controls.permanentCredit.addTo(this)
|
|
@@ -176,7 +168,7 @@ const ManageTilelayerMixin = {
|
|
|
176
168
|
if (this._controls) this._controls.tilelayers.setLayers()
|
|
177
169
|
},
|
|
178
170
|
|
|
179
|
-
createTileLayer: (tilelayer) => new
|
|
171
|
+
createTileLayer: (tilelayer) => new TileLayer(tilelayer.url_template, tilelayer),
|
|
180
172
|
|
|
181
173
|
selectTileLayer: function (tilelayer) {
|
|
182
174
|
if (tilelayer === this.selectedTilelayer) {
|
|
@@ -303,7 +295,7 @@ export const LeafletMap = BaseMap.extend({
|
|
|
303
295
|
// when scrolling the main page and touching the
|
|
304
296
|
// map in an iframe. May be a bit dumb, but let's
|
|
305
297
|
// try like this for now.
|
|
306
|
-
if (
|
|
298
|
+
if (Browser.mobile) this.dragging.disable()
|
|
307
299
|
}
|
|
308
300
|
// Needs tilelayer to exist for minimap
|
|
309
301
|
this.renderControls()
|
|
@@ -312,7 +304,7 @@ export const LeafletMap = BaseMap.extend({
|
|
|
312
304
|
|
|
313
305
|
latLng: (a, b, c) => {
|
|
314
306
|
// manage geojson case and call original method
|
|
315
|
-
if (!(a instanceof
|
|
307
|
+
if (!(a instanceof LatLng) && a.coordinates) {
|
|
316
308
|
// Guess it's a geojson
|
|
317
309
|
a = [a.coordinates[1], a.coordinates[0]]
|
|
318
310
|
}
|
|
@@ -361,7 +353,7 @@ export const LeafletMap = BaseMap.extend({
|
|
|
361
353
|
!Number.isNaN(north) &&
|
|
362
354
|
!Number.isNaN(east)
|
|
363
355
|
) {
|
|
364
|
-
const bounds =
|
|
356
|
+
const bounds = new LatLngBounds([
|
|
365
357
|
[south, west],
|
|
366
358
|
[north, east],
|
|
367
359
|
])
|
|
@@ -381,7 +373,7 @@ export const LeafletMap = BaseMap.extend({
|
|
|
381
373
|
setMaxBounds: function (bounds) {
|
|
382
374
|
// Hack. Remove me when fix is released:
|
|
383
375
|
// https://github.com/Leaflet/Leaflet/pull/4494
|
|
384
|
-
bounds =
|
|
376
|
+
bounds = new LatLngBounds(bounds)
|
|
385
377
|
|
|
386
378
|
if (!bounds.isValid()) {
|
|
387
379
|
this.options.maxBounds = null
|
|
@@ -390,6 +382,14 @@ export const LeafletMap = BaseMap.extend({
|
|
|
390
382
|
return BaseMap.prototype.setMaxBounds.call(this, bounds)
|
|
391
383
|
},
|
|
392
384
|
|
|
385
|
+
getLayersBounds: (layers) => {
|
|
386
|
+
const bounds = new LatLngBounds()
|
|
387
|
+
for (const layer of layers) {
|
|
388
|
+
bounds.extend(layer.getBounds())
|
|
389
|
+
}
|
|
390
|
+
return bounds
|
|
391
|
+
},
|
|
392
|
+
|
|
393
393
|
initEditTools: function () {
|
|
394
394
|
this.editTools = new U.Editable(this._umap)
|
|
395
395
|
},
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Popup as BasePopup,
|
|
3
3
|
DomEvent,
|
|
4
|
-
DomUtil,
|
|
5
4
|
Path,
|
|
6
5
|
} from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
7
6
|
import Browser from '../browser.js'
|
|
8
7
|
import loadTemplate from './template.js'
|
|
8
|
+
import * as DOMUtils from '../domutils.js'
|
|
9
9
|
|
|
10
10
|
export default function loadPopup(name) {
|
|
11
11
|
switch (name) {
|
|
@@ -25,7 +25,8 @@ const Popup = BasePopup.extend({
|
|
|
25
25
|
},
|
|
26
26
|
|
|
27
27
|
loadContent: async function () {
|
|
28
|
-
const container =
|
|
28
|
+
const container = document.createElement('div')
|
|
29
|
+
container.classList.add('umap-popup')
|
|
29
30
|
const name = this.feature.getOption('popupTemplate')
|
|
30
31
|
this.content = await loadTemplate(name, this.feature, container)
|
|
31
32
|
const elements = container.querySelectorAll('img,iframe')
|
|
@@ -34,7 +35,9 @@ const Popup = BasePopup.extend({
|
|
|
34
35
|
}
|
|
35
36
|
if (!elements.length && container.textContent.replace('\n', '') === '') {
|
|
36
37
|
container.innerHTML = ''
|
|
37
|
-
|
|
38
|
+
container.appendChild(
|
|
39
|
+
DOMUtils.loadTemplate(`<h3>${this.feature.getDisplayName()}</h3>`)
|
|
40
|
+
)
|
|
38
41
|
}
|
|
39
42
|
this.setContent(container)
|
|
40
43
|
},
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DomEvent,
|
|
3
|
-
DomUtil,
|
|
4
|
-
CircleMarker,
|
|
5
|
-
} from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
1
|
+
import { DomEvent, CircleMarker } from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
6
2
|
import { getLocale, translate } from '../i18n.js'
|
|
7
3
|
import { Request } from '../request.js'
|
|
8
4
|
import * as Utils from '../utils.js'
|
|
@@ -92,7 +88,11 @@ class PopupTemplate {
|
|
|
92
88
|
const title = this.renderTitle(feature)
|
|
93
89
|
if (title) container.appendChild(title)
|
|
94
90
|
const body = await this.renderBody(feature)
|
|
95
|
-
if (body)
|
|
91
|
+
if (body) {
|
|
92
|
+
const div = DOMUtils.loadTemplate('<div class="umap-popup-content"></div>')
|
|
93
|
+
div.appendChild(body)
|
|
94
|
+
container.appendChild(div)
|
|
95
|
+
}
|
|
96
96
|
const footer = this.renderFooter(feature)
|
|
97
97
|
if (footer) container.appendChild(footer)
|
|
98
98
|
}
|
|
@@ -108,29 +108,20 @@ export const TitleMixin = (Base) =>
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
class Table extends TitleMixin(PopupTemplate) {
|
|
111
|
-
|
|
112
|
-
// TODO, manage links (url, mailto, wikipedia...)
|
|
113
|
-
const value = Utils.escapeHTML(feature.properties[key]).trim()
|
|
114
|
-
if (value.indexOf('http') === 0) {
|
|
115
|
-
return `<a href="${value}" target="_blank">${value}</a>`
|
|
116
|
-
}
|
|
117
|
-
return value
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
makeRow(feature, key) {
|
|
111
|
+
makeRow(feature, field) {
|
|
121
112
|
return Utils.loadTemplate(
|
|
122
|
-
`<tr><th>${key}</th><td>${
|
|
113
|
+
`<tr><th>${field.key}</th><td>${field.render(feature.properties[field.key])}</td></tr>`
|
|
123
114
|
)
|
|
124
115
|
}
|
|
125
116
|
|
|
126
117
|
async renderBody(feature) {
|
|
127
118
|
const table = document.createElement('table')
|
|
128
119
|
|
|
129
|
-
for (const
|
|
130
|
-
if (
|
|
120
|
+
for (const field of feature.fields) {
|
|
121
|
+
if (U.LABEL_KEYS.includes(field.key)) {
|
|
131
122
|
continue
|
|
132
123
|
}
|
|
133
|
-
table.appendChild(this.makeRow(feature,
|
|
124
|
+
table.appendChild(this.makeRow(feature, field))
|
|
134
125
|
}
|
|
135
126
|
return table
|
|
136
127
|
}
|
|
@@ -138,16 +129,17 @@ class Table extends TitleMixin(PopupTemplate) {
|
|
|
138
129
|
|
|
139
130
|
class GeoRSSImage extends TitleMixin(PopupTemplate) {
|
|
140
131
|
async renderBody(feature) {
|
|
141
|
-
const body =
|
|
142
|
-
|
|
143
|
-
|
|
132
|
+
const body = DOMUtils.loadTemplate(
|
|
133
|
+
`<a href="${feature.properties.link}" target="_blank"></a>`
|
|
134
|
+
)
|
|
144
135
|
if (feature.properties.img) {
|
|
145
|
-
const img = DomUtil.create('img', '', body)
|
|
146
|
-
img.src = feature.properties.img
|
|
147
136
|
// Sadly, we are unable to override this from JS the clean way
|
|
148
137
|
// See https://github.com/Leaflet/Leaflet/commit/61d746818b99d362108545c151a27f09d60960ee#commitcomment-6061847
|
|
149
|
-
|
|
150
|
-
|
|
138
|
+
body.appendChild(
|
|
139
|
+
DOMUtils.loadTemplate(
|
|
140
|
+
`<img src=${feature.properties.img} style="max-width: 500px; max-height: 500px;">`
|
|
141
|
+
)
|
|
142
|
+
)
|
|
151
143
|
}
|
|
152
144
|
return body
|
|
153
145
|
}
|
|
@@ -165,15 +157,16 @@ class GeoRSSLink extends PopupTemplate {
|
|
|
165
157
|
|
|
166
158
|
class OSM extends PopupTemplate {
|
|
167
159
|
renderTitle(feature) {
|
|
168
|
-
const title = DomUtil.add('h3', 'popup-title')
|
|
169
160
|
const color = feature.getPreviewColor()
|
|
170
|
-
title
|
|
161
|
+
const [title, { iconContainer }] = DOMUtils.loadTemplateWithRefs(`
|
|
162
|
+
<h3 class="popup-title" style="background-color: ${color};">
|
|
163
|
+
<span data-ref="iconContainer"></span> ${this.getName(feature)}
|
|
164
|
+
</h3>`)
|
|
171
165
|
const iconUrl = feature.getDynamicOption('iconUrl')
|
|
172
|
-
const icon = Icon.makeElement(iconUrl,
|
|
173
|
-
|
|
166
|
+
const icon = Icon.makeElement(iconUrl, iconContainer)
|
|
167
|
+
icon.classList.add('icon')
|
|
174
168
|
Icon.setContrast(icon, title, iconUrl, color)
|
|
175
169
|
if (DOMUtils.contrastedColor(title, color)) title.style.color = 'white'
|
|
176
|
-
DomUtil.add('span', '', title, this.getName(feature))
|
|
177
170
|
return title
|
|
178
171
|
}
|
|
179
172
|
|
|
@@ -190,15 +183,16 @@ class OSM extends PopupTemplate {
|
|
|
190
183
|
const locale = getLocale()
|
|
191
184
|
const street = props['addr:street']
|
|
192
185
|
if (street) {
|
|
193
|
-
const row = DomUtil.add('address', 'address', body)
|
|
194
186
|
const number = props['addr:housenumber']
|
|
187
|
+
let content
|
|
195
188
|
if (number) {
|
|
196
|
-
// Poor way to deal with international forms of
|
|
197
|
-
|
|
198
|
-
DomUtil.add('span', '', row, `${translate('Street')}: ${street}`)
|
|
189
|
+
// Poor way to deal with international forms of writing addresses
|
|
190
|
+
content = `<span>${translate('№')}: ${number}</span><span>${translate('Street')}: ${street}</span>`
|
|
199
191
|
} else {
|
|
200
|
-
|
|
192
|
+
content = street
|
|
201
193
|
}
|
|
194
|
+
const row = DOMUtils.loadTemplate(`<address class="address">${content}</address>`)
|
|
195
|
+
body.appendChild(row)
|
|
202
196
|
}
|
|
203
197
|
if (props.website) {
|
|
204
198
|
body.appendChild(
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import {
|
|
3
3
|
CircleMarker as BaseCircleMarker,
|
|
4
4
|
DomEvent,
|
|
5
|
-
DomUtil,
|
|
6
5
|
GeoJSON,
|
|
7
6
|
LatLng,
|
|
8
7
|
LatLngBounds,
|
|
@@ -314,7 +313,7 @@ const PathMixin = {
|
|
|
314
313
|
this.enableEdit()
|
|
315
314
|
} else {
|
|
316
315
|
this._map._umap.tooltip.open({
|
|
317
|
-
content:
|
|
316
|
+
content: translate('Please zoom in to edit the geometry'),
|
|
318
317
|
})
|
|
319
318
|
this.disableEdit()
|
|
320
319
|
}
|
|
@@ -6,6 +6,7 @@ import Orderable from './orderable.js'
|
|
|
6
6
|
import * as Utils from './utils.js'
|
|
7
7
|
import * as Icon from './rendering/icon.js'
|
|
8
8
|
import { SCHEMA } from './schema.js'
|
|
9
|
+
import { Registry as Fields } from './data/fields.js'
|
|
9
10
|
|
|
10
11
|
const EMPTY_VALUES = ['', undefined, null]
|
|
11
12
|
|
|
@@ -28,12 +29,12 @@ class Rule {
|
|
|
28
29
|
// cf https://caniuse.com/?search=public%20class%20field
|
|
29
30
|
this._condition = null
|
|
30
31
|
this.OPERATORS = [
|
|
31
|
-
['>',
|
|
32
|
-
['<',
|
|
32
|
+
['>', 'gt'],
|
|
33
|
+
['<', 'lt'],
|
|
33
34
|
// When sent by Django
|
|
34
|
-
['<',
|
|
35
|
-
['!=',
|
|
36
|
-
['=',
|
|
35
|
+
['<', 'lt'],
|
|
36
|
+
['!=', 'not_equal'],
|
|
37
|
+
['=', 'equal'],
|
|
37
38
|
]
|
|
38
39
|
this.parent = parent
|
|
39
40
|
this._umap = umap
|
|
@@ -47,58 +48,47 @@ class Rule {
|
|
|
47
48
|
this.parent.render(fields)
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
equal(other) {
|
|
51
|
-
return this.expected === other
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
not_equal(other) {
|
|
55
|
-
return this.expected !== other
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
gt(other) {
|
|
59
|
-
return other > this.expected
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
lt(other) {
|
|
63
|
-
return other < this.expected
|
|
64
|
-
}
|
|
65
|
-
|
|
66
51
|
parse() {
|
|
67
52
|
let vars = []
|
|
68
53
|
this.cast = (v) => v
|
|
69
54
|
this.operator = undefined
|
|
70
|
-
|
|
55
|
+
let operator = undefined
|
|
56
|
+
for (const [sign, funcName] of this.OPERATORS) {
|
|
71
57
|
if (this.condition.includes(sign)) {
|
|
72
|
-
|
|
58
|
+
operator = funcName
|
|
73
59
|
vars = this.condition.split(sign)
|
|
74
60
|
break
|
|
75
61
|
}
|
|
76
62
|
}
|
|
77
63
|
if (vars.length !== 2) return
|
|
78
|
-
this.
|
|
64
|
+
this.field = this.parent.fields.get(vars[0]) || new Fields.String(vars[0])
|
|
65
|
+
this.operator = this.field[operator]
|
|
79
66
|
this.expected = vars[1]
|
|
80
67
|
if (EMPTY_VALUES.includes(this.expected)) {
|
|
81
68
|
this.cast = (v) => EMPTY_VALUES.includes(v)
|
|
82
69
|
}
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
70
|
+
// TODO: deal with legacy rules on non typed fields
|
|
71
|
+
else {
|
|
72
|
+
this.cast = this.field.parse
|
|
73
|
+
if (
|
|
74
|
+
// Special cases where we want to be lousy when checking isNaN without
|
|
75
|
+
// coercing to a Number first because we handle multiple types.
|
|
76
|
+
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/
|
|
77
|
+
// Reference/Global_Objects/Number/isNaN
|
|
78
|
+
// biome-ignore lint/suspicious/noGlobalIsNan: expected might not be a number.
|
|
79
|
+
!isNaN(this.expected) &&
|
|
80
|
+
['gt', 'lt'].includes(operator) &&
|
|
81
|
+
this.field.TYPE !== 'Number'
|
|
82
|
+
) {
|
|
83
|
+
this.cast = Number.parseFloat
|
|
94
84
|
}
|
|
95
85
|
}
|
|
96
86
|
this.expected = this.cast(this.expected)
|
|
97
87
|
}
|
|
98
88
|
|
|
99
89
|
match(props) {
|
|
100
|
-
if (!this.operator || !this.active) return false
|
|
101
|
-
return this.operator(this.cast(props[this.key]))
|
|
90
|
+
if (!this.operator || !this.active || !this.field) return false
|
|
91
|
+
return this.operator(this.expected, this.cast(props[this.field.key]))
|
|
102
92
|
}
|
|
103
93
|
|
|
104
94
|
getOption(option) {
|
|
@@ -118,6 +108,7 @@ class Rule {
|
|
|
118
108
|
'name',
|
|
119
109
|
'properties.color',
|
|
120
110
|
'properties.iconClass',
|
|
111
|
+
'properties.iconSize',
|
|
121
112
|
'properties.iconUrl',
|
|
122
113
|
'properties.iconOpacity',
|
|
123
114
|
'properties.opacity',
|
|
@@ -132,7 +123,7 @@ class Rule {
|
|
|
132
123
|
const container = document.createElement('div')
|
|
133
124
|
container.appendChild(builder.build())
|
|
134
125
|
const autocomplete = new AutocompleteDatalist(builder.helpers.condition.input)
|
|
135
|
-
const properties = this.parent.
|
|
126
|
+
const properties = Array.from(this.parent.fields.keys())
|
|
136
127
|
autocomplete.suggestions = properties
|
|
137
128
|
autocomplete.input.addEventListener('input', (event) => {
|
|
138
129
|
const value = event.target.value
|
|
@@ -140,9 +131,11 @@ class Rule {
|
|
|
140
131
|
autocomplete.suggestions = [`${value}=`, `${value}!=`, `${value}>`, `${value}<`]
|
|
141
132
|
} else if (value.endsWith('=')) {
|
|
142
133
|
const key = value.split('!')[0].split('=')[0]
|
|
143
|
-
|
|
144
|
-
.
|
|
145
|
-
|
|
134
|
+
if (key) {
|
|
135
|
+
autocomplete.suggestions = this.parent
|
|
136
|
+
.sortedValues(key)
|
|
137
|
+
.map((str) => `${value}${str ?? ''}`)
|
|
138
|
+
}
|
|
146
139
|
}
|
|
147
140
|
})
|
|
148
141
|
const backButton = Utils.loadTemplate(`
|
|
@@ -123,13 +123,6 @@ export const SCHEMA = {
|
|
|
123
123
|
edit_status: {
|
|
124
124
|
type: Number,
|
|
125
125
|
},
|
|
126
|
-
editinosmControl: {
|
|
127
|
-
type: Boolean,
|
|
128
|
-
impacts: ['ui'],
|
|
129
|
-
nullable: true,
|
|
130
|
-
label: translate('Display the control to open OpenStreetMap editor'),
|
|
131
|
-
default: null,
|
|
132
|
-
},
|
|
133
126
|
editors: {
|
|
134
127
|
type: Array,
|
|
135
128
|
},
|