umap-project 2.5.0__py3-none-any.whl → 2.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.
Potentially problematic release.
This version of umap-project might be problematic. Click here for more details.
- umap/__init__.py +1 -1
- umap/admin.py +6 -1
- umap/context_processors.py +2 -1
- umap/decorators.py +13 -2
- umap/forms.py +26 -2
- umap/locale/br/LC_MESSAGES/django.mo +0 -0
- umap/locale/br/LC_MESSAGES/django.po +252 -146
- umap/locale/ca/LC_MESSAGES/django.mo +0 -0
- umap/locale/ca/LC_MESSAGES/django.po +274 -162
- umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- umap/locale/cs_CZ/LC_MESSAGES/django.po +261 -150
- umap/locale/de/LC_MESSAGES/django.mo +0 -0
- umap/locale/de/LC_MESSAGES/django.po +299 -187
- umap/locale/el/LC_MESSAGES/django.mo +0 -0
- umap/locale/el/LC_MESSAGES/django.po +215 -159
- umap/locale/en/LC_MESSAGES/django.po +211 -155
- umap/locale/es/LC_MESSAGES/django.mo +0 -0
- umap/locale/es/LC_MESSAGES/django.po +255 -144
- umap/locale/eu/LC_MESSAGES/django.mo +0 -0
- umap/locale/eu/LC_MESSAGES/django.po +254 -198
- umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
- umap/locale/fa_IR/LC_MESSAGES/django.po +347 -235
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +216 -160
- umap/locale/hu/LC_MESSAGES/django.mo +0 -0
- umap/locale/hu/LC_MESSAGES/django.po +215 -159
- umap/locale/it/LC_MESSAGES/django.mo +0 -0
- umap/locale/it/LC_MESSAGES/django.po +252 -146
- umap/locale/ms/LC_MESSAGES/django.mo +0 -0
- umap/locale/ms/LC_MESSAGES/django.po +252 -146
- umap/locale/pl/LC_MESSAGES/django.mo +0 -0
- umap/locale/pl/LC_MESSAGES/django.po +254 -148
- umap/locale/pt/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt/LC_MESSAGES/django.po +215 -159
- umap/locale/sv/LC_MESSAGES/django.mo +0 -0
- umap/locale/sv/LC_MESSAGES/django.po +254 -143
- umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
- umap/locale/th_TH/LC_MESSAGES/django.po +125 -70
- umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
- umap/locale/zh_TW/LC_MESSAGES/django.po +256 -145
- umap/migrations/0022_add_team.py +94 -0
- umap/models.py +45 -10
- umap/settings/__init__.py +2 -0
- umap/settings/base.py +9 -2
- umap/static/umap/base.css +32 -41
- umap/static/umap/content.css +19 -25
- umap/static/umap/css/icon.css +63 -37
- umap/static/umap/css/importers.css +1 -1
- umap/static/umap/css/slideshow.css +7 -5
- umap/static/umap/css/tableeditor.css +4 -3
- umap/static/umap/img/16-white.svg +1 -4
- umap/static/umap/img/16.svg +2 -6
- umap/static/umap/img/24-white.svg +4 -4
- umap/static/umap/img/24.svg +6 -6
- umap/static/umap/img/source/16-white.svg +2 -5
- umap/static/umap/img/source/16.svg +3 -7
- umap/static/umap/img/source/24-white.svg +7 -14
- umap/static/umap/img/source/24.svg +10 -17
- umap/static/umap/js/components/alerts/alert.css +20 -8
- umap/static/umap/js/modules/autocomplete.js +8 -12
- umap/static/umap/js/modules/browser.js +4 -3
- umap/static/umap/js/modules/caption.js +9 -11
- umap/static/umap/js/modules/data/features.js +993 -0
- umap/static/umap/js/modules/data/layer.js +1210 -0
- umap/static/umap/js/modules/formatter.js +12 -3
- umap/static/umap/js/modules/global.js +21 -5
- umap/static/umap/js/modules/importers/overpass.js +22 -8
- umap/static/umap/js/modules/permissions.js +280 -0
- umap/static/umap/js/{umap.icon.js → modules/rendering/icon.js} +77 -56
- umap/static/umap/js/modules/rendering/layers/base.js +105 -0
- umap/static/umap/js/modules/rendering/layers/classified.js +484 -0
- umap/static/umap/js/modules/rendering/layers/cluster.js +103 -0
- umap/static/umap/js/modules/rendering/layers/heat.js +182 -0
- umap/static/umap/js/modules/rendering/popup.js +99 -0
- umap/static/umap/js/modules/rendering/template.js +217 -0
- umap/static/umap/js/modules/rendering/ui.js +610 -0
- umap/static/umap/js/modules/rules.js +16 -3
- umap/static/umap/js/modules/schema.js +25 -1
- umap/static/umap/js/modules/share.js +66 -45
- umap/static/umap/js/modules/sync/updaters.js +9 -10
- umap/static/umap/js/modules/tableeditor.js +7 -7
- umap/static/umap/js/modules/ui/dialog.js +8 -4
- umap/static/umap/js/modules/utils.js +22 -13
- umap/static/umap/js/umap.controls.js +80 -146
- umap/static/umap/js/umap.core.js +9 -9
- umap/static/umap/js/umap.forms.js +41 -17
- umap/static/umap/js/umap.js +72 -65
- umap/static/umap/locale/am_ET.js +8 -2
- umap/static/umap/locale/am_ET.json +8 -2
- umap/static/umap/locale/ar.js +8 -2
- umap/static/umap/locale/ar.json +8 -2
- umap/static/umap/locale/ast.js +8 -2
- umap/static/umap/locale/ast.json +8 -2
- umap/static/umap/locale/bg.js +8 -2
- umap/static/umap/locale/bg.json +8 -2
- umap/static/umap/locale/br.js +42 -36
- umap/static/umap/locale/br.json +42 -36
- umap/static/umap/locale/ca.js +67 -61
- umap/static/umap/locale/ca.json +67 -61
- umap/static/umap/locale/cs_CZ.js +8 -2
- umap/static/umap/locale/cs_CZ.json +8 -2
- umap/static/umap/locale/da.js +8 -2
- umap/static/umap/locale/da.json +8 -2
- umap/static/umap/locale/de.js +143 -137
- umap/static/umap/locale/de.json +143 -137
- umap/static/umap/locale/el.js +54 -48
- umap/static/umap/locale/el.json +54 -48
- umap/static/umap/locale/en.js +10 -2
- umap/static/umap/locale/en.json +10 -2
- umap/static/umap/locale/en_US.json +8 -2
- umap/static/umap/locale/es.js +8 -2
- umap/static/umap/locale/es.json +8 -2
- umap/static/umap/locale/et.js +8 -2
- umap/static/umap/locale/et.json +8 -2
- umap/static/umap/locale/eu.js +346 -338
- umap/static/umap/locale/eu.json +346 -338
- umap/static/umap/locale/fa_IR.js +415 -407
- umap/static/umap/locale/fa_IR.json +415 -407
- umap/static/umap/locale/fi.js +8 -2
- umap/static/umap/locale/fi.json +8 -2
- umap/static/umap/locale/fr.js +11 -3
- umap/static/umap/locale/fr.json +11 -3
- umap/static/umap/locale/gl.js +8 -2
- umap/static/umap/locale/gl.json +8 -2
- umap/static/umap/locale/he.js +8 -2
- umap/static/umap/locale/he.json +8 -2
- umap/static/umap/locale/hr.js +8 -2
- umap/static/umap/locale/hr.json +8 -2
- umap/static/umap/locale/hu.js +31 -23
- umap/static/umap/locale/hu.json +31 -23
- umap/static/umap/locale/id.js +8 -2
- umap/static/umap/locale/id.json +8 -2
- umap/static/umap/locale/is.js +8 -2
- umap/static/umap/locale/is.json +8 -2
- umap/static/umap/locale/it.js +8 -2
- umap/static/umap/locale/it.json +8 -2
- umap/static/umap/locale/ja.js +8 -2
- umap/static/umap/locale/ja.json +8 -2
- umap/static/umap/locale/ko.js +8 -2
- umap/static/umap/locale/ko.json +8 -2
- umap/static/umap/locale/lt.js +8 -2
- umap/static/umap/locale/lt.json +8 -2
- umap/static/umap/locale/ms.js +8 -2
- umap/static/umap/locale/ms.json +8 -2
- umap/static/umap/locale/nl.js +8 -2
- umap/static/umap/locale/nl.json +8 -2
- umap/static/umap/locale/no.js +8 -2
- umap/static/umap/locale/no.json +8 -2
- umap/static/umap/locale/pl.js +54 -48
- umap/static/umap/locale/pl.json +54 -48
- umap/static/umap/locale/pl_PL.json +8 -2
- umap/static/umap/locale/pt.js +24 -18
- umap/static/umap/locale/pt.json +24 -18
- umap/static/umap/locale/pt_BR.js +8 -2
- umap/static/umap/locale/pt_BR.json +8 -2
- umap/static/umap/locale/pt_PT.js +214 -208
- umap/static/umap/locale/pt_PT.json +214 -208
- umap/static/umap/locale/ro.js +8 -2
- umap/static/umap/locale/ro.json +8 -2
- umap/static/umap/locale/ru.js +8 -2
- umap/static/umap/locale/ru.json +8 -2
- umap/static/umap/locale/sk_SK.js +8 -2
- umap/static/umap/locale/sk_SK.json +8 -2
- umap/static/umap/locale/sl.js +8 -2
- umap/static/umap/locale/sl.json +8 -2
- umap/static/umap/locale/sr.js +8 -2
- umap/static/umap/locale/sr.json +8 -2
- umap/static/umap/locale/sv.js +8 -2
- umap/static/umap/locale/sv.json +8 -2
- umap/static/umap/locale/th_TH.js +33 -27
- umap/static/umap/locale/th_TH.json +33 -27
- umap/static/umap/locale/tr.js +8 -2
- umap/static/umap/locale/tr.json +8 -2
- umap/static/umap/locale/uk_UA.js +8 -2
- umap/static/umap/locale/uk_UA.json +8 -2
- umap/static/umap/locale/vi.js +8 -2
- umap/static/umap/locale/vi.json +8 -2
- umap/static/umap/locale/vi_VN.json +8 -2
- umap/static/umap/locale/zh.js +8 -2
- umap/static/umap/locale/zh.json +8 -2
- umap/static/umap/locale/zh_CN.json +8 -2
- umap/static/umap/locale/zh_TW.Big5.json +8 -2
- umap/static/umap/locale/zh_TW.js +102 -96
- umap/static/umap/locale/zh_TW.json +102 -96
- umap/static/umap/map.css +111 -108
- umap/static/umap/nav.css +19 -10
- umap/static/umap/unittests/utils.js +230 -107
- umap/static/umap/vars.css +1 -0
- umap/static/umap/vendors/csv2geojson/csv2geojson.js +62 -40
- umap/static/umap/vendors/editable/Leaflet.Editable.js +2079 -1937
- umap/storage.py +4 -3
- umap/templates/404.html +5 -1
- umap/templates/500.html +3 -1
- umap/templates/auth/user_detail.html +8 -2
- umap/templates/auth/user_form.html +19 -10
- umap/templates/auth/user_stars.html +8 -2
- umap/templates/base.html +1 -0
- umap/templates/registration/login.html +18 -3
- umap/templates/umap/about.html +1 -0
- umap/templates/umap/about_summary.html +22 -7
- umap/templates/umap/components/alerts/alert.html +42 -21
- umap/templates/umap/content.html +2 -0
- umap/templates/umap/content_footer.html +7 -3
- umap/templates/umap/css.html +1 -0
- umap/templates/umap/dashboard_menu.html +15 -0
- umap/templates/umap/home.html +14 -4
- umap/templates/umap/js.html +4 -9
- umap/templates/umap/login_popup_end.html +10 -4
- umap/templates/umap/map_detail.html +8 -2
- umap/templates/umap/map_fragment.html +3 -1
- umap/templates/umap/map_init.html +2 -1
- umap/templates/umap/map_list.html +6 -3
- umap/templates/umap/map_table.html +36 -12
- umap/templates/umap/messages.html +0 -1
- umap/templates/umap/navigation.html +2 -1
- umap/templates/umap/password_change.html +5 -1
- umap/templates/umap/password_change_done.html +8 -2
- umap/templates/umap/search.html +8 -2
- umap/templates/umap/search_bar.html +1 -0
- umap/templates/umap/team_confirm_delete.html +19 -0
- umap/templates/umap/team_detail.html +27 -0
- umap/templates/umap/team_form.html +60 -0
- umap/templates/umap/user_dashboard.html +7 -9
- umap/templates/umap/user_teams.html +51 -0
- umap/tests/base.py +8 -1
- umap/tests/conftest.py +6 -0
- umap/tests/fixtures/test_circles_layer.geojson +219 -0
- umap/tests/fixtures/test_upload_georss.xml +20 -0
- umap/tests/integration/conftest.py +18 -4
- umap/tests/integration/helpers.py +12 -0
- umap/tests/integration/test_anonymous_owned_map.py +23 -0
- umap/tests/integration/test_basics.py +29 -0
- umap/tests/integration/test_browser.py +20 -0
- umap/tests/integration/test_caption.py +20 -0
- umap/tests/integration/test_circles_layer.py +69 -0
- umap/tests/integration/test_conditional_rules.py +102 -17
- umap/tests/integration/test_draw_polygon.py +138 -13
- umap/tests/integration/test_draw_polyline.py +8 -18
- umap/tests/integration/test_edit_datalayer.py +3 -3
- umap/tests/integration/test_import.py +124 -5
- umap/tests/integration/test_owned_map.py +21 -13
- umap/tests/integration/test_querystring.py +7 -0
- umap/tests/integration/test_team.py +47 -0
- umap/tests/integration/test_tilelayer.py +19 -2
- umap/tests/integration/test_view_marker.py +28 -1
- umap/tests/integration/test_websocket_sync.py +5 -5
- umap/tests/test_datalayer.py +32 -7
- umap/tests/test_datalayer_views.py +1 -1
- umap/tests/test_map.py +30 -4
- umap/tests/test_map_views.py +2 -2
- umap/tests/test_statics.py +40 -0
- umap/tests/test_team_views.py +131 -0
- umap/tests/test_views.py +15 -1
- umap/urls.py +23 -13
- umap/views.py +116 -10
- {umap_project-2.5.0.dist-info → umap_project-2.6.0.dist-info}/METADATA +14 -14
- {umap_project-2.5.0.dist-info → umap_project-2.6.0.dist-info}/RECORD +260 -253
- umap/static/umap/js/umap.datalayer.permissions.js +0 -70
- umap/static/umap/js/umap.features.js +0 -1290
- umap/static/umap/js/umap.layer.js +0 -1837
- umap/static/umap/js/umap.permissions.js +0 -208
- umap/static/umap/js/umap.popup.js +0 -341
- umap/static/umap/test/TableEditor.js +0 -104
- umap/static/umap/vendors/leaflet/leaflet-src.js +0 -14512
- umap/static/umap/vendors/leaflet/leaflet-src.js.map +0 -1
- umap/static/umap/vendors/leaflet/leaflet.js +0 -6
- umap/static/umap/vendors/leaflet/leaflet.js.map +0 -1
- umap/static/umap/vendors/markercluster/WhereAreTheJavascriptFiles.txt +0 -5
- umap/static/umap/vendors/markercluster/leaflet.markercluster-src.js +0 -2718
- umap/static/umap/vendors/markercluster/leaflet.markercluster-src.js.map +0 -1
- umap/static/umap/vendors/toolbar/leaflet.toolbar-src.css +0 -117
- umap/static/umap/vendors/toolbar/leaflet.toolbar-src.js +0 -365
- umap/tests/integration/test_statics.py +0 -47
- {umap_project-2.5.0.dist-info → umap_project-2.6.0.dist-info}/WHEEL +0 -0
- {umap_project-2.5.0.dist-info → umap_project-2.6.0.dist-info}/entry_points.txt +0 -0
- {umap_project-2.5.0.dist-info → umap_project-2.6.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
// Uses global L.HeatLayer, not exposed as ESM
|
|
2
|
+
import {
|
|
3
|
+
Marker,
|
|
4
|
+
LatLng,
|
|
5
|
+
latLngBounds,
|
|
6
|
+
Bounds,
|
|
7
|
+
point,
|
|
8
|
+
} from '../../../../vendors/leaflet/leaflet-src.esm.js'
|
|
9
|
+
import { LayerMixin } from './base.js'
|
|
10
|
+
import * as Utils from '../../utils.js'
|
|
11
|
+
import { translate } from '../../i18n.js'
|
|
12
|
+
|
|
13
|
+
export const Heat = L.HeatLayer.extend({
|
|
14
|
+
statics: {
|
|
15
|
+
NAME: translate('Heatmap'),
|
|
16
|
+
TYPE: 'Heat',
|
|
17
|
+
},
|
|
18
|
+
includes: [LayerMixin],
|
|
19
|
+
browsable: false,
|
|
20
|
+
|
|
21
|
+
initialize: function (datalayer) {
|
|
22
|
+
this.datalayer = datalayer
|
|
23
|
+
L.HeatLayer.prototype.initialize.call(this, [], this.datalayer.options.heat)
|
|
24
|
+
LayerMixin.onInit.call(this, this.datalayer.map)
|
|
25
|
+
if (!Utils.isObject(this.datalayer.options.heat)) {
|
|
26
|
+
this.datalayer.options.heat = {}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
addLayer: function (layer) {
|
|
31
|
+
if (layer instanceof Marker) {
|
|
32
|
+
let latlng = layer.getLatLng()
|
|
33
|
+
let alt
|
|
34
|
+
if (this.datalayer.options.heat?.intensityProperty) {
|
|
35
|
+
alt = Number.parseFloat(
|
|
36
|
+
layer.feature.properties[this.datalayer.options.heat.intensityProperty || 0]
|
|
37
|
+
)
|
|
38
|
+
latlng = new LatLng(latlng.lat, latlng.lng, alt)
|
|
39
|
+
}
|
|
40
|
+
this.addLatLng(latlng)
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
onAdd: function (map) {
|
|
45
|
+
LayerMixin.onAdd.call(this, map)
|
|
46
|
+
return L.HeatLayer.prototype.onAdd.call(this, map)
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
onRemove: function (map) {
|
|
50
|
+
LayerMixin.onRemove.call(this, map)
|
|
51
|
+
return L.HeatLayer.prototype.onRemove.call(this, map)
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
clearLayers: function () {
|
|
55
|
+
this.setLatLngs([])
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
getFeatures: () => ({}),
|
|
59
|
+
|
|
60
|
+
getBounds: function () {
|
|
61
|
+
return latLngBounds(this._latlngs)
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
getEditableOptions: () => [
|
|
65
|
+
[
|
|
66
|
+
'options.heat.radius',
|
|
67
|
+
{
|
|
68
|
+
handler: 'Range',
|
|
69
|
+
min: 10,
|
|
70
|
+
max: 100,
|
|
71
|
+
step: 5,
|
|
72
|
+
label: translate('Heatmap radius'),
|
|
73
|
+
helpText: translate('Override heatmap radius (default 25)'),
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
[
|
|
77
|
+
'options.heat.intensityProperty',
|
|
78
|
+
{
|
|
79
|
+
handler: 'BlurInput',
|
|
80
|
+
placeholder: translate('Heatmap intensity property'),
|
|
81
|
+
helpText: translate('Optional intensity property for heatmap'),
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
],
|
|
85
|
+
|
|
86
|
+
onEdit: function (field, builder) {
|
|
87
|
+
if (field === 'options.heat.intensityProperty') {
|
|
88
|
+
this.datalayer.resetLayer(true) // We need to repopulate the latlngs
|
|
89
|
+
return
|
|
90
|
+
}
|
|
91
|
+
if (field === 'options.heat.radius') {
|
|
92
|
+
this.options.radius = this.datalayer.options.heat.radius
|
|
93
|
+
}
|
|
94
|
+
this._updateOptions()
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
redraw: function () {
|
|
98
|
+
// setlalngs call _redraw through setAnimFrame, thus async, so this
|
|
99
|
+
// can ends with race condition if we remove the layer very faslty after.
|
|
100
|
+
// TODO: PR in upstream Leaflet.heat
|
|
101
|
+
if (!this._map) return
|
|
102
|
+
L.HeatLayer.prototype.redraw.call(this)
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
_redraw: function () {
|
|
106
|
+
// Import patch from https://github.com/Leaflet/Leaflet.heat/pull/78
|
|
107
|
+
// Remove me when this get merged and released.
|
|
108
|
+
if (!this._map) {
|
|
109
|
+
return
|
|
110
|
+
}
|
|
111
|
+
const data = []
|
|
112
|
+
const r = this._heat._r
|
|
113
|
+
const size = this._map.getSize()
|
|
114
|
+
const bounds = new Bounds(point([-r, -r]), size.add([r, r]))
|
|
115
|
+
const cellSize = r / 2
|
|
116
|
+
const grid = []
|
|
117
|
+
const panePos = this._map._getMapPanePos()
|
|
118
|
+
const offsetX = panePos.x % cellSize
|
|
119
|
+
const offsetY = panePos.y % cellSize
|
|
120
|
+
let i
|
|
121
|
+
let len
|
|
122
|
+
let p
|
|
123
|
+
let cell
|
|
124
|
+
let x
|
|
125
|
+
let y
|
|
126
|
+
let j
|
|
127
|
+
let len2
|
|
128
|
+
|
|
129
|
+
this._max = 1
|
|
130
|
+
|
|
131
|
+
for (i = 0, len = this._latlngs.length; i < len; i++) {
|
|
132
|
+
p = this._map.latLngToContainerPoint(this._latlngs[i])
|
|
133
|
+
x = Math.floor((p.x - offsetX) / cellSize) + 2
|
|
134
|
+
y = Math.floor((p.y - offsetY) / cellSize) + 2
|
|
135
|
+
|
|
136
|
+
const alt =
|
|
137
|
+
this._latlngs[i].alt !== undefined
|
|
138
|
+
? this._latlngs[i].alt
|
|
139
|
+
: this._latlngs[i][2] !== undefined
|
|
140
|
+
? +this._latlngs[i][2]
|
|
141
|
+
: 1
|
|
142
|
+
|
|
143
|
+
grid[y] = grid[y] || []
|
|
144
|
+
cell = grid[y][x]
|
|
145
|
+
|
|
146
|
+
if (!cell) {
|
|
147
|
+
cell = grid[y][x] = [p.x, p.y, alt]
|
|
148
|
+
cell.p = p
|
|
149
|
+
} else {
|
|
150
|
+
cell[0] = (cell[0] * cell[2] + p.x * alt) / (cell[2] + alt) // x
|
|
151
|
+
cell[1] = (cell[1] * cell[2] + p.y * alt) / (cell[2] + alt) // y
|
|
152
|
+
cell[2] += alt // cumulated intensity value
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Set the max for the current zoom level
|
|
156
|
+
if (cell[2] > this._max) {
|
|
157
|
+
this._max = cell[2]
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
this._heat.max(this._max)
|
|
162
|
+
|
|
163
|
+
for (i = 0, len = grid.length; i < len; i++) {
|
|
164
|
+
if (grid[i]) {
|
|
165
|
+
for (j = 0, len2 = grid[i].length; j < len2; j++) {
|
|
166
|
+
cell = grid[i][j]
|
|
167
|
+
if (cell && bounds.contains(cell.p)) {
|
|
168
|
+
data.push([
|
|
169
|
+
Math.round(cell[0]),
|
|
170
|
+
Math.round(cell[1]),
|
|
171
|
+
Math.min(cell[2], this._max),
|
|
172
|
+
])
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
this._heat.data(data).draw(this.options.minOpacity)
|
|
179
|
+
|
|
180
|
+
this._frame = null
|
|
181
|
+
},
|
|
182
|
+
})
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DomEvent,
|
|
3
|
+
DomUtil,
|
|
4
|
+
Path,
|
|
5
|
+
Popup as BasePopup,
|
|
6
|
+
} from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
7
|
+
import loadTemplate from './template.js'
|
|
8
|
+
import Browser from '../browser.js'
|
|
9
|
+
|
|
10
|
+
export default function loadPopup(name) {
|
|
11
|
+
switch (name) {
|
|
12
|
+
case 'Large':
|
|
13
|
+
return PopupLarge
|
|
14
|
+
case 'Panel':
|
|
15
|
+
return Panel
|
|
16
|
+
default:
|
|
17
|
+
return Popup
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const Popup = BasePopup.extend({
|
|
22
|
+
initialize: function (feature) {
|
|
23
|
+
this.feature = feature
|
|
24
|
+
this.container = DomUtil.create('div', 'umap-popup')
|
|
25
|
+
this.format()
|
|
26
|
+
BasePopup.prototype.initialize.call(this, {}, feature)
|
|
27
|
+
this.setContent(this.container)
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
format: function () {
|
|
31
|
+
const name = this.feature.getOption('popupTemplate')
|
|
32
|
+
this.content = loadTemplate(name, this.feature, this.container)
|
|
33
|
+
const elements = this.container.querySelectorAll('img,iframe')
|
|
34
|
+
for (const element of elements) {
|
|
35
|
+
this.onElementLoaded(element)
|
|
36
|
+
}
|
|
37
|
+
if (!elements.length && this.container.textContent.replace('\n', '') === '') {
|
|
38
|
+
this.container.innerHTML = ''
|
|
39
|
+
DomUtil.add('h3', '', this.container, this.feature.getDisplayName())
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
onElementLoaded: function (el) {
|
|
44
|
+
DomEvent.on(el, 'load', () => {
|
|
45
|
+
this._updateLayout()
|
|
46
|
+
this._updatePosition()
|
|
47
|
+
this._adjustPan()
|
|
48
|
+
})
|
|
49
|
+
},
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
const PopupLarge = Popup.extend({
|
|
53
|
+
options: {
|
|
54
|
+
maxWidth: 500,
|
|
55
|
+
className: 'umap-popup-large',
|
|
56
|
+
},
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
const Panel = Popup.extend({
|
|
60
|
+
options: {
|
|
61
|
+
zoomAnimation: false,
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
onAdd: function (map) {
|
|
65
|
+
map.panel.setDefaultMode('expanded')
|
|
66
|
+
map.panel.open({
|
|
67
|
+
content: this._content,
|
|
68
|
+
actions: [Browser.backButton(map)],
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
// fire events as in base class Popup.js:onAdd
|
|
72
|
+
map.fire('popupopen', { popup: this })
|
|
73
|
+
if (this._source) {
|
|
74
|
+
this._source.fire('popupopen', { popup: this }, true)
|
|
75
|
+
if (!(this._source instanceof Path)) {
|
|
76
|
+
this._source.on('preclick', DomEvent.stopPropagation)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
onRemove: function (map) {
|
|
82
|
+
map.panel.close()
|
|
83
|
+
|
|
84
|
+
// fire events as in base class Popup.js:onRemove
|
|
85
|
+
map.fire('popupclose', { popup: this })
|
|
86
|
+
if (this._source) {
|
|
87
|
+
this._source.fire('popupclose', { popup: this }, true)
|
|
88
|
+
if (!(this._source instanceof Path)) {
|
|
89
|
+
this._source.off('preclick', DomEvent.stopPropagation)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
update: () => {},
|
|
95
|
+
_updateLayout: () => {},
|
|
96
|
+
_updatePosition: () => {},
|
|
97
|
+
_adjustPan: () => {},
|
|
98
|
+
_animateZoom: () => {},
|
|
99
|
+
})
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { DomUtil, DomEvent } from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
2
|
+
import { translate, getLocale } from '../i18n.js'
|
|
3
|
+
import * as Utils from '../utils.js'
|
|
4
|
+
import * as Icon from './icon.js'
|
|
5
|
+
|
|
6
|
+
export default function loadTemplate(name, feature, container) {
|
|
7
|
+
let klass = PopupTemplate
|
|
8
|
+
switch (name) {
|
|
9
|
+
case 'GeoRSSLink':
|
|
10
|
+
klass = GeoRSSLink
|
|
11
|
+
break
|
|
12
|
+
case 'GeoRSSImage':
|
|
13
|
+
klass = GeoRSSImage
|
|
14
|
+
break
|
|
15
|
+
case 'Table':
|
|
16
|
+
klass = Table
|
|
17
|
+
break
|
|
18
|
+
case 'OSM':
|
|
19
|
+
klass = OSM
|
|
20
|
+
break
|
|
21
|
+
}
|
|
22
|
+
const content = new klass()
|
|
23
|
+
return content.render(feature, container)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
class PopupTemplate {
|
|
27
|
+
renderTitle(feature) {}
|
|
28
|
+
|
|
29
|
+
renderBody(feature) {
|
|
30
|
+
const template = feature.getOption('popupContentTemplate')
|
|
31
|
+
const target = feature.getOption('outlinkTarget')
|
|
32
|
+
const properties = feature.extendedProperties()
|
|
33
|
+
// Resolve properties inside description
|
|
34
|
+
properties.description = Utils.greedyTemplate(
|
|
35
|
+
feature.properties.description || '',
|
|
36
|
+
properties
|
|
37
|
+
)
|
|
38
|
+
let content = Utils.greedyTemplate(template, properties)
|
|
39
|
+
content = Utils.toHTML(content, { target: target })
|
|
40
|
+
return Utils.loadTemplate(`<div class="umap-popup-container text">${content}</div>`)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
renderFooter(feature) {
|
|
44
|
+
if (feature.hasPopupFooter()) {
|
|
45
|
+
const template = `
|
|
46
|
+
<ul class="umap-popup-footer dark">
|
|
47
|
+
<li rel="prev"><button class="icon icon-16 icon-back" data-ref="previous"></button></li>
|
|
48
|
+
<li class="zoom" title="${translate('Zoom to this feature')}"><button class="icon icon-16 icon-zoom" data-ref="zoom"></button></li>
|
|
49
|
+
<li rel="next"><button class="icon icon-16 icon-forward" data-ref="next"></button></li>
|
|
50
|
+
</ul>`
|
|
51
|
+
const [footer, { previous, zoom, next }] = Utils.loadTemplateWithRefs(template)
|
|
52
|
+
const nextFeature = feature.getNext()
|
|
53
|
+
const previousFeature = feature.getPrevious()
|
|
54
|
+
// Fixme: remove me when this is merged and released
|
|
55
|
+
// https://github.com/Leaflet/Leaflet/pull/9052
|
|
56
|
+
DomEvent.disableClickPropagation(footer)
|
|
57
|
+
if (nextFeature) {
|
|
58
|
+
next.title = translate('Go to «{feature}»', {
|
|
59
|
+
feature: nextFeature.properties.name || translate('next'),
|
|
60
|
+
})
|
|
61
|
+
DomEvent.on(next, 'click', () => {
|
|
62
|
+
nextFeature.zoomTo({ callback: nextFeature.view })
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
if (previousFeature) {
|
|
66
|
+
previous.title = translate('Go to «{feature}»', {
|
|
67
|
+
feature: previousFeature.properties.name || translate('previous'),
|
|
68
|
+
})
|
|
69
|
+
DomEvent.on(previous, 'click', () => {
|
|
70
|
+
previousFeature.zoomTo({ callback: previousFeature.view })
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
DomEvent.on(zoom, 'click', () => feature.zoomTo())
|
|
74
|
+
return footer
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
render(feature, container) {
|
|
79
|
+
const title = this.renderTitle(feature)
|
|
80
|
+
if (title) container.appendChild(title)
|
|
81
|
+
const body = this.renderBody(feature)
|
|
82
|
+
if (body) DomUtil.add('div', 'umap-popup-content', container, body)
|
|
83
|
+
const footer = this.renderFooter(feature)
|
|
84
|
+
if (footer) container.appendChild(footer)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export const TitleMixin = (Base) =>
|
|
88
|
+
class extends Base {
|
|
89
|
+
renderTitle(feature) {
|
|
90
|
+
const title = feature.getDisplayName()
|
|
91
|
+
if (title) {
|
|
92
|
+
return Utils.loadTemplate(`<h3 class="popup-title">${title}</h3>`)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
class Table extends TitleMixin(PopupTemplate) {
|
|
98
|
+
getValue(feature, key) {
|
|
99
|
+
// TODO, manage links (url, mailto, wikipedia...)
|
|
100
|
+
const value = Utils.escapeHTML(feature.properties[key]).trim()
|
|
101
|
+
if (value.indexOf('http') === 0) {
|
|
102
|
+
return `<a href="${value}" target="_blank">${value}</a>`
|
|
103
|
+
}
|
|
104
|
+
return value
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
makeRow(feature, key) {
|
|
108
|
+
return Utils.loadTemplate(
|
|
109
|
+
`<tr><th>${key}</th><td>${this.getValue(feature, key)}</td></tr>`
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
renderBody(feature) {
|
|
114
|
+
const table = document.createElement('table')
|
|
115
|
+
|
|
116
|
+
for (const key in feature.properties) {
|
|
117
|
+
if (typeof feature.properties[key] === 'object' || key === 'name') continue
|
|
118
|
+
table.appendChild(this.makeRow(feature, key))
|
|
119
|
+
}
|
|
120
|
+
return table
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
class GeoRSSImage extends TitleMixin(PopupTemplate) {
|
|
125
|
+
renderBody(feature) {
|
|
126
|
+
const body = DomUtil.create('a')
|
|
127
|
+
body.href = feature.properties.link
|
|
128
|
+
body.target = '_blank'
|
|
129
|
+
if (feature.properties.img) {
|
|
130
|
+
const img = DomUtil.create('img', '', body)
|
|
131
|
+
img.src = feature.properties.img
|
|
132
|
+
// Sadly, we are unable to override this from JS the clean way
|
|
133
|
+
// See https://github.com/Leaflet/Leaflet/commit/61d746818b99d362108545c151a27f09d60960ee#commitcomment-6061847
|
|
134
|
+
img.style.maxWidth = '500px'
|
|
135
|
+
img.style.maxHeight = '500px'
|
|
136
|
+
}
|
|
137
|
+
return body
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
class GeoRSSLink extends PopupTemplate {
|
|
142
|
+
renderBody(feature) {
|
|
143
|
+
if (feature.properties.link) {
|
|
144
|
+
return Utils.loadTemplate(
|
|
145
|
+
`<a href="${feature.properties.link}" target="_blank"><h3>${feature.getDisplayName()}</h3></a>`
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
class OSM extends TitleMixin(PopupTemplate) {
|
|
152
|
+
getName(feature) {
|
|
153
|
+
const props = feature.properties
|
|
154
|
+
const locale = getLocale()
|
|
155
|
+
if (locale && props[`name:${locale}`]) return props[`name:${locale}`]
|
|
156
|
+
return props.name
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
renderBody(feature) {
|
|
160
|
+
const props = feature.properties
|
|
161
|
+
const body = document.createElement('div')
|
|
162
|
+
const title = DomUtil.add('h3', 'popup-title', container)
|
|
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))
|
|
171
|
+
const street = props['addr:street']
|
|
172
|
+
if (street) {
|
|
173
|
+
const row = DomUtil.add('address', 'address', body)
|
|
174
|
+
const number = props['addr:housenumber']
|
|
175
|
+
if (number) {
|
|
176
|
+
// Poor way to deal with international forms of writting addresses
|
|
177
|
+
DomUtil.add('span', '', row, `${translate('No.')}: ${number}`)
|
|
178
|
+
DomUtil.add('span', '', row, `${translate('Street')}: ${street}`)
|
|
179
|
+
} else {
|
|
180
|
+
DomUtil.add('span', '', row, street)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (props.website) {
|
|
184
|
+
body.appendChild(
|
|
185
|
+
Utils.loadTemplate(`<div><a href="${props.website}">${props.website}</a></div>`)
|
|
186
|
+
)
|
|
187
|
+
}
|
|
188
|
+
const phone = props.phone || props['contact:phone']
|
|
189
|
+
if (phone) {
|
|
190
|
+
body.appendChild(
|
|
191
|
+
Utils.loadTemplate(`<div><a href="tel:${phone}">${phone}</a></div>`)
|
|
192
|
+
)
|
|
193
|
+
}
|
|
194
|
+
if (props.mobile) {
|
|
195
|
+
body.appendChild(
|
|
196
|
+
Utils.loadTemplate(
|
|
197
|
+
`<div><a href="tel:${props.mobile}">${props.mobile}</a></div>`
|
|
198
|
+
)
|
|
199
|
+
)
|
|
200
|
+
}
|
|
201
|
+
const email = props.email || props['contact:email']
|
|
202
|
+
if (email) {
|
|
203
|
+
body.appendChild(
|
|
204
|
+
Utils.loadTemplate(`<div><a href="mailto:${email}">${email}</a></div>`)
|
|
205
|
+
)
|
|
206
|
+
}
|
|
207
|
+
const id = props['@id'] || props.id
|
|
208
|
+
if (id) {
|
|
209
|
+
body.appendChild(
|
|
210
|
+
Utils.loadTemplate(
|
|
211
|
+
`<div class="osm-link"><a href="https://www.openstreetmap.org/${id}">${translate('See on OpenStreetMap')}</a></div>`
|
|
212
|
+
)
|
|
213
|
+
)
|
|
214
|
+
}
|
|
215
|
+
return body
|
|
216
|
+
}
|
|
217
|
+
}
|