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
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { DomUtil } from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
2
1
|
import { translate } from '../i18n.js'
|
|
2
|
+
import * as DOMUtils from '../domutils.js'
|
|
3
3
|
|
|
4
4
|
export class Importer {
|
|
5
5
|
constructor(map, options) {
|
|
@@ -9,20 +9,20 @@ export class Importer {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
async open(importer) {
|
|
12
|
-
const container =
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
const [container, { select }] = DOMUtils.loadTemplateWithRefs(`
|
|
13
|
+
<div class="formbox">
|
|
14
|
+
<h3>${this.name}</h3>
|
|
15
|
+
<select data-ref="select">
|
|
16
|
+
<option value="">${translate('Choose a dataset')}</option>
|
|
17
|
+
</select>
|
|
18
|
+
</div>
|
|
19
|
+
`)
|
|
20
|
+
|
|
21
21
|
for (const dataset of this.choices) {
|
|
22
|
-
const option =
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
option
|
|
22
|
+
const option = DOMUtils.loadTemplate(
|
|
23
|
+
`<option value="${dataset.url}" data-format="${dataset.format || 'geojson'}">${dataset.label}</option>`
|
|
24
|
+
)
|
|
25
|
+
select.appendChild(option)
|
|
26
26
|
}
|
|
27
27
|
const confirm = () => {
|
|
28
28
|
if (select.value) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { DomEvent, DomUtil } from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
2
1
|
import { uMapAlert as Alert } from '../../components/alerts/alert.js'
|
|
3
2
|
import { BaseAjax, SingleMixin } from '../autocomplete.js'
|
|
4
3
|
import { translate } from '../i18n.js'
|
|
5
4
|
import * as Utils from '../utils.js'
|
|
5
|
+
import * as DOMUtils from '../domutils.js'
|
|
6
6
|
|
|
7
7
|
const BOUNDARY_TYPES = {
|
|
8
8
|
admin_6: 'département',
|
|
@@ -14,18 +14,20 @@ const BOUNDARY_TYPES = {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
const TEMPLATE = `
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
<
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
17
|
+
<div>
|
|
18
|
+
<h3>GeoDataMine</h3>
|
|
19
|
+
<p>${translate('GeoDataMine: thematic data from OpenStreetMap')}.</p>
|
|
20
|
+
<div class="formbox">
|
|
21
|
+
<select name="theme" data-ref="select">
|
|
22
|
+
<option value="">${translate('Choose a theme')}</option>
|
|
23
|
+
</select>
|
|
24
|
+
<label>
|
|
25
|
+
<input type="checkbox" name="aspoint" />
|
|
26
|
+
${translate('Simplify all geometries to points')}
|
|
27
|
+
</label>
|
|
28
|
+
<label id="boundary">
|
|
29
|
+
</label>
|
|
30
|
+
</div>
|
|
29
31
|
</div>
|
|
30
32
|
`
|
|
31
33
|
|
|
@@ -49,20 +51,16 @@ export class Importer {
|
|
|
49
51
|
async open(importer) {
|
|
50
52
|
let boundary = null
|
|
51
53
|
let boundaryName = null
|
|
52
|
-
const container =
|
|
53
|
-
container.innerHTML = TEMPLATE
|
|
54
|
+
const [container, { select }] = DOMUtils.loadTemplateWithRefs(TEMPLATE)
|
|
54
55
|
const response = await this.umap.request.get(`${this.baseUrl}/themes`)
|
|
55
|
-
const select = container.querySelector('select')
|
|
56
56
|
if (response?.ok) {
|
|
57
57
|
const { themes } = await response.json()
|
|
58
58
|
themes.sort((a, b) => Utils.naturalSort(a['name:fr'], b['name:fr']))
|
|
59
59
|
for (const theme of themes) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
parent: select,
|
|
65
|
-
})
|
|
60
|
+
const option = DOMUtils.loadTemplate(
|
|
61
|
+
`<option value="${theme.id}">${theme['name:fr']}</option>`
|
|
62
|
+
)
|
|
63
|
+
select.appendChild(option)
|
|
66
64
|
}
|
|
67
65
|
} else {
|
|
68
66
|
console.error(response)
|
|
@@ -63,6 +63,16 @@ const PORTALS = [
|
|
|
63
63
|
url: 'https://admin.geospm.com',
|
|
64
64
|
platform: 'prodige',
|
|
65
65
|
},
|
|
66
|
+
{
|
|
67
|
+
name: 'SNCF',
|
|
68
|
+
url: 'https://ressources.data.sncf.com',
|
|
69
|
+
platform: 'opendatasoft',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: 'Réseau STAR Rennes',
|
|
73
|
+
url: 'https://data.explore.star.fr',
|
|
74
|
+
platform: 'opendatasoft',
|
|
75
|
+
},
|
|
66
76
|
{
|
|
67
77
|
name: 'Toulouse Métropole',
|
|
68
78
|
url: 'https://data.toulouse-metropole.fr',
|
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
import { DomUtil } from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
2
1
|
import { uMapAlert as Alert } from '../../components/alerts/alert.js'
|
|
3
2
|
import { BaseAjax, SingleMixin } from '../autocomplete.js'
|
|
4
3
|
import { translate } from '../i18n.js'
|
|
4
|
+
import * as DOMUtils from '../domutils.js'
|
|
5
5
|
|
|
6
6
|
const TEMPLATE = `
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
7
|
+
<div>
|
|
8
|
+
<h3>Overpass</h3>
|
|
9
|
+
<label>
|
|
10
|
+
<span data-help="overpassImporter">${translate('Expression')}</span>
|
|
11
|
+
<input type="text" placeholder="amenity=drinking_water" name="tags" data-ref="tags" />
|
|
12
|
+
</label>
|
|
13
|
+
<label>
|
|
14
|
+
${translate('Geometry mode')}
|
|
15
|
+
<select name="out">
|
|
16
|
+
<option value="geom" selected>${translate('Default')}</option>
|
|
17
|
+
<option value="center">${translate('Only geometry centers')}</option>
|
|
18
|
+
</select>
|
|
19
|
+
</label>
|
|
20
|
+
<label data-ref="area" id="area"><span>${translate('Search area')}</span></label>
|
|
21
|
+
</div>
|
|
20
22
|
`
|
|
21
23
|
|
|
22
24
|
class Autocomplete extends SingleMixin(BaseAjax) {
|
|
@@ -57,12 +59,11 @@ export class Importer {
|
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
async open(importer) {
|
|
60
|
-
const container =
|
|
61
|
-
container.innerHTML = TEMPLATE
|
|
62
|
+
const [container, { area, tags }] = DOMUtils.loadTemplateWithRefs(TEMPLATE)
|
|
62
63
|
if (this.expression) {
|
|
63
|
-
|
|
64
|
+
tags.value = this.expression
|
|
64
65
|
}
|
|
65
|
-
this.autocomplete = new Autocomplete(
|
|
66
|
+
this.autocomplete = new Autocomplete(area, {
|
|
66
67
|
url: this.searchUrl,
|
|
67
68
|
placeholder: translate(
|
|
68
69
|
'Type area name, or let empty to load data in current map view'
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { DomUtil } from '../../vendors/leaflet/leaflet-src.esm.js'
|
|
2
1
|
import { uMapAlert as Alert } from '../components/alerts/alert.js'
|
|
3
2
|
import { MutatingForm } from './form/builder.js'
|
|
4
3
|
import { translate } from './i18n.js'
|
|
@@ -127,7 +126,11 @@ export class MapPermissions {
|
|
|
127
126
|
])
|
|
128
127
|
collaboratorsFields.push([
|
|
129
128
|
'properties.owner',
|
|
130
|
-
{
|
|
129
|
+
{
|
|
130
|
+
handler: 'ManageOwner',
|
|
131
|
+
label: translate("Map's owner"),
|
|
132
|
+
url: this._umap.properties.urls.agnocomplete,
|
|
133
|
+
},
|
|
131
134
|
])
|
|
132
135
|
if (this._umap.properties.user?.teams?.length) {
|
|
133
136
|
collaboratorsFields.push([
|
|
@@ -142,7 +145,11 @@ export class MapPermissions {
|
|
|
142
145
|
}
|
|
143
146
|
collaboratorsFields.push([
|
|
144
147
|
'properties.editors',
|
|
145
|
-
{
|
|
148
|
+
{
|
|
149
|
+
handler: 'ManageEditors',
|
|
150
|
+
label: translate("Map's editors"),
|
|
151
|
+
url: this._umap.properties.urls.agnocomplete,
|
|
152
|
+
},
|
|
146
153
|
])
|
|
147
154
|
|
|
148
155
|
const builder = new MutatingForm(this, topFields)
|
|
@@ -177,8 +184,11 @@ export class MapPermissions {
|
|
|
177
184
|
Alert.info(translate('Please save the map first'))
|
|
178
185
|
return
|
|
179
186
|
}
|
|
180
|
-
const container =
|
|
181
|
-
|
|
187
|
+
const container = DOMUtils.loadTemplate(`
|
|
188
|
+
<div class="umap-edit-permissions">
|
|
189
|
+
<h3><i class="icon icon-16 icon-key"></i> ${translate('Update permissions')}</h3>
|
|
190
|
+
</div>
|
|
191
|
+
`)
|
|
182
192
|
if (this.isAnonymousMap()) this._editAnonymous(container)
|
|
183
193
|
else this._editWithOwner(container)
|
|
184
194
|
this._editDatalayers(container)
|
|
@@ -1,6 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Control,
|
|
3
|
+
LayerGroup,
|
|
4
|
+
latLng,
|
|
5
|
+
Icon,
|
|
6
|
+
Marker,
|
|
7
|
+
} from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
8
|
+
import {
|
|
9
|
+
PhotonSearch,
|
|
10
|
+
PhotonReverse,
|
|
11
|
+
} from '../../../vendors/photon/leaflet.photon.esm.js'
|
|
2
12
|
import * as Utils from '../utils.js'
|
|
3
13
|
import { translate } from '../i18n.js'
|
|
14
|
+
import { uMapAlert as Alert } from '../../components/alerts/alert.js'
|
|
4
15
|
|
|
5
16
|
export const HomeControl = Control.extend({
|
|
6
17
|
options: {
|
|
@@ -9,8 +20,9 @@ export const HomeControl = Control.extend({
|
|
|
9
20
|
|
|
10
21
|
onAdd: (map) => {
|
|
11
22
|
const path = map._umap.getStaticPathFor('home.svg')
|
|
23
|
+
const homeURL = map._umap.urls.get('home')
|
|
12
24
|
const container = Utils.loadTemplate(
|
|
13
|
-
`<a href="
|
|
25
|
+
`<a href="${homeURL}" class="home-button" title="${translate('Back to home')}"><img src="${path}" alt="${translate('Home logo')}" width="38px" height="38px" /></a>`
|
|
14
26
|
)
|
|
15
27
|
return container
|
|
16
28
|
},
|
|
@@ -124,6 +136,7 @@ const BaseButton = Control.extend({
|
|
|
124
136
|
initialize: function (umap, options) {
|
|
125
137
|
this._umap = umap
|
|
126
138
|
Control.prototype.initialize.call(this, options)
|
|
139
|
+
this.afterInit()
|
|
127
140
|
},
|
|
128
141
|
|
|
129
142
|
onAdd: function (map) {
|
|
@@ -153,6 +166,7 @@ const BaseButton = Control.extend({
|
|
|
153
166
|
this.afterRemove(map)
|
|
154
167
|
},
|
|
155
168
|
|
|
169
|
+
afterInit: () => {},
|
|
156
170
|
afterAdd: (container, map) => {},
|
|
157
171
|
afterRemove: (map) => {},
|
|
158
172
|
})
|
|
@@ -221,7 +235,7 @@ export const SearchControl = BaseButton.extend({
|
|
|
221
235
|
},
|
|
222
236
|
|
|
223
237
|
afterAdd(container, map) {
|
|
224
|
-
this.layer =
|
|
238
|
+
this.layer = new LayerGroup().addTo(map)
|
|
225
239
|
this.photonOptions = {
|
|
226
240
|
limit: 10,
|
|
227
241
|
noResultLabel: translate('No results'),
|
|
@@ -244,7 +258,7 @@ export const SearchControl = BaseButton.extend({
|
|
|
244
258
|
const [container, { input, resultsContainer }] =
|
|
245
259
|
Utils.loadTemplateWithRefs(template)
|
|
246
260
|
const id = Math.random()
|
|
247
|
-
this.search = new
|
|
261
|
+
this.search = new Search(
|
|
248
262
|
this._umap._leafletMap,
|
|
249
263
|
input,
|
|
250
264
|
this.layer,
|
|
@@ -252,10 +266,10 @@ export const SearchControl = BaseButton.extend({
|
|
|
252
266
|
)
|
|
253
267
|
this._umap.panel.open({ content: container }).then(() => {
|
|
254
268
|
this.search.on('ajax:send', () => {
|
|
255
|
-
this._umap.
|
|
269
|
+
this._umap.loader.start(id)
|
|
256
270
|
})
|
|
257
271
|
this.search.on('ajax:return', () => {
|
|
258
|
-
this._umap.
|
|
272
|
+
this._umap.loader.stop(id)
|
|
259
273
|
})
|
|
260
274
|
this.search.resultsContainer = resultsContainer
|
|
261
275
|
input.focus()
|
|
@@ -282,19 +296,16 @@ export const AttributionControl = Control.Attribution.extend({
|
|
|
282
296
|
${originalCredits}
|
|
283
297
|
<span data-ref="short"> — ${Utils.toHTML(shortCredit)}</span>
|
|
284
298
|
<a href="#" data-ref="caption"> — ${translate('Open caption')}</a>
|
|
285
|
-
<a href="/" data-ref="home"> — ${translate('Home')}</a>
|
|
286
299
|
<a href="https://umap-project.org/" data-ref="site"> — ${translate('Powered by uMap')}</a>
|
|
287
300
|
<a href="#" class="attribution-toggle"></a>
|
|
288
301
|
</div>
|
|
289
302
|
`
|
|
290
|
-
const [container, { short, caption,
|
|
291
|
-
Utils.loadTemplateWithRefs(template)
|
|
303
|
+
const [container, { short, caption, site }] = Utils.loadTemplateWithRefs(template)
|
|
292
304
|
caption.addEventListener('click', () => this._map._umap.openCaption())
|
|
293
305
|
this._container.appendChild(container)
|
|
294
306
|
short.hidden = !shortCredit
|
|
295
307
|
caption.hidden = !captionMenus
|
|
296
308
|
site.hidden = !captionMenus
|
|
297
|
-
home.hidden = this._map._umap.isEmbed || !captionMenus
|
|
298
309
|
},
|
|
299
310
|
})
|
|
300
311
|
|
|
@@ -359,3 +370,185 @@ export const TileLayerChooser = BaseButton.extend({
|
|
|
359
370
|
return li
|
|
360
371
|
},
|
|
361
372
|
})
|
|
373
|
+
|
|
374
|
+
export const LocateControl = BaseButton.extend({
|
|
375
|
+
options: {
|
|
376
|
+
position: 'topleft',
|
|
377
|
+
title: translate('Center map on your location'),
|
|
378
|
+
icon: 'icon-locate',
|
|
379
|
+
},
|
|
380
|
+
|
|
381
|
+
async start() {
|
|
382
|
+
await this.loadPlugin()
|
|
383
|
+
this._locate.start()
|
|
384
|
+
},
|
|
385
|
+
|
|
386
|
+
stop() {
|
|
387
|
+
this._locate?.stop()
|
|
388
|
+
},
|
|
389
|
+
|
|
390
|
+
async loadPlugin() {
|
|
391
|
+
if (this._locate) return
|
|
392
|
+
const { LocateControl } = await import(
|
|
393
|
+
'../../../vendors/locatecontrol/L.Control.Locate.esm.js'
|
|
394
|
+
)
|
|
395
|
+
this._locate = new LocateControl({
|
|
396
|
+
strings: {
|
|
397
|
+
title: translate('Center map on your location'),
|
|
398
|
+
},
|
|
399
|
+
showPopup: false,
|
|
400
|
+
flyTo: this.options.easing,
|
|
401
|
+
onLocationError: (err) => Alert.error(err.message),
|
|
402
|
+
})
|
|
403
|
+
this._locate._map = this._umap._leafletMap
|
|
404
|
+
this._locate.onAdd(this._umap._leafletMap)
|
|
405
|
+
},
|
|
406
|
+
|
|
407
|
+
async onClick() {
|
|
408
|
+
if (this._locate?._active) {
|
|
409
|
+
this.stop()
|
|
410
|
+
} else {
|
|
411
|
+
this.start()
|
|
412
|
+
}
|
|
413
|
+
},
|
|
414
|
+
|
|
415
|
+
afterRemove() {
|
|
416
|
+
this.stop()
|
|
417
|
+
},
|
|
418
|
+
|
|
419
|
+
afterInit() {
|
|
420
|
+
this._umap._leafletMap.on('locateactivate', () => {
|
|
421
|
+
this._container.classList.add('active')
|
|
422
|
+
})
|
|
423
|
+
this._umap._leafletMap.on('locatedeactivate', () => {
|
|
424
|
+
this._container.classList.remove('active')
|
|
425
|
+
})
|
|
426
|
+
},
|
|
427
|
+
})
|
|
428
|
+
|
|
429
|
+
export const Search = PhotonSearch.extend({
|
|
430
|
+
initialize: function (map, input, layer, options) {
|
|
431
|
+
this.options.placeholder = translate('Type a place name or coordinates')
|
|
432
|
+
this.options.location_bias_scale = 0.5
|
|
433
|
+
PhotonSearch.prototype.initialize.call(this, map, input, options)
|
|
434
|
+
this.options.url = map.options.urls.search
|
|
435
|
+
if (map.options.maxBounds) this.options.bbox = map.options.maxBounds.toBBoxString()
|
|
436
|
+
this.reverse = new PhotonReverse({
|
|
437
|
+
handleResults: (geojson) => {
|
|
438
|
+
this.handleResultsWithReverse(geojson)
|
|
439
|
+
},
|
|
440
|
+
})
|
|
441
|
+
this.layer = layer
|
|
442
|
+
},
|
|
443
|
+
|
|
444
|
+
handleResultsWithReverse: function (geojson) {
|
|
445
|
+
const latlng = this.reverse.latlng
|
|
446
|
+
geojson.features.unshift({
|
|
447
|
+
type: 'Feature',
|
|
448
|
+
geometry: { type: 'Point', coordinates: [latlng.lng, latlng.lat] },
|
|
449
|
+
properties: {
|
|
450
|
+
name: translate('Go to "{coords}"', { coords: `${latlng.lat} ${latlng.lng}` }),
|
|
451
|
+
},
|
|
452
|
+
})
|
|
453
|
+
|
|
454
|
+
this.handleResults(geojson)
|
|
455
|
+
},
|
|
456
|
+
|
|
457
|
+
search: function () {
|
|
458
|
+
this.layer.clearLayers()
|
|
459
|
+
const pattern = /^(?<lat>[-+]?\d{1,2}[.,]\d+)\s*[ ,]\s*(?<lng>[-+]?\d{1,3}[.,]\d+)$/
|
|
460
|
+
if (pattern.test(this.input.value)) {
|
|
461
|
+
this.hide()
|
|
462
|
+
const { lat, lng } = pattern.exec(this.input.value).groups
|
|
463
|
+
const latlng = latLng(lat, lng)
|
|
464
|
+
if (Utils.LatLngIsValid(latlng)) {
|
|
465
|
+
this.reverse.doReverse(latlng)
|
|
466
|
+
} else {
|
|
467
|
+
Alert.error(translate('Invalid latitude or longitude'))
|
|
468
|
+
}
|
|
469
|
+
return
|
|
470
|
+
}
|
|
471
|
+
// Only numbers, abort.
|
|
472
|
+
if (/^[\d .,]*$/.test(this.input.value)) return
|
|
473
|
+
// Do normal search
|
|
474
|
+
this.options.includePosition = this.map.getZoom() > 10
|
|
475
|
+
PhotonSearch.prototype.search.call(this)
|
|
476
|
+
},
|
|
477
|
+
|
|
478
|
+
onBlur: function (e) {
|
|
479
|
+
// Overrided because we don't want to hide the results on blur.
|
|
480
|
+
this.fire('blur')
|
|
481
|
+
},
|
|
482
|
+
|
|
483
|
+
formatResult: function (feature, el) {
|
|
484
|
+
const [tools, { point, geom }] = Utils.loadTemplateWithRefs(`
|
|
485
|
+
<span class="search-result-tools">
|
|
486
|
+
<button type="button" title="${translate('Add this geometry to my map')}" data-ref=geom><i class="icon icon-16 icon-polygon-plus"></i></button>
|
|
487
|
+
<button type="button" title="${translate('Add this place to my map')}" data-ref=point><i class="icon icon-16 icon-marker-plus"></i></button>
|
|
488
|
+
</span>
|
|
489
|
+
`)
|
|
490
|
+
geom.hidden = !['R', 'W'].includes(feature.properties.osm_type)
|
|
491
|
+
point.addEventListener('mousedown', (event) => {
|
|
492
|
+
event.stopPropagation()
|
|
493
|
+
const datalayer = this.map._umap.defaultEditDataLayer()
|
|
494
|
+
const marker = datalayer.makeFeature(feature)
|
|
495
|
+
marker.edit()
|
|
496
|
+
})
|
|
497
|
+
geom.addEventListener('mousedown', async (event) => {
|
|
498
|
+
event.stopPropagation()
|
|
499
|
+
const osm_id = feature.properties.osm_id
|
|
500
|
+
const types = {
|
|
501
|
+
R: 'relation',
|
|
502
|
+
W: 'way',
|
|
503
|
+
N: 'node',
|
|
504
|
+
}
|
|
505
|
+
const osm_type = types[feature.properties.osm_type]
|
|
506
|
+
if (!osm_type || !osm_id) return
|
|
507
|
+
const importer = this.map._umap.importer
|
|
508
|
+
importer.build()
|
|
509
|
+
importer.format = 'geojson'
|
|
510
|
+
importer.raw = await this.getOSMObject(osm_type, osm_id)
|
|
511
|
+
importer.submit()
|
|
512
|
+
})
|
|
513
|
+
el.appendChild(tools)
|
|
514
|
+
this._formatResult(feature, el)
|
|
515
|
+
const path = this.map._umap.getStaticPathFor('target.svg')
|
|
516
|
+
const icon = new Icon({
|
|
517
|
+
iconUrl: path,
|
|
518
|
+
iconSize: [24, 24],
|
|
519
|
+
iconAnchor: [12, 12],
|
|
520
|
+
})
|
|
521
|
+
const coords = feature.geometry.coordinates
|
|
522
|
+
const target = new Marker([coords[1], coords[0]], { icon })
|
|
523
|
+
el.addEventListener('mouseover', (event) => {
|
|
524
|
+
target.addTo(this.layer)
|
|
525
|
+
})
|
|
526
|
+
el.addEventListener('mouseout', (event) => {
|
|
527
|
+
target.removeFrom(this.layer)
|
|
528
|
+
})
|
|
529
|
+
},
|
|
530
|
+
|
|
531
|
+
async getOSMObject(osm_type, osm_id) {
|
|
532
|
+
const url = `https://www.openstreetmap.org/api/0.6/${osm_type}/${osm_id}/full`
|
|
533
|
+
const response = await this.map._umap.request.get(url)
|
|
534
|
+
if (response?.ok) {
|
|
535
|
+
const data = await this.map._umap.formatter.fromOSM(await response.text())
|
|
536
|
+
data.features = data.features.filter(
|
|
537
|
+
(feature) => feature.properties.id === `${osm_type}/${osm_id}`
|
|
538
|
+
)
|
|
539
|
+
return JSON.stringify(data)
|
|
540
|
+
}
|
|
541
|
+
},
|
|
542
|
+
|
|
543
|
+
setChoice: function (choice) {
|
|
544
|
+
choice = choice || this.RESULTS[this.CURRENT]
|
|
545
|
+
if (choice) {
|
|
546
|
+
const feature = choice.feature
|
|
547
|
+
const zoom = Math.max(this.map.getZoom(), 14) // Never unzoom.
|
|
548
|
+
this.map.setView(
|
|
549
|
+
[feature.geometry.coordinates[1], feature.geometry.coordinates[0]],
|
|
550
|
+
zoom
|
|
551
|
+
)
|
|
552
|
+
}
|
|
553
|
+
},
|
|
554
|
+
})
|
|
@@ -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'
|
|
@@ -80,7 +80,7 @@ const ClassifiedMixin = {
|
|
|
80
80
|
const ul = Utils.loadTemplate('<ul></ul>')
|
|
81
81
|
const items = this.getLegendItems()
|
|
82
82
|
for (const [color, label] of items) {
|
|
83
|
-
const rgbColor = DOMUtils.
|
|
83
|
+
const rgbColor = DOMUtils.colorToRGB(color)
|
|
84
84
|
const opacity = this.datalayer.getOption('fillOpacity')
|
|
85
85
|
const bgColor = `rgba(${rgbColor.join(',')}, ${opacity})`
|
|
86
86
|
const li = Utils.loadTemplate(`
|
|
@@ -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
|
})
|