umap-project 2.7.3__py3-none-any.whl → 2.8.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/forms.py +4 -14
- umap/locale/am_ET/LC_MESSAGES/django.mo +0 -0
- umap/locale/am_ET/LC_MESSAGES/django.po +278 -151
- umap/locale/ar/LC_MESSAGES/django.mo +0 -0
- umap/locale/ar/LC_MESSAGES/django.po +335 -141
- umap/locale/bg/LC_MESSAGES/django.mo +0 -0
- umap/locale/bg/LC_MESSAGES/django.po +279 -152
- umap/locale/br/LC_MESSAGES/django.mo +0 -0
- umap/locale/br/LC_MESSAGES/django.po +95 -79
- umap/locale/ca/LC_MESSAGES/django.mo +0 -0
- umap/locale/ca/LC_MESSAGES/django.po +85 -68
- umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- umap/locale/cs_CZ/LC_MESSAGES/django.po +78 -66
- umap/locale/da/LC_MESSAGES/django.mo +0 -0
- umap/locale/da/LC_MESSAGES/django.po +280 -153
- umap/locale/de/LC_MESSAGES/django.mo +0 -0
- umap/locale/de/LC_MESSAGES/django.po +80 -64
- umap/locale/el/LC_MESSAGES/django.mo +0 -0
- umap/locale/el/LC_MESSAGES/django.po +82 -66
- umap/locale/en/LC_MESSAGES/django.po +73 -61
- umap/locale/es/LC_MESSAGES/django.mo +0 -0
- umap/locale/es/LC_MESSAGES/django.po +75 -63
- umap/locale/et/LC_MESSAGES/django.mo +0 -0
- umap/locale/et/LC_MESSAGES/django.po +280 -153
- umap/locale/eu/LC_MESSAGES/django.mo +0 -0
- umap/locale/eu/LC_MESSAGES/django.po +82 -66
- umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
- umap/locale/fa_IR/LC_MESSAGES/django.po +80 -64
- umap/locale/fi/LC_MESSAGES/django.mo +0 -0
- umap/locale/fi/LC_MESSAGES/django.po +278 -151
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +75 -63
- umap/locale/gl/LC_MESSAGES/django.mo +0 -0
- umap/locale/gl/LC_MESSAGES/django.po +280 -153
- umap/locale/he/LC_MESSAGES/django.mo +0 -0
- umap/locale/he/LC_MESSAGES/django.po +281 -154
- umap/locale/hu/LC_MESSAGES/django.mo +0 -0
- umap/locale/hu/LC_MESSAGES/django.po +80 -64
- umap/locale/is/LC_MESSAGES/django.mo +0 -0
- umap/locale/is/LC_MESSAGES/django.po +280 -153
- umap/locale/it/LC_MESSAGES/django.mo +0 -0
- umap/locale/it/LC_MESSAGES/django.po +82 -66
- umap/locale/ja/LC_MESSAGES/django.mo +0 -0
- umap/locale/ja/LC_MESSAGES/django.po +280 -153
- umap/locale/ko/LC_MESSAGES/django.mo +0 -0
- umap/locale/ko/LC_MESSAGES/django.po +280 -153
- umap/locale/lt/LC_MESSAGES/django.mo +0 -0
- umap/locale/lt/LC_MESSAGES/django.po +280 -153
- umap/locale/ms/LC_MESSAGES/django.mo +0 -0
- umap/locale/ms/LC_MESSAGES/django.po +82 -66
- umap/locale/nl/LC_MESSAGES/django.mo +0 -0
- umap/locale/nl/LC_MESSAGES/django.po +280 -153
- umap/locale/pl/LC_MESSAGES/django.mo +0 -0
- umap/locale/pl/LC_MESSAGES/django.po +82 -66
- umap/locale/pt/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt/LC_MESSAGES/django.po +75 -63
- umap/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt_BR/LC_MESSAGES/django.po +280 -153
- umap/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt_PT/LC_MESSAGES/django.po +280 -153
- umap/locale/ru/LC_MESSAGES/django.mo +0 -0
- umap/locale/ru/LC_MESSAGES/django.po +280 -153
- umap/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
- umap/locale/sk_SK/LC_MESSAGES/django.po +280 -153
- umap/locale/sl/LC_MESSAGES/django.mo +0 -0
- umap/locale/sl/LC_MESSAGES/django.po +280 -153
- umap/locale/sr/LC_MESSAGES/django.mo +0 -0
- umap/locale/sr/LC_MESSAGES/django.po +280 -153
- umap/locale/sv/LC_MESSAGES/django.mo +0 -0
- umap/locale/sv/LC_MESSAGES/django.po +81 -65
- umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
- umap/locale/th_TH/LC_MESSAGES/django.po +257 -185
- umap/locale/tr/LC_MESSAGES/django.mo +0 -0
- umap/locale/tr/LC_MESSAGES/django.po +280 -153
- umap/locale/uk_UA/LC_MESSAGES/django.mo +0 -0
- umap/locale/uk_UA/LC_MESSAGES/django.po +280 -153
- umap/locale/vi/LC_MESSAGES/django.mo +0 -0
- umap/locale/vi/LC_MESSAGES/django.po +278 -151
- umap/locale/zh/LC_MESSAGES/django.mo +0 -0
- umap/locale/zh/LC_MESSAGES/django.po +278 -151
- umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
- umap/locale/zh_TW/LC_MESSAGES/django.po +97 -81
- umap/management/commands/empty_trash.py +35 -0
- umap/management/commands/migrate_to_S3.py +29 -0
- umap/migrations/0023_alter_datalayer_uuid.py +19 -0
- umap/migrations/0024_alter_map_share_status.py +30 -0
- umap/migrations/0025_alter_datalayer_geojson.py +24 -0
- umap/models.py +68 -116
- umap/settings/base.py +23 -3
- umap/settings/local_s3.py +45 -0
- umap/static/umap/base.css +3 -603
- umap/static/umap/content.css +5 -3
- umap/static/umap/css/bar.css +202 -0
- umap/static/umap/css/form.css +620 -0
- umap/static/umap/css/icon.css +21 -1
- umap/static/umap/css/popup.css +125 -0
- umap/static/umap/img/16-white.svg +16 -4
- umap/static/umap/img/16.svg +1 -1
- umap/static/umap/img/source/16-white.svg +46 -45
- umap/static/umap/img/source/16.svg +1 -753
- umap/static/umap/js/components/fragment.js +3 -1
- umap/static/umap/js/modules/browser.js +20 -19
- umap/static/umap/js/modules/caption.js +21 -22
- umap/static/umap/js/modules/data/features.js +120 -78
- umap/static/umap/js/modules/data/layer.js +195 -153
- umap/static/umap/js/modules/facets.js +9 -9
- umap/static/umap/js/modules/formatter.js +5 -5
- umap/static/umap/js/modules/global.js +4 -52
- umap/static/umap/js/modules/help.js +18 -21
- umap/static/umap/js/modules/importer.js +133 -56
- umap/static/umap/js/modules/importers/cadastrefr.js +4 -0
- umap/static/umap/js/modules/importers/geodatamine.js +3 -3
- umap/static/umap/js/modules/importers/overpass.js +5 -0
- umap/static/umap/js/modules/permissions.js +85 -87
- umap/static/umap/js/modules/rendering/icon.js +2 -1
- umap/static/umap/js/modules/rendering/layers/base.js +15 -15
- umap/static/umap/js/modules/rendering/layers/classified.js +1 -1
- umap/static/umap/js/modules/rendering/layers/cluster.js +1 -1
- umap/static/umap/js/modules/rendering/layers/heat.js +1 -1
- umap/static/umap/js/modules/rendering/map.js +390 -0
- umap/static/umap/js/modules/rendering/popup.js +19 -19
- umap/static/umap/js/modules/rendering/template.js +88 -21
- umap/static/umap/js/modules/rendering/ui.js +63 -14
- umap/static/umap/js/modules/request.js +2 -2
- umap/static/umap/js/modules/rules.js +22 -25
- umap/static/umap/js/modules/saving.js +47 -0
- umap/static/umap/js/modules/schema.js +6 -0
- umap/static/umap/js/modules/share.js +21 -24
- umap/static/umap/js/modules/slideshow.js +24 -20
- umap/static/umap/js/modules/sync/updaters.js +7 -9
- umap/static/umap/js/modules/tableeditor.js +20 -19
- umap/static/umap/js/modules/ui/bar.js +196 -0
- umap/static/umap/js/modules/ui/dialog.js +5 -0
- umap/static/umap/js/modules/ui/panel.js +10 -9
- umap/static/umap/js/modules/umap.js +1691 -0
- umap/static/umap/js/modules/urls.js +2 -2
- umap/static/umap/js/modules/utils.js +22 -6
- umap/static/umap/js/umap.controls.js +81 -305
- umap/static/umap/js/umap.core.js +29 -50
- umap/static/umap/js/umap.forms.js +78 -27
- umap/static/umap/keycloak.png +0 -0
- umap/static/umap/locale/am_ET.js +26 -10
- umap/static/umap/locale/am_ET.json +26 -10
- umap/static/umap/locale/ar.js +26 -10
- umap/static/umap/locale/ar.json +26 -10
- umap/static/umap/locale/ast.js +26 -10
- umap/static/umap/locale/ast.json +26 -10
- umap/static/umap/locale/bg.js +26 -10
- umap/static/umap/locale/bg.json +26 -10
- umap/static/umap/locale/br.js +27 -20
- umap/static/umap/locale/br.json +27 -20
- umap/static/umap/locale/ca.js +32 -29
- umap/static/umap/locale/ca.json +32 -29
- umap/static/umap/locale/cs_CZ.js +24 -17
- umap/static/umap/locale/cs_CZ.json +24 -17
- umap/static/umap/locale/da.js +26 -10
- umap/static/umap/locale/da.json +26 -10
- umap/static/umap/locale/de.js +21 -14
- umap/static/umap/locale/de.json +21 -14
- umap/static/umap/locale/el.js +28 -12
- umap/static/umap/locale/el.json +28 -12
- umap/static/umap/locale/en.js +14 -9
- umap/static/umap/locale/en.json +14 -9
- umap/static/umap/locale/en_US.json +26 -10
- umap/static/umap/locale/es.js +16 -13
- umap/static/umap/locale/es.json +16 -13
- umap/static/umap/locale/et.js +26 -10
- umap/static/umap/locale/et.json +26 -10
- umap/static/umap/locale/eu.js +16 -9
- umap/static/umap/locale/eu.json +16 -9
- umap/static/umap/locale/fa_IR.js +16 -9
- umap/static/umap/locale/fa_IR.json +16 -9
- umap/static/umap/locale/fi.js +26 -10
- umap/static/umap/locale/fi.json +26 -10
- umap/static/umap/locale/fr.js +14 -9
- umap/static/umap/locale/fr.json +14 -9
- umap/static/umap/locale/gl.js +26 -10
- umap/static/umap/locale/gl.json +26 -10
- umap/static/umap/locale/he.js +26 -10
- umap/static/umap/locale/he.json +26 -10
- umap/static/umap/locale/hr.js +26 -10
- umap/static/umap/locale/hr.json +26 -10
- umap/static/umap/locale/hu.js +16 -9
- umap/static/umap/locale/hu.json +16 -9
- umap/static/umap/locale/id.js +26 -10
- umap/static/umap/locale/id.json +26 -10
- umap/static/umap/locale/is.js +26 -10
- umap/static/umap/locale/is.json +26 -10
- umap/static/umap/locale/it.js +26 -10
- umap/static/umap/locale/it.json +26 -10
- umap/static/umap/locale/ja.js +26 -10
- umap/static/umap/locale/ja.json +26 -10
- umap/static/umap/locale/ko.js +26 -10
- umap/static/umap/locale/ko.json +26 -10
- umap/static/umap/locale/lt.js +26 -10
- umap/static/umap/locale/lt.json +26 -10
- umap/static/umap/locale/ms.js +28 -12
- umap/static/umap/locale/ms.json +28 -12
- umap/static/umap/locale/nl.js +28 -12
- umap/static/umap/locale/nl.json +28 -12
- umap/static/umap/locale/no.js +26 -10
- umap/static/umap/locale/no.json +26 -10
- umap/static/umap/locale/pl.js +28 -12
- umap/static/umap/locale/pl.json +28 -12
- umap/static/umap/locale/pl_PL.json +26 -10
- umap/static/umap/locale/pt.js +16 -9
- umap/static/umap/locale/pt.json +16 -9
- umap/static/umap/locale/pt_BR.js +26 -10
- umap/static/umap/locale/pt_BR.json +26 -10
- umap/static/umap/locale/pt_PT.js +16 -9
- umap/static/umap/locale/pt_PT.json +16 -9
- umap/static/umap/locale/ro.js +26 -10
- umap/static/umap/locale/ro.json +26 -10
- umap/static/umap/locale/ru.js +26 -10
- umap/static/umap/locale/ru.json +26 -10
- umap/static/umap/locale/si.js +7 -7
- umap/static/umap/locale/si.json +7 -7
- umap/static/umap/locale/sk_SK.js +26 -10
- umap/static/umap/locale/sk_SK.json +26 -10
- umap/static/umap/locale/sl.js +26 -10
- umap/static/umap/locale/sl.json +26 -10
- umap/static/umap/locale/sr.js +26 -10
- umap/static/umap/locale/sr.json +26 -10
- umap/static/umap/locale/sv.js +27 -11
- umap/static/umap/locale/sv.json +27 -11
- umap/static/umap/locale/th_TH.js +28 -12
- umap/static/umap/locale/th_TH.json +28 -12
- umap/static/umap/locale/tr.js +26 -10
- umap/static/umap/locale/tr.json +26 -10
- umap/static/umap/locale/uk_UA.js +26 -10
- umap/static/umap/locale/uk_UA.json +26 -10
- umap/static/umap/locale/vi.js +26 -10
- umap/static/umap/locale/vi.json +26 -10
- umap/static/umap/locale/vi_VN.json +26 -10
- umap/static/umap/locale/zh.js +26 -10
- umap/static/umap/locale/zh.json +26 -10
- umap/static/umap/locale/zh_CN.json +26 -10
- umap/static/umap/locale/zh_TW.Big5.json +26 -10
- umap/static/umap/locale/zh_TW.js +34 -27
- umap/static/umap/locale/zh_TW.json +34 -27
- umap/static/umap/map.css +39 -530
- umap/static/umap/unittests/URLs.js +15 -15
- umap/static/umap/unittests/utils.js +23 -1
- umap/static/umap/vars.css +2 -1
- umap/static/umap/vendors/formbuilder/Leaflet.FormBuilder.js +5 -1
- umap/storage/__init__.py +3 -0
- umap/storage/fs.py +101 -0
- umap/storage/s3.py +61 -0
- umap/templates/base.html +2 -0
- umap/templates/registration/login.html +7 -6
- umap/templates/umap/components/alerts/alert.html +4 -0
- umap/templates/umap/css.html +6 -0
- umap/templates/umap/js.html +3 -2
- umap/templates/umap/map_init.html +6 -5
- umap/templates/umap/user_dashboard.html +20 -19
- umap/tests/base.py +5 -1
- umap/tests/fixtures/test_upload_simple_marker.json +19 -0
- umap/tests/integration/conftest.py +2 -1
- umap/tests/integration/test_anonymous_owned_map.py +18 -10
- umap/tests/integration/test_browser.py +16 -1
- umap/tests/integration/test_dashboard.py +1 -1
- umap/tests/integration/test_edit_datalayer.py +29 -7
- umap/tests/integration/test_import.py +28 -6
- umap/tests/integration/test_optimistic_merge.py +31 -8
- umap/tests/integration/test_owned_map.py +22 -16
- umap/tests/integration/test_popup.py +44 -0
- umap/tests/integration/test_save.py +35 -0
- umap/tests/integration/test_view_marker.py +12 -0
- umap/tests/integration/test_view_polyline.py +257 -0
- umap/tests/integration/test_websocket_sync.py +81 -9
- umap/tests/test_dashboard.py +82 -0
- umap/tests/test_datalayer.py +6 -7
- umap/tests/test_datalayer_s3.py +135 -0
- umap/tests/test_datalayer_views.py +28 -10
- umap/tests/test_empty_trash.py +34 -0
- umap/tests/test_map.py +12 -3
- umap/tests/test_map_views.py +69 -37
- umap/tests/test_statics.py +1 -1
- umap/tests/test_team_views.py +35 -1
- umap/tests/test_views.py +31 -52
- umap/urls.py +3 -3
- umap/views.py +126 -90
- {umap_project-2.7.3.dist-info → umap_project-2.8.0.dist-info}/METADATA +16 -13
- {umap_project-2.7.3.dist-info → umap_project-2.8.0.dist-info}/RECORD +289 -269
- umap/management/commands/purge_purgatory.py +0 -28
- umap/static/umap/js/umap.js +0 -1903
- umap/tests/test_purge_purgatory.py +0 -25
- /umap/{storage.py → storage/staticfiles.py} +0 -0
- {umap_project-2.7.3.dist-info → umap_project-2.8.0.dist-info}/WHEEL +0 -0
- {umap_project-2.7.3.dist-info → umap_project-2.8.0.dist-info}/entry_points.txt +0 -0
- {umap_project-2.7.3.dist-info → umap_project-2.8.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
// Goes here all code related to Leaflet, DOM and user interactions.
|
|
2
|
+
import {
|
|
3
|
+
Map as BaseMap,
|
|
4
|
+
DomUtil,
|
|
5
|
+
DomEvent,
|
|
6
|
+
latLngBounds,
|
|
7
|
+
latLng,
|
|
8
|
+
Control,
|
|
9
|
+
setOptions,
|
|
10
|
+
} from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
11
|
+
import { translate } from '../i18n.js'
|
|
12
|
+
import { uMapAlert as Alert } from '../../components/alerts/alert.js'
|
|
13
|
+
import * as Utils from '../utils.js'
|
|
14
|
+
import * as Icon from './icon.js'
|
|
15
|
+
|
|
16
|
+
// Those options are not saved on the server, so they can live here
|
|
17
|
+
// instead of in umap.properties
|
|
18
|
+
BaseMap.mergeOptions({
|
|
19
|
+
demoTileInfos: { s: 'a', z: 9, x: 265, y: 181, '-y': 181, r: '' },
|
|
20
|
+
attributionControl: false,
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const ControlsMixin = {
|
|
24
|
+
HIDDABLE_CONTROLS: [
|
|
25
|
+
'zoom',
|
|
26
|
+
'search',
|
|
27
|
+
'fullscreen',
|
|
28
|
+
'embed',
|
|
29
|
+
'datalayers',
|
|
30
|
+
'caption',
|
|
31
|
+
'locate',
|
|
32
|
+
'measure',
|
|
33
|
+
'editinosm',
|
|
34
|
+
'star',
|
|
35
|
+
'tilelayers',
|
|
36
|
+
],
|
|
37
|
+
|
|
38
|
+
initControls: function () {
|
|
39
|
+
this._controls = {}
|
|
40
|
+
|
|
41
|
+
if (this._umap.hasEditMode() && !this.options.noControl) {
|
|
42
|
+
new U.EditControl(this).addTo(this)
|
|
43
|
+
|
|
44
|
+
new U.DrawToolbar({ map: this }).addTo(this)
|
|
45
|
+
const editActions = [
|
|
46
|
+
U.EditCaptionAction,
|
|
47
|
+
U.ImportAction,
|
|
48
|
+
U.EditLayersAction,
|
|
49
|
+
U.ChangeTileLayerAction,
|
|
50
|
+
U.UpdateExtentAction,
|
|
51
|
+
U.UpdatePermsAction,
|
|
52
|
+
U.EditPropertiesAction,
|
|
53
|
+
]
|
|
54
|
+
if (this.options.editMode === 'advanced') {
|
|
55
|
+
new U.SettingsToolbar({ actions: editActions }).addTo(this)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
this._controls.zoom = new Control.Zoom({
|
|
59
|
+
zoomInTitle: translate('Zoom in'),
|
|
60
|
+
zoomOutTitle: translate('Zoom out'),
|
|
61
|
+
})
|
|
62
|
+
this._controls.datalayers = new U.DataLayersControl(this._umap)
|
|
63
|
+
this._controls.caption = new U.CaptionControl(this._umap)
|
|
64
|
+
this._controls.locate = new U.Locate(this, {
|
|
65
|
+
strings: {
|
|
66
|
+
title: translate('Center map on your location'),
|
|
67
|
+
},
|
|
68
|
+
showPopup: false,
|
|
69
|
+
// We style this control in our own CSS for consistency with other controls,
|
|
70
|
+
// but the control breaks if we don't specify a class here, so a fake class
|
|
71
|
+
// will do.
|
|
72
|
+
icon: 'umap-fake-class',
|
|
73
|
+
iconLoading: 'umap-fake-class',
|
|
74
|
+
flyTo: this.options.easing,
|
|
75
|
+
onLocationError: (err) => U.Alert.error(err.message),
|
|
76
|
+
})
|
|
77
|
+
this._controls.fullscreen = new Control.Fullscreen({
|
|
78
|
+
title: {
|
|
79
|
+
false: translate('View Fullscreen'),
|
|
80
|
+
true: translate('Exit Fullscreen'),
|
|
81
|
+
},
|
|
82
|
+
})
|
|
83
|
+
this._controls.search = new U.SearchControl()
|
|
84
|
+
this._controls.embed = new Control.Embed(this._umap)
|
|
85
|
+
this._controls.tilelayersChooser = new U.TileLayerChooser(this)
|
|
86
|
+
if (this.options.user?.id) this._controls.star = new U.StarControl(this._umap)
|
|
87
|
+
this._controls.editinosm = new Control.EditInOSM({
|
|
88
|
+
position: 'topleft',
|
|
89
|
+
widgetOptions: {
|
|
90
|
+
helpText: translate(
|
|
91
|
+
'Open this map extent in a map editor to provide more accurate data to OpenStreetMap'
|
|
92
|
+
),
|
|
93
|
+
},
|
|
94
|
+
})
|
|
95
|
+
this._controls.measure = new L.MeasureControl().initHandler(this)
|
|
96
|
+
this._controls.more = new U.MoreControls()
|
|
97
|
+
this._controls.scale = L.control.scale()
|
|
98
|
+
this._controls.permanentCredit = new U.PermanentCreditsControl(this)
|
|
99
|
+
this._umap.drop = new U.DropControl(this)
|
|
100
|
+
this._controls.tilelayers = new U.TileLayerControl(this)
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
renderControls: function () {
|
|
104
|
+
for (const control of Object.values(this._controls)) {
|
|
105
|
+
this.removeControl(control)
|
|
106
|
+
}
|
|
107
|
+
if (this.options.noControl) return
|
|
108
|
+
|
|
109
|
+
this._controls.attribution = new U.AttributionControl().addTo(this)
|
|
110
|
+
if (this.options.miniMap) {
|
|
111
|
+
this.whenReady(function () {
|
|
112
|
+
if (this.selectedTilelayer) {
|
|
113
|
+
this._controls.miniMap = new Control.MiniMap(this.selectedTilelayer, {
|
|
114
|
+
aimingRectOptions: {
|
|
115
|
+
color: this._umap.getProperty('color'),
|
|
116
|
+
fillColor: this._umap.getProperty('fillColor'),
|
|
117
|
+
stroke: this._umap.getProperty('stroke'),
|
|
118
|
+
fill: this._umap.getProperty('fill'),
|
|
119
|
+
weight: this._umap.getProperty('weight'),
|
|
120
|
+
opacity: this._umap.getProperty('opacity'),
|
|
121
|
+
fillOpacity: this._umap.getProperty('fillOpacity'),
|
|
122
|
+
},
|
|
123
|
+
}).addTo(this)
|
|
124
|
+
this._controls.miniMap._miniMap.invalidateSize()
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
}
|
|
128
|
+
for (const name of this.HIDDABLE_CONTROLS) {
|
|
129
|
+
const status = this._umap.getProperty(`${name}Control`)
|
|
130
|
+
if (status === false) continue
|
|
131
|
+
const control = this._controls[name]
|
|
132
|
+
if (!control) continue
|
|
133
|
+
control.addTo(this)
|
|
134
|
+
if (status === undefined || status === null) {
|
|
135
|
+
DomUtil.addClass(control._container, 'display-on-more')
|
|
136
|
+
} else {
|
|
137
|
+
DomUtil.removeClass(control._container, 'display-on-more')
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (this._umap.getProperty('permanentCredit'))
|
|
141
|
+
this._controls.permanentCredit.addTo(this)
|
|
142
|
+
if (this._umap.getProperty('moreControl')) this._controls.more.addTo(this)
|
|
143
|
+
if (this._umap.getProperty('scaleControl')) this._controls.scale.addTo(this)
|
|
144
|
+
this._controls.tilelayers.setLayers()
|
|
145
|
+
},
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const ManageTilelayerMixin = {
|
|
149
|
+
initTileLayers: function () {
|
|
150
|
+
this.tilelayers = []
|
|
151
|
+
for (const props of this.options.tilelayers) {
|
|
152
|
+
const layer = this.createTileLayer(props)
|
|
153
|
+
this.tilelayers.push(layer)
|
|
154
|
+
if (
|
|
155
|
+
this.options.tilelayer &&
|
|
156
|
+
this.options.tilelayer.url_template === props.url_template
|
|
157
|
+
) {
|
|
158
|
+
// Keep control over the displayed attribution for non custom tilelayers
|
|
159
|
+
this.options.tilelayer.attribution = props.attribution
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (this.options.tilelayer?.url_template && this.options.tilelayer.attribution) {
|
|
163
|
+
this.customTilelayer = this.createTileLayer(this.options.tilelayer)
|
|
164
|
+
this.selectTileLayer(this.customTilelayer)
|
|
165
|
+
} else {
|
|
166
|
+
this.selectTileLayer(this.tilelayers[0])
|
|
167
|
+
}
|
|
168
|
+
if (this._controls) this._controls.tilelayers.setLayers()
|
|
169
|
+
},
|
|
170
|
+
|
|
171
|
+
createTileLayer: (tilelayer) => new L.TileLayer(tilelayer.url_template, tilelayer),
|
|
172
|
+
|
|
173
|
+
selectTileLayer: function (tilelayer) {
|
|
174
|
+
if (tilelayer === this.selectedTilelayer) {
|
|
175
|
+
return
|
|
176
|
+
}
|
|
177
|
+
try {
|
|
178
|
+
this.addLayer(tilelayer)
|
|
179
|
+
this.fire('baselayerchange', { layer: tilelayer })
|
|
180
|
+
if (this.selectedTilelayer) {
|
|
181
|
+
this.removeLayer(this.selectedTilelayer)
|
|
182
|
+
}
|
|
183
|
+
this.selectedTilelayer = tilelayer
|
|
184
|
+
if (
|
|
185
|
+
!Number.isNaN(this.selectedTilelayer.options.minZoom) &&
|
|
186
|
+
this.getZoom() < this.selectedTilelayer.options.minZoom
|
|
187
|
+
) {
|
|
188
|
+
this.setZoom(this.selectedTilelayer.options.minZoom)
|
|
189
|
+
}
|
|
190
|
+
if (
|
|
191
|
+
!Number.isNaN(this.selectedTilelayer.options.maxZoom) &&
|
|
192
|
+
this.getZoom() > this.selectedTilelayer.options.maxZoom
|
|
193
|
+
) {
|
|
194
|
+
this.setZoom(this.selectedTilelayer.options.maxZoom)
|
|
195
|
+
}
|
|
196
|
+
} catch (e) {
|
|
197
|
+
console.error(e)
|
|
198
|
+
this.removeLayer(tilelayer)
|
|
199
|
+
Alert.error(`${translate('Error in the tilelayer URL')}: ${tilelayer._url}`)
|
|
200
|
+
// Users can put tilelayer URLs by hand, and if they add wrong {variable},
|
|
201
|
+
// Leaflet throw an error, and then the map is no more editable
|
|
202
|
+
}
|
|
203
|
+
this.setOverlay()
|
|
204
|
+
},
|
|
205
|
+
|
|
206
|
+
eachTileLayer: function (callback, context) {
|
|
207
|
+
const urls = []
|
|
208
|
+
const callOne = (layer) => {
|
|
209
|
+
// Prevent adding a duplicate background,
|
|
210
|
+
// while adding selected/custom on top of the list
|
|
211
|
+
const url = layer.options.url_template
|
|
212
|
+
if (urls.indexOf(url) !== -1) return
|
|
213
|
+
callback.call(context, layer)
|
|
214
|
+
urls.push(url)
|
|
215
|
+
}
|
|
216
|
+
if (this.selectedTilelayer) callOne(this.selectedTilelayer)
|
|
217
|
+
if (this.customTilelayer) callOne(this.customTilelayer)
|
|
218
|
+
this.tilelayers.forEach(callOne)
|
|
219
|
+
},
|
|
220
|
+
|
|
221
|
+
setOverlay: function () {
|
|
222
|
+
if (!this.options.overlay || !this.options.overlay.url_template) return
|
|
223
|
+
const overlay = this.createTileLayer(this.options.overlay)
|
|
224
|
+
try {
|
|
225
|
+
this.addLayer(overlay)
|
|
226
|
+
if (this.overlay) this.removeLayer(this.overlay)
|
|
227
|
+
this.overlay = overlay
|
|
228
|
+
} catch (e) {
|
|
229
|
+
this.removeLayer(overlay)
|
|
230
|
+
console.error(e)
|
|
231
|
+
Alert.error(`${translate('Error in the overlay URL')}: ${overlay._url}`)
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
|
|
235
|
+
updateTileLayers: function () {
|
|
236
|
+
if (this._controls.tilelayersChooser) {
|
|
237
|
+
this._controls.tilelayersChooser.openSwitcher({ edit: true })
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export const LeafletMap = BaseMap.extend({
|
|
243
|
+
includes: [ControlsMixin, ManageTilelayerMixin],
|
|
244
|
+
|
|
245
|
+
// The initialize and the setup method might seem similar, but they
|
|
246
|
+
// serve two different purposes:
|
|
247
|
+
// initialize is for Leaflet internal, when we do "new LeafletMap",
|
|
248
|
+
// while setup is the public API for the LeafletMap to actually
|
|
249
|
+
// render to the DOM.
|
|
250
|
+
initialize: function (umap, element) {
|
|
251
|
+
this._umap = umap
|
|
252
|
+
const options = this._umap.properties
|
|
253
|
+
|
|
254
|
+
BaseMap.prototype.initialize.call(this, element, options)
|
|
255
|
+
|
|
256
|
+
// After calling parent initialize, as we are doing initCenter our-selves
|
|
257
|
+
|
|
258
|
+
this.loader = new Control.Loading()
|
|
259
|
+
this.loader.onAdd(this)
|
|
260
|
+
|
|
261
|
+
if (!this.options.noControl) {
|
|
262
|
+
DomEvent.on(document.body, 'dataloading', (event) =>
|
|
263
|
+
this.fire('dataloading', event.detail)
|
|
264
|
+
)
|
|
265
|
+
DomEvent.on(document.body, 'dataload', (event) =>
|
|
266
|
+
this.fire('dataload', event.detail)
|
|
267
|
+
)
|
|
268
|
+
this.on('click', this.closeInplaceToolbar)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
this.on('baselayerchange', (e) => {
|
|
272
|
+
if (this._controls.miniMap) this._controls.miniMap.onMainMapBaseLayerChange(e)
|
|
273
|
+
})
|
|
274
|
+
},
|
|
275
|
+
|
|
276
|
+
setup: function () {
|
|
277
|
+
this.initControls()
|
|
278
|
+
// Needs locate control and hash to exist
|
|
279
|
+
this.initCenter()
|
|
280
|
+
this.initTileLayers()
|
|
281
|
+
this.renderUI()
|
|
282
|
+
},
|
|
283
|
+
|
|
284
|
+
renderUI: function () {
|
|
285
|
+
setOptions(this, this._umap.properties)
|
|
286
|
+
if (this.options.scrollWheelZoom) {
|
|
287
|
+
this.scrollWheelZoom.enable()
|
|
288
|
+
this.dragging.enable()
|
|
289
|
+
} else {
|
|
290
|
+
this.scrollWheelZoom.disable()
|
|
291
|
+
// In mobile, do not let the user move the map
|
|
292
|
+
// when scrolling the main page and touching the
|
|
293
|
+
// map in an iframe. May be a bit dumb, but let's
|
|
294
|
+
// try like this for now.
|
|
295
|
+
if (L.Browser.mobile) this.dragging.disable()
|
|
296
|
+
}
|
|
297
|
+
// Needs tilelayer to exist for minimap
|
|
298
|
+
this.renderControls()
|
|
299
|
+
this.handleLimitBounds()
|
|
300
|
+
},
|
|
301
|
+
|
|
302
|
+
closeInplaceToolbar: function () {
|
|
303
|
+
const toolbar = this._toolbars[L.Toolbar.Popup._toolbar_class_id]
|
|
304
|
+
if (toolbar) toolbar.remove()
|
|
305
|
+
},
|
|
306
|
+
|
|
307
|
+
latLng: (a, b, c) => {
|
|
308
|
+
// manage geojson case and call original method
|
|
309
|
+
if (!(a instanceof L.LatLng) && a.coordinates) {
|
|
310
|
+
// Guess it's a geojson
|
|
311
|
+
a = [a.coordinates[1], a.coordinates[0]]
|
|
312
|
+
}
|
|
313
|
+
return latLng(a, b, c)
|
|
314
|
+
},
|
|
315
|
+
|
|
316
|
+
_setDefaultCenter: function () {
|
|
317
|
+
this.options.center = this.latLng(this.options.center)
|
|
318
|
+
this.setView(this.options.center, this.options.zoom)
|
|
319
|
+
},
|
|
320
|
+
|
|
321
|
+
initCenter: function () {
|
|
322
|
+
this._setDefaultCenter()
|
|
323
|
+
if (this.options.hash) this.addHash()
|
|
324
|
+
if (this.options.hash && this._hash.parseHash(location.hash)) {
|
|
325
|
+
// FIXME An invalid hash will cause the load to fail
|
|
326
|
+
this._hash.update()
|
|
327
|
+
} else if (this.options.defaultView === 'locate' && !this.options.noControl) {
|
|
328
|
+
this._controls.locate.start()
|
|
329
|
+
} else if (this.options.defaultView === 'data') {
|
|
330
|
+
this._umap.onceDataLoaded(this._umap.fitDataBounds)
|
|
331
|
+
} else if (this.options.defaultView === 'latest') {
|
|
332
|
+
this._umap.onceDataLoaded(() => {
|
|
333
|
+
if (!this._umap.hasData()) return
|
|
334
|
+
const datalayer = this._umap.firstVisibleDatalayer()
|
|
335
|
+
let feature
|
|
336
|
+
if (datalayer) {
|
|
337
|
+
const feature = datalayer.getFeatureByIndex(-1)
|
|
338
|
+
if (feature) {
|
|
339
|
+
feature.zoomTo({ callback: this.options.noControl ? null : feature.view })
|
|
340
|
+
return
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
})
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
|
|
347
|
+
handleLimitBounds: function () {
|
|
348
|
+
const south = Number.parseFloat(this.options.limitBounds.south)
|
|
349
|
+
const west = Number.parseFloat(this.options.limitBounds.west)
|
|
350
|
+
const north = Number.parseFloat(this.options.limitBounds.north)
|
|
351
|
+
const east = Number.parseFloat(this.options.limitBounds.east)
|
|
352
|
+
if (
|
|
353
|
+
!Number.isNaN(south) &&
|
|
354
|
+
!Number.isNaN(west) &&
|
|
355
|
+
!Number.isNaN(north) &&
|
|
356
|
+
!Number.isNaN(east)
|
|
357
|
+
) {
|
|
358
|
+
const bounds = latLngBounds([
|
|
359
|
+
[south, west],
|
|
360
|
+
[north, east],
|
|
361
|
+
])
|
|
362
|
+
this.options.minZoom = this.getBoundsZoom(bounds, false)
|
|
363
|
+
try {
|
|
364
|
+
this.setMaxBounds(bounds)
|
|
365
|
+
} catch (e) {
|
|
366
|
+
// Unusable bounds, like -2 -2 -2 -2?
|
|
367
|
+
console.error('Error limiting bounds', e)
|
|
368
|
+
}
|
|
369
|
+
} else {
|
|
370
|
+
this.options.minZoom = 0
|
|
371
|
+
this.setMaxBounds()
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
|
|
375
|
+
setMaxBounds: function (bounds) {
|
|
376
|
+
// Hack. Remove me when fix is released:
|
|
377
|
+
// https://github.com/Leaflet/Leaflet/pull/4494
|
|
378
|
+
bounds = latLngBounds(bounds)
|
|
379
|
+
|
|
380
|
+
if (!bounds.isValid()) {
|
|
381
|
+
this.options.maxBounds = null
|
|
382
|
+
return this.off('moveend', this._panInsideMaxBounds)
|
|
383
|
+
}
|
|
384
|
+
return BaseMap.prototype.setMaxBounds.call(this, bounds)
|
|
385
|
+
},
|
|
386
|
+
|
|
387
|
+
initEditTools: function () {
|
|
388
|
+
this.editTools = new U.Editable(this._umap)
|
|
389
|
+
},
|
|
390
|
+
})
|
|
@@ -21,30 +21,30 @@ export default function loadPopup(name) {
|
|
|
21
21
|
const Popup = BasePopup.extend({
|
|
22
22
|
initialize: function (feature) {
|
|
23
23
|
this.feature = feature
|
|
24
|
-
|
|
25
|
-
this.format()
|
|
26
|
-
BasePopup.prototype.initialize.call(this, {}, feature)
|
|
27
|
-
this.setContent(this.container)
|
|
24
|
+
BasePopup.prototype.initialize.call(this, {}, feature.ui)
|
|
28
25
|
},
|
|
29
26
|
|
|
30
|
-
|
|
27
|
+
loadContent: async function () {
|
|
28
|
+
const container = DomUtil.create('div', 'umap-popup')
|
|
31
29
|
const name = this.feature.getOption('popupTemplate')
|
|
32
|
-
this.content = loadTemplate(name, this.feature,
|
|
33
|
-
const elements =
|
|
30
|
+
this.content = await loadTemplate(name, this.feature, container)
|
|
31
|
+
const elements = container.querySelectorAll('img,iframe')
|
|
34
32
|
for (const element of elements) {
|
|
35
33
|
this.onElementLoaded(element)
|
|
36
34
|
}
|
|
37
|
-
if (!elements.length &&
|
|
38
|
-
|
|
39
|
-
DomUtil.add('h3', '',
|
|
35
|
+
if (!elements.length && container.textContent.replace('\n', '') === '') {
|
|
36
|
+
container.innerHTML = ''
|
|
37
|
+
DomUtil.add('h3', '', container, this.feature.getDisplayName())
|
|
40
38
|
}
|
|
39
|
+
this.setContent(container)
|
|
41
40
|
},
|
|
42
41
|
|
|
43
42
|
onElementLoaded: function (el) {
|
|
44
43
|
DomEvent.on(el, 'load', () => {
|
|
45
44
|
this._updateLayout()
|
|
46
45
|
this._updatePosition()
|
|
47
|
-
|
|
46
|
+
// Do not call when feature is in cluster.
|
|
47
|
+
if (this._map) this._adjustPan()
|
|
48
48
|
})
|
|
49
49
|
},
|
|
50
50
|
})
|
|
@@ -61,15 +61,15 @@ const Panel = Popup.extend({
|
|
|
61
61
|
zoomAnimation: false,
|
|
62
62
|
},
|
|
63
63
|
|
|
64
|
-
onAdd: function (
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
onAdd: function (leafletMap) {
|
|
65
|
+
leafletMap._umap.panel.setDefaultMode('expanded')
|
|
66
|
+
leafletMap._umap.panel.open({
|
|
67
67
|
content: this._content,
|
|
68
|
-
actions: [Browser.backButton(
|
|
68
|
+
actions: [Browser.backButton(leafletMap._umap)],
|
|
69
69
|
})
|
|
70
70
|
|
|
71
71
|
// fire events as in base class Popup.js:onAdd
|
|
72
|
-
|
|
72
|
+
leafletMap.fire('popupopen', { popup: this })
|
|
73
73
|
if (this._source) {
|
|
74
74
|
this._source.fire('popupopen', { popup: this }, true)
|
|
75
75
|
if (!(this._source instanceof Path)) {
|
|
@@ -78,11 +78,11 @@ const Panel = Popup.extend({
|
|
|
78
78
|
}
|
|
79
79
|
},
|
|
80
80
|
|
|
81
|
-
onRemove: function (
|
|
82
|
-
|
|
81
|
+
onRemove: function (leafletMap) {
|
|
82
|
+
leafletMap._umap.panel.close()
|
|
83
83
|
|
|
84
84
|
// fire events as in base class Popup.js:onRemove
|
|
85
|
-
|
|
85
|
+
leafletMap.fire('popupclose', { popup: this })
|
|
86
86
|
if (this._source) {
|
|
87
87
|
this._source.fire('popupclose', { popup: this }, true)
|
|
88
88
|
if (!(this._source instanceof Path)) {
|
|
@@ -2,8 +2,9 @@ import { DomUtil, DomEvent } from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
|
2
2
|
import { translate, getLocale } from '../i18n.js'
|
|
3
3
|
import * as Utils from '../utils.js'
|
|
4
4
|
import * as Icon from './icon.js'
|
|
5
|
+
import { Request } from '../request.js'
|
|
5
6
|
|
|
6
|
-
export default function loadTemplate(name, feature, container) {
|
|
7
|
+
export default async function loadTemplate(name, feature, container) {
|
|
7
8
|
let klass = PopupTemplate
|
|
8
9
|
switch (name) {
|
|
9
10
|
case 'GeoRSSLink':
|
|
@@ -18,9 +19,12 @@ export default function loadTemplate(name, feature, container) {
|
|
|
18
19
|
case 'OSM':
|
|
19
20
|
klass = OSM
|
|
20
21
|
break
|
|
22
|
+
case 'Wikipedia':
|
|
23
|
+
klass = Wikipedia
|
|
24
|
+
break
|
|
21
25
|
}
|
|
22
26
|
const content = new klass()
|
|
23
|
-
return content.render(feature, container)
|
|
27
|
+
return await content.render(feature, container)
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
class PopupTemplate {
|
|
@@ -35,6 +39,7 @@ class PopupTemplate {
|
|
|
35
39
|
feature.properties.description || '',
|
|
36
40
|
properties
|
|
37
41
|
)
|
|
42
|
+
properties.name = properties.name ?? feature.getDisplayName()
|
|
38
43
|
let content = Utils.greedyTemplate(template, properties)
|
|
39
44
|
content = Utils.toHTML(content, { target: target })
|
|
40
45
|
return Utils.loadTemplate(`<div class="umap-popup-container text">${content}</div>`)
|
|
@@ -59,7 +64,7 @@ class PopupTemplate {
|
|
|
59
64
|
feature: nextFeature.properties.name || translate('next'),
|
|
60
65
|
})
|
|
61
66
|
DomEvent.on(next, 'click', () => {
|
|
62
|
-
nextFeature.zoomTo({ callback: nextFeature.view })
|
|
67
|
+
nextFeature.zoomTo({ callback: (event) => nextFeature.view(event) })
|
|
63
68
|
})
|
|
64
69
|
}
|
|
65
70
|
if (previousFeature) {
|
|
@@ -67,7 +72,7 @@ class PopupTemplate {
|
|
|
67
72
|
feature: previousFeature.properties.name || translate('previous'),
|
|
68
73
|
})
|
|
69
74
|
DomEvent.on(previous, 'click', () => {
|
|
70
|
-
previousFeature.zoomTo({ callback: previousFeature.view })
|
|
75
|
+
previousFeature.zoomTo({ callback: (event) => previousFeature.view(event) })
|
|
71
76
|
})
|
|
72
77
|
}
|
|
73
78
|
DomEvent.on(zoom, 'click', () => feature.zoomTo())
|
|
@@ -75,10 +80,10 @@ class PopupTemplate {
|
|
|
75
80
|
}
|
|
76
81
|
}
|
|
77
82
|
|
|
78
|
-
render(feature, container) {
|
|
83
|
+
async render(feature, container) {
|
|
79
84
|
const title = this.renderTitle(feature)
|
|
80
85
|
if (title) container.appendChild(title)
|
|
81
|
-
const body = this.renderBody(feature)
|
|
86
|
+
const body = await this.renderBody(feature)
|
|
82
87
|
if (body) DomUtil.add('div', 'umap-popup-content', container, body)
|
|
83
88
|
const footer = this.renderFooter(feature)
|
|
84
89
|
if (footer) container.appendChild(footer)
|
|
@@ -110,11 +115,13 @@ class Table extends TitleMixin(PopupTemplate) {
|
|
|
110
115
|
)
|
|
111
116
|
}
|
|
112
117
|
|
|
113
|
-
renderBody(feature) {
|
|
118
|
+
async renderBody(feature) {
|
|
114
119
|
const table = document.createElement('table')
|
|
115
120
|
|
|
116
121
|
for (const key in feature.properties) {
|
|
117
|
-
if (typeof feature.properties[key] === 'object' || key
|
|
122
|
+
if (typeof feature.properties[key] === 'object' || U.LABEL_KEYS.includes(key)) {
|
|
123
|
+
continue
|
|
124
|
+
}
|
|
118
125
|
table.appendChild(this.makeRow(feature, key))
|
|
119
126
|
}
|
|
120
127
|
return table
|
|
@@ -122,7 +129,7 @@ class Table extends TitleMixin(PopupTemplate) {
|
|
|
122
129
|
}
|
|
123
130
|
|
|
124
131
|
class GeoRSSImage extends TitleMixin(PopupTemplate) {
|
|
125
|
-
renderBody(feature) {
|
|
132
|
+
async renderBody(feature) {
|
|
126
133
|
const body = DomUtil.create('a')
|
|
127
134
|
body.href = feature.properties.link
|
|
128
135
|
body.target = '_blank'
|
|
@@ -139,7 +146,7 @@ class GeoRSSImage extends TitleMixin(PopupTemplate) {
|
|
|
139
146
|
}
|
|
140
147
|
|
|
141
148
|
class GeoRSSLink extends PopupTemplate {
|
|
142
|
-
renderBody(feature) {
|
|
149
|
+
async renderBody(feature) {
|
|
143
150
|
if (feature.properties.link) {
|
|
144
151
|
return Utils.loadTemplate(
|
|
145
152
|
`<a href="${feature.properties.link}" target="_blank"><h3>${feature.getDisplayName()}</h3></a>`
|
|
@@ -148,7 +155,20 @@ class GeoRSSLink extends PopupTemplate {
|
|
|
148
155
|
}
|
|
149
156
|
}
|
|
150
157
|
|
|
151
|
-
class OSM extends
|
|
158
|
+
class OSM extends PopupTemplate {
|
|
159
|
+
renderTitle(feature) {
|
|
160
|
+
const title = DomUtil.add('h3', 'popup-title')
|
|
161
|
+
const color = feature.getPreviewColor()
|
|
162
|
+
title.style.backgroundColor = color
|
|
163
|
+
const iconUrl = feature.getDynamicOption('iconUrl')
|
|
164
|
+
const icon = Icon.makeElement(iconUrl, title)
|
|
165
|
+
DomUtil.addClass(icon, 'icon')
|
|
166
|
+
Icon.setContrast(icon, title, iconUrl, color)
|
|
167
|
+
if (DomUtil.contrastedColor(title, color)) title.style.color = 'white'
|
|
168
|
+
DomUtil.add('span', '', title, this.getName(feature))
|
|
169
|
+
return title
|
|
170
|
+
}
|
|
171
|
+
|
|
152
172
|
getName(feature) {
|
|
153
173
|
const props = feature.properties
|
|
154
174
|
const locale = getLocale()
|
|
@@ -156,18 +176,10 @@ class OSM extends TitleMixin(PopupTemplate) {
|
|
|
156
176
|
return props.name
|
|
157
177
|
}
|
|
158
178
|
|
|
159
|
-
renderBody(feature) {
|
|
179
|
+
async renderBody(feature) {
|
|
160
180
|
const props = feature.properties
|
|
161
181
|
const body = document.createElement('div')
|
|
162
|
-
const
|
|
163
|
-
const color = feature.getPreviewColor()
|
|
164
|
-
title.style.backgroundColor = color
|
|
165
|
-
const iconUrl = feature.getDynamicOption('iconUrl')
|
|
166
|
-
const icon = Icon.makeElement(iconUrl, title)
|
|
167
|
-
DomUtil.addClass(icon, 'icon')
|
|
168
|
-
Icon.setContrast(icon, title, iconUrl, color)
|
|
169
|
-
if (DomUtil.contrastedColor(title, color)) title.style.color = 'white'
|
|
170
|
-
DomUtil.add('span', '', title, this.getName(feature))
|
|
182
|
+
const locale = getLocale()
|
|
171
183
|
const street = props['addr:street']
|
|
172
184
|
if (street) {
|
|
173
185
|
const row = DomUtil.add('address', 'address', body)
|
|
@@ -204,6 +216,21 @@ class OSM extends TitleMixin(PopupTemplate) {
|
|
|
204
216
|
Utils.loadTemplate(`<div><a href="mailto:${email}">${email}</a></div>`)
|
|
205
217
|
)
|
|
206
218
|
}
|
|
219
|
+
if (props.panoramax) {
|
|
220
|
+
body.appendChild(
|
|
221
|
+
Utils.loadTemplate(
|
|
222
|
+
`<div><img src="https://api.panoramax.xyz/api/pictures/${props.panoramax}/sd.jpg" /></div>`
|
|
223
|
+
)
|
|
224
|
+
)
|
|
225
|
+
}
|
|
226
|
+
const wikipedia = props[`wikipedia:${locale}`] || props.wikipedia
|
|
227
|
+
if (wikipedia) {
|
|
228
|
+
body.appendChild(
|
|
229
|
+
Utils.loadTemplate(
|
|
230
|
+
`<div class="wikipedia-link"><a href="https://wikipedia.org/wiki/${wikipedia}" target="_blank">${translate('Wikipedia')}</a></div>`
|
|
231
|
+
)
|
|
232
|
+
)
|
|
233
|
+
}
|
|
207
234
|
const id = props['@id'] || props.id
|
|
208
235
|
if (id) {
|
|
209
236
|
body.appendChild(
|
|
@@ -215,3 +242,43 @@ class OSM extends TitleMixin(PopupTemplate) {
|
|
|
215
242
|
return body
|
|
216
243
|
}
|
|
217
244
|
}
|
|
245
|
+
|
|
246
|
+
const _WIKIPEDIA_CACHE = {}
|
|
247
|
+
|
|
248
|
+
class Wikipedia extends PopupTemplate {
|
|
249
|
+
async callWikipedia(wikipedia) {
|
|
250
|
+
if (wikipedia && _WIKIPEDIA_CACHE[wikipedia]) return _WIKIPEDIA_CACHE[wikipedia]
|
|
251
|
+
// Wikipedia value should be in form of "{locale}:{title}", according to https://wiki.openstreetmap.org/wiki/Key:wikipedia
|
|
252
|
+
const [locale, page] = wikipedia.split(':')
|
|
253
|
+
const url = `https://${locale}.wikipedia.org/w/api.php?action=query&format=json&origin=*&pithumbsize=500&prop=extracts|pageimages&titles=${page}`
|
|
254
|
+
const request = new Request()
|
|
255
|
+
const response = await request.get(url)
|
|
256
|
+
if (response?.ok) {
|
|
257
|
+
const data = await response.json()
|
|
258
|
+
_WIKIPEDIA_CACHE[wikipedia] = data
|
|
259
|
+
return data
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
async renderBody(feature) {
|
|
264
|
+
const body = document.createElement('div')
|
|
265
|
+
const wikipedia = feature.properties.wikipedia
|
|
266
|
+
if (!wikipedia) return ''
|
|
267
|
+
const data = await this.callWikipedia(wikipedia)
|
|
268
|
+
if (data) {
|
|
269
|
+
const page = Object.values(data.query.pages)[0]
|
|
270
|
+
const title = page.title || feature.getDisplayName()
|
|
271
|
+
const extract = page.extract || ''
|
|
272
|
+
const thumbnail = page.thumbnail?.source
|
|
273
|
+
const [content, { image }] = Utils.loadTemplateWithRefs(
|
|
274
|
+
`<div><h3>${Utils.escapeHTML(title)}</h3><img data-ref="image" hidden src="" />${Utils.escapeHTML(extract)}</div>`
|
|
275
|
+
)
|
|
276
|
+
if (thumbnail) {
|
|
277
|
+
image.src = thumbnail
|
|
278
|
+
image.hidden = false
|
|
279
|
+
}
|
|
280
|
+
body.appendChild(content)
|
|
281
|
+
}
|
|
282
|
+
return body
|
|
283
|
+
}
|
|
284
|
+
}
|