umap-project 1.12.1__py3-none-any.whl → 1.13.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 +82 -54
- umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- umap/locale/cs_CZ/LC_MESSAGES/django.po +82 -54
- umap/locale/el/LC_MESSAGES/django.mo +0 -0
- umap/locale/el/LC_MESSAGES/django.po +86 -58
- umap/locale/en/LC_MESSAGES/django.po +79 -51
- umap/locale/es/LC_MESSAGES/django.mo +0 -0
- umap/locale/es/LC_MESSAGES/django.po +82 -54
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +84 -56
- umap/locale/hu/LC_MESSAGES/django.mo +0 -0
- umap/locale/hu/LC_MESSAGES/django.po +108 -80
- umap/locale/it/LC_MESSAGES/django.mo +0 -0
- umap/locale/it/LC_MESSAGES/django.po +82 -54
- umap/locale/ms/LC_MESSAGES/django.mo +0 -0
- umap/locale/ms/LC_MESSAGES/django.po +82 -54
- umap/locale/pl/LC_MESSAGES/django.mo +0 -0
- umap/locale/pl/LC_MESSAGES/django.po +82 -54
- umap/locale/sv/LC_MESSAGES/django.mo +0 -0
- umap/locale/sv/LC_MESSAGES/django.po +82 -54
- umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
- umap/locale/zh_TW/LC_MESSAGES/django.po +86 -58
- umap/models.py +29 -0
- umap/static/umap/base.css +33 -5
- umap/static/umap/content.css +41 -2
- umap/static/umap/img/16.svg +12 -2
- umap/static/umap/img/source/16.svg +165 -820
- umap/static/umap/js/umap.browser.js +9 -3
- umap/static/umap/js/umap.controls.js +60 -222
- umap/static/umap/js/umap.core.js +66 -30
- umap/static/umap/js/umap.forms.js +18 -31
- umap/static/umap/js/umap.icon.js +44 -21
- umap/static/umap/js/umap.js +11 -27
- umap/static/umap/js/umap.layer.js +68 -25
- umap/static/umap/js/umap.popup.js +87 -0
- umap/static/umap/js/umap.share.js +254 -0
- umap/static/umap/js/umap.ui.js +4 -2
- umap/static/umap/locale/am_ET.js +19 -9
- umap/static/umap/locale/am_ET.json +19 -9
- umap/static/umap/locale/ar.js +19 -9
- umap/static/umap/locale/ar.json +19 -9
- umap/static/umap/locale/ast.js +19 -9
- umap/static/umap/locale/ast.json +19 -9
- umap/static/umap/locale/bg.js +19 -9
- umap/static/umap/locale/bg.json +19 -9
- umap/static/umap/locale/br.js +22 -12
- umap/static/umap/locale/br.json +22 -12
- umap/static/umap/locale/ca.js +19 -9
- umap/static/umap/locale/ca.json +19 -9
- umap/static/umap/locale/cs_CZ.js +19 -9
- umap/static/umap/locale/cs_CZ.json +19 -9
- umap/static/umap/locale/da.js +19 -9
- umap/static/umap/locale/da.json +19 -9
- umap/static/umap/locale/de.js +30 -20
- umap/static/umap/locale/de.json +30 -20
- umap/static/umap/locale/el.js +19 -9
- umap/static/umap/locale/el.json +19 -9
- umap/static/umap/locale/en.js +19 -9
- umap/static/umap/locale/en.json +19 -9
- umap/static/umap/locale/en_US.json +19 -9
- umap/static/umap/locale/es.js +19 -9
- umap/static/umap/locale/es.json +19 -9
- umap/static/umap/locale/et.js +19 -9
- umap/static/umap/locale/et.json +19 -9
- umap/static/umap/locale/fa_IR.js +19 -9
- umap/static/umap/locale/fa_IR.json +19 -9
- umap/static/umap/locale/fi.js +19 -9
- umap/static/umap/locale/fi.json +19 -9
- umap/static/umap/locale/fr.js +21 -11
- umap/static/umap/locale/fr.json +21 -11
- umap/static/umap/locale/gl.js +19 -9
- umap/static/umap/locale/gl.json +19 -9
- umap/static/umap/locale/he.js +19 -9
- umap/static/umap/locale/he.json +19 -9
- umap/static/umap/locale/hr.js +19 -9
- umap/static/umap/locale/hr.json +19 -9
- umap/static/umap/locale/hu.js +19 -9
- umap/static/umap/locale/hu.json +19 -9
- umap/static/umap/locale/id.js +19 -9
- umap/static/umap/locale/id.json +19 -9
- umap/static/umap/locale/is.js +19 -9
- umap/static/umap/locale/is.json +19 -9
- umap/static/umap/locale/it.js +19 -9
- umap/static/umap/locale/it.json +19 -9
- umap/static/umap/locale/ja.js +19 -9
- umap/static/umap/locale/ja.json +19 -9
- umap/static/umap/locale/ko.js +19 -9
- umap/static/umap/locale/ko.json +19 -9
- umap/static/umap/locale/lt.js +19 -9
- umap/static/umap/locale/lt.json +19 -9
- umap/static/umap/locale/ms.js +19 -9
- umap/static/umap/locale/ms.json +19 -9
- umap/static/umap/locale/nl.js +20 -10
- umap/static/umap/locale/nl.json +20 -10
- umap/static/umap/locale/no.js +19 -9
- umap/static/umap/locale/no.json +19 -9
- umap/static/umap/locale/pl.js +19 -9
- umap/static/umap/locale/pl.json +19 -9
- umap/static/umap/locale/pl_PL.json +19 -9
- umap/static/umap/locale/pt.js +19 -9
- umap/static/umap/locale/pt.json +19 -9
- umap/static/umap/locale/pt_BR.js +19 -9
- umap/static/umap/locale/pt_BR.json +19 -9
- umap/static/umap/locale/pt_PT.js +19 -9
- umap/static/umap/locale/pt_PT.json +19 -9
- umap/static/umap/locale/ro.js +19 -9
- umap/static/umap/locale/ro.json +19 -9
- umap/static/umap/locale/ru.js +19 -9
- umap/static/umap/locale/ru.json +19 -9
- umap/static/umap/locale/sk_SK.js +19 -9
- umap/static/umap/locale/sk_SK.json +19 -9
- umap/static/umap/locale/sl.js +19 -9
- umap/static/umap/locale/sl.json +19 -9
- umap/static/umap/locale/sr.js +19 -9
- umap/static/umap/locale/sr.json +19 -9
- umap/static/umap/locale/sv.js +19 -9
- umap/static/umap/locale/sv.json +19 -9
- umap/static/umap/locale/th_TH.js +19 -9
- umap/static/umap/locale/th_TH.json +19 -9
- umap/static/umap/locale/tr.js +19 -9
- umap/static/umap/locale/tr.json +19 -9
- umap/static/umap/locale/uk_UA.js +19 -9
- umap/static/umap/locale/uk_UA.json +19 -9
- umap/static/umap/locale/vi.js +19 -9
- umap/static/umap/locale/vi.json +19 -9
- umap/static/umap/locale/vi_VN.json +19 -9
- umap/static/umap/locale/zh.js +19 -9
- umap/static/umap/locale/zh.json +19 -9
- umap/static/umap/locale/zh_CN.json +19 -9
- umap/static/umap/locale/zh_TW.Big5.json +19 -9
- umap/static/umap/locale/zh_TW.js +55 -45
- umap/static/umap/locale/zh_TW.json +55 -45
- umap/static/umap/map.css +77 -10
- umap/static/umap/test/Map.Export.js +3 -3
- umap/static/umap/test/Polygon.js +2 -2
- umap/static/umap/test/Polyline.js +2 -0
- umap/static/umap/test/index.html +1 -0
- umap/static/umap/vendors/leaflet/leaflet-src.esm.js +7055 -7054
- umap/static/umap/vendors/leaflet/leaflet-src.js +7144 -7144
- umap/static/umap/vendors/toolbar/leaflet.toolbar-src.js +1 -1
- umap/templates/auth/user_form.html +1 -1
- umap/templates/umap/content.html +1 -1
- umap/templates/umap/js.html +1 -0
- umap/templates/umap/map_list.html +1 -1
- umap/templates/umap/map_table.html +67 -35
- umap/templates/umap/user_dashboard.html +23 -1
- umap/templatetags/umap_tags.py +7 -27
- umap/tests/integration/test_edit_datalayer.py +45 -0
- umap/tests/integration/test_export_map.py +2 -3
- umap/tests/integration/test_facets_browser.py +86 -0
- umap/utils.py +17 -0
- umap/views.py +7 -18
- {umap_project-1.12.1.dist-info → umap_project-1.13.0.dist-info}/METADATA +4 -11
- {umap_project-1.12.1.dist-info → umap_project-1.13.0.dist-info}/RECORD +159 -156
- {umap_project-1.12.1.dist-info → umap_project-1.13.0.dist-info}/WHEEL +0 -0
- {umap_project-1.12.1.dist-info → umap_project-1.13.0.dist-info}/entry_points.txt +0 -0
- {umap_project-1.12.1.dist-info → umap_project-1.13.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -13,7 +13,7 @@ L.U.Browser = L.Class.extend({
|
|
|
13
13
|
zoom_to = L.DomUtil.create('i', 'feature-zoom_to', feature_li),
|
|
14
14
|
edit = L.DomUtil.create('i', 'show-on-edit feature-edit', feature_li),
|
|
15
15
|
del = L.DomUtil.create('i', 'show-on-edit feature-delete', feature_li),
|
|
16
|
-
|
|
16
|
+
colorBox = L.DomUtil.create('i', 'feature-color', feature_li),
|
|
17
17
|
title = L.DomUtil.create('span', 'feature-title', feature_li),
|
|
18
18
|
symbol = feature._getIconUrl
|
|
19
19
|
? L.U.Icon.prototype.formatUrl(feature._getIconUrl(), feature)
|
|
@@ -22,8 +22,12 @@ L.U.Browser = L.Class.extend({
|
|
|
22
22
|
edit.title = L._('Edit this feature')
|
|
23
23
|
del.title = L._('Delete this feature')
|
|
24
24
|
title.textContent = feature.getDisplayName() || '—'
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
const bgcolor = feature.getOption('color')
|
|
26
|
+
colorBox.style.backgroundColor = bgcolor
|
|
27
|
+
if (symbol && symbol !== this.map.options.default_iconUrl) {
|
|
28
|
+
const icon = L.U.Icon.makeIconElement(symbol, colorBox)
|
|
29
|
+
L.U.Icon.setIconContrast(icon, colorBox, symbol, bgcolor)
|
|
30
|
+
}
|
|
27
31
|
L.DomEvent.on(
|
|
28
32
|
zoom_to,
|
|
29
33
|
'click',
|
|
@@ -58,6 +62,8 @@ L.U.Browser = L.Class.extend({
|
|
|
58
62
|
container.id = `browse_data_datalayer_${datalayer.umap_id}`
|
|
59
63
|
datalayer.renderToolbox(headline)
|
|
60
64
|
L.DomUtil.add('span', '', headline, datalayer.options.name)
|
|
65
|
+
const counter = L.DomUtil.add('span', 'datalayer-counter', headline, datalayer.count())
|
|
66
|
+
counter.title = L._('{count} features in this layer', {count: datalayer.count()})
|
|
61
67
|
const ul = L.DomUtil.create('ul', '', container)
|
|
62
68
|
L.DomUtil.classIf(container, 'off', !datalayer.isVisible())
|
|
63
69
|
|
|
@@ -409,9 +409,9 @@ L.Control.Embed = L.Control.extend({
|
|
|
409
409
|
const shareButton = L.DomUtil.createButton(
|
|
410
410
|
'',
|
|
411
411
|
container,
|
|
412
|
-
L._('Share
|
|
413
|
-
map.
|
|
414
|
-
map
|
|
412
|
+
L._('Share and download'),
|
|
413
|
+
map.share.open,
|
|
414
|
+
map.share
|
|
415
415
|
)
|
|
416
416
|
L.DomEvent.on(shareButton, 'dblclick', L.DomEvent.stopPropagation)
|
|
417
417
|
return container
|
|
@@ -632,12 +632,14 @@ L.U.DataLayersControl = L.Control.extend({
|
|
|
632
632
|
function (e) {
|
|
633
633
|
const layer = this.map.datalayers[e.src.dataset.id],
|
|
634
634
|
other = this.map.datalayers[e.dst.dataset.id],
|
|
635
|
-
minIndex = Math.min(
|
|
635
|
+
minIndex = Math.min(layer.getRank(), other.getRank()),
|
|
636
|
+
maxIndex = Math.max(layer.getRank(), other.getRank())
|
|
636
637
|
if (e.finalIndex === 0) layer.bringToTop()
|
|
637
638
|
else if (e.finalIndex > e.initialIndex) layer.insertBefore(other)
|
|
638
639
|
else layer.insertAfter(other)
|
|
639
640
|
this.map.eachDataLayerReverse((datalayer) => {
|
|
640
|
-
if (datalayer.getRank() >= minIndex
|
|
641
|
+
if (datalayer.getRank() >= minIndex && datalayer.getRank() <= maxIndex)
|
|
642
|
+
datalayer.isDirty = true
|
|
641
643
|
})
|
|
642
644
|
this.map.indexDatalayers()
|
|
643
645
|
},
|
|
@@ -894,46 +896,6 @@ L.U.Map.include({
|
|
|
894
896
|
this.ui.openPanel({ data: { html: container }, actions: actions })
|
|
895
897
|
},
|
|
896
898
|
|
|
897
|
-
EXPORT_TYPES: {
|
|
898
|
-
geojson: {
|
|
899
|
-
formatter: function (map) {
|
|
900
|
-
return JSON.stringify(map.toGeoJSON(), null, 2)
|
|
901
|
-
},
|
|
902
|
-
ext: '.geojson',
|
|
903
|
-
filetype: 'application/json',
|
|
904
|
-
},
|
|
905
|
-
gpx: {
|
|
906
|
-
formatter: function (map) {
|
|
907
|
-
return togpx(map.toGeoJSON())
|
|
908
|
-
},
|
|
909
|
-
ext: '.gpx',
|
|
910
|
-
filetype: 'application/gpx+xml',
|
|
911
|
-
},
|
|
912
|
-
kml: {
|
|
913
|
-
formatter: function (map) {
|
|
914
|
-
return tokml(map.toGeoJSON())
|
|
915
|
-
},
|
|
916
|
-
ext: '.kml',
|
|
917
|
-
filetype: 'application/vnd.google-earth.kml+xml',
|
|
918
|
-
},
|
|
919
|
-
csv: {
|
|
920
|
-
formatter: function (map) {
|
|
921
|
-
const table = []
|
|
922
|
-
map.eachFeature((feature) => {
|
|
923
|
-
const row = feature.toGeoJSON()['properties'],
|
|
924
|
-
center = feature.getCenter()
|
|
925
|
-
delete row['_umap_options']
|
|
926
|
-
row['Latitude'] = center.lat
|
|
927
|
-
row['Longitude'] = center.lng
|
|
928
|
-
table.push(row)
|
|
929
|
-
})
|
|
930
|
-
return csv2geojson.dsv.csvFormat(table)
|
|
931
|
-
},
|
|
932
|
-
ext: '.csv',
|
|
933
|
-
filetype: 'text/csv',
|
|
934
|
-
},
|
|
935
|
-
},
|
|
936
|
-
|
|
937
899
|
renderEditToolbar: function () {
|
|
938
900
|
const container = L.DomUtil.create(
|
|
939
901
|
'div',
|
|
@@ -1081,107 +1043,6 @@ L.U.Map.include({
|
|
|
1081
1043
|
this
|
|
1082
1044
|
)
|
|
1083
1045
|
},
|
|
1084
|
-
|
|
1085
|
-
renderShareBox: function () {
|
|
1086
|
-
const container = L.DomUtil.create('div', 'umap-share')
|
|
1087
|
-
const title = L.DomUtil.create('h3', '', container)
|
|
1088
|
-
title.textContent = L._('Share, download and embed this map')
|
|
1089
|
-
|
|
1090
|
-
const embedTitle = L.DomUtil.add('h4', '', container, L._('Embed the map'))
|
|
1091
|
-
const iframe = L.DomUtil.create('textarea', 'umap-share-iframe', container)
|
|
1092
|
-
const urlTitle = L.DomUtil.add('h4', '', container, L._('Direct link'))
|
|
1093
|
-
const exportUrl = L.DomUtil.create('input', 'umap-share-url', container)
|
|
1094
|
-
let option
|
|
1095
|
-
exportUrl.type = 'text'
|
|
1096
|
-
const UIFields = [
|
|
1097
|
-
['dimensions.width', { handler: 'Input', label: L._('width') }],
|
|
1098
|
-
['dimensions.height', { handler: 'Input', label: L._('height') }],
|
|
1099
|
-
[
|
|
1100
|
-
'options.includeFullScreenLink',
|
|
1101
|
-
{ handler: 'Switch', label: L._('Include full screen link?') },
|
|
1102
|
-
],
|
|
1103
|
-
[
|
|
1104
|
-
'options.currentView',
|
|
1105
|
-
{ handler: 'Switch', label: L._('Current view instead of default map view?') },
|
|
1106
|
-
],
|
|
1107
|
-
[
|
|
1108
|
-
'options.keepCurrentDatalayers',
|
|
1109
|
-
{ handler: 'Switch', label: L._('Keep current visible layers') },
|
|
1110
|
-
],
|
|
1111
|
-
[
|
|
1112
|
-
'options.viewCurrentFeature',
|
|
1113
|
-
{ handler: 'Switch', label: L._('Open current feature on load') },
|
|
1114
|
-
],
|
|
1115
|
-
'queryString.moreControl',
|
|
1116
|
-
'queryString.scrollWheelZoom',
|
|
1117
|
-
'queryString.miniMap',
|
|
1118
|
-
'queryString.scaleControl',
|
|
1119
|
-
'queryString.onLoadPanel',
|
|
1120
|
-
'queryString.captionBar',
|
|
1121
|
-
'queryString.captionMenus',
|
|
1122
|
-
]
|
|
1123
|
-
for (let i = 0; i < this.HIDDABLE_CONTROLS.length; i++) {
|
|
1124
|
-
UIFields.push(`queryString.${this.HIDDABLE_CONTROLS[i]}Control`)
|
|
1125
|
-
}
|
|
1126
|
-
const iframeExporter = new L.U.IframeExporter(this)
|
|
1127
|
-
const buildIframeCode = () => {
|
|
1128
|
-
iframe.innerHTML = iframeExporter.build()
|
|
1129
|
-
exportUrl.value = window.location.protocol + iframeExporter.buildUrl()
|
|
1130
|
-
}
|
|
1131
|
-
buildIframeCode()
|
|
1132
|
-
const builder = new L.U.FormBuilder(iframeExporter, UIFields, {
|
|
1133
|
-
callback: buildIframeCode,
|
|
1134
|
-
})
|
|
1135
|
-
const iframeOptions = L.DomUtil.createFieldset(container, L._('Export options'))
|
|
1136
|
-
iframeOptions.appendChild(builder.build())
|
|
1137
|
-
if (this.options.shortUrl) {
|
|
1138
|
-
L.DomUtil.create('hr', '', container)
|
|
1139
|
-
L.DomUtil.add('h4', '', container, L._('Short URL'))
|
|
1140
|
-
const shortUrl = L.DomUtil.create('input', 'umap-short-url', container)
|
|
1141
|
-
shortUrl.type = 'text'
|
|
1142
|
-
shortUrl.value = this.options.shortUrl
|
|
1143
|
-
}
|
|
1144
|
-
L.DomUtil.create('hr', '', container)
|
|
1145
|
-
L.DomUtil.add('h4', '', container, L._('Backup data'))
|
|
1146
|
-
const downloadUrl = L.Util.template(this.options.urls.map_download, {
|
|
1147
|
-
map_id: this.options.umap_id,
|
|
1148
|
-
})
|
|
1149
|
-
const link = L.DomUtil.createLink(
|
|
1150
|
-
'button',
|
|
1151
|
-
container,
|
|
1152
|
-
L._('Download full data'),
|
|
1153
|
-
downloadUrl
|
|
1154
|
-
)
|
|
1155
|
-
let name = this.options.name || 'data'
|
|
1156
|
-
name = name.replace(/[^a-z0-9]/gi, '_').toLowerCase()
|
|
1157
|
-
link.setAttribute('download', `${name}.umap`)
|
|
1158
|
-
L.DomUtil.create('hr', '', container)
|
|
1159
|
-
L.DomUtil.add('h4', '', container, L._('Download data'))
|
|
1160
|
-
const typeInput = L.DomUtil.create('select', '', container)
|
|
1161
|
-
typeInput.name = 'format'
|
|
1162
|
-
const exportCaveat = L.DomUtil.add(
|
|
1163
|
-
'small',
|
|
1164
|
-
'help-text',
|
|
1165
|
-
container,
|
|
1166
|
-
L._('Only visible features will be downloaded.')
|
|
1167
|
-
)
|
|
1168
|
-
for (const key in this.EXPORT_TYPES) {
|
|
1169
|
-
if (this.EXPORT_TYPES.hasOwnProperty(key)) {
|
|
1170
|
-
option = L.DomUtil.create('option', '', typeInput)
|
|
1171
|
-
option.value = key
|
|
1172
|
-
option.textContent = this.EXPORT_TYPES[key].name || key
|
|
1173
|
-
if (this.EXPORT_TYPES[key].selected) option.selected = true
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
|
-
L.DomUtil.createButton(
|
|
1177
|
-
'button',
|
|
1178
|
-
container,
|
|
1179
|
-
L._('Download data'),
|
|
1180
|
-
() => this.download(typeInput.value),
|
|
1181
|
-
this
|
|
1182
|
-
)
|
|
1183
|
-
this.ui.openPanel({ data: { html: container } })
|
|
1184
|
-
},
|
|
1185
1046
|
})
|
|
1186
1047
|
|
|
1187
1048
|
/* Used in view mode to define the current tilelayer */
|
|
@@ -1199,11 +1060,21 @@ L.U.TileLayerControl = L.Control.IconLayers.extend({
|
|
|
1199
1060
|
if (!layers) {
|
|
1200
1061
|
layers = []
|
|
1201
1062
|
this.map.eachTileLayer((layer) => {
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1063
|
+
try {
|
|
1064
|
+
// We'd like to use layer.getTileUrl, but this method will only work
|
|
1065
|
+
// when the tilelayer is actually added to the map (needs this._tileZoom
|
|
1066
|
+
// to be defined)
|
|
1067
|
+
// Fixme when https://github.com/Leaflet/Leaflet/pull/9201 is released
|
|
1068
|
+
const icon = L.Util.template(layer.options.url_template, this.map.demoTileInfos)
|
|
1069
|
+
layers.push({
|
|
1070
|
+
title: layer.options.name,
|
|
1071
|
+
layer: layer,
|
|
1072
|
+
icon: icon,
|
|
1073
|
+
})
|
|
1074
|
+
} catch (e) {
|
|
1075
|
+
// Skip this tilelayer
|
|
1076
|
+
console.error(e)
|
|
1077
|
+
}
|
|
1207
1078
|
})
|
|
1208
1079
|
}
|
|
1209
1080
|
const maxShown = 10
|
|
@@ -1353,9 +1224,47 @@ L.U.StarControl = L.Control.extend({
|
|
|
1353
1224
|
|
|
1354
1225
|
L.U.Search = L.PhotonSearch.extend({
|
|
1355
1226
|
initialize: function (map, input, options) {
|
|
1227
|
+
this.options.placeholder = L._('Type a place name or coordinates')
|
|
1356
1228
|
L.PhotonSearch.prototype.initialize.call(this, map, input, options)
|
|
1357
1229
|
this.options.url = map.options.urls.search
|
|
1358
1230
|
if (map.options.maxBounds) this.options.bbox = map.options.maxBounds.toBBoxString()
|
|
1231
|
+
this.reverse = new L.PhotonReverse({
|
|
1232
|
+
handleResults: (geojson) => {
|
|
1233
|
+
this.handleResultsWithReverse(geojson)
|
|
1234
|
+
},
|
|
1235
|
+
})
|
|
1236
|
+
},
|
|
1237
|
+
|
|
1238
|
+
handleResultsWithReverse: function (geojson) {
|
|
1239
|
+
const latlng = this.reverse.latlng
|
|
1240
|
+
geojson.features.unshift({
|
|
1241
|
+
type: 'Feature',
|
|
1242
|
+
geometry: { type: 'Point', coordinates: [latlng.lng, latlng.lat] },
|
|
1243
|
+
properties: {
|
|
1244
|
+
name: L._('Go to "{coords}"', { coords: `${latlng.lat} ${latlng.lng}` }),
|
|
1245
|
+
},
|
|
1246
|
+
})
|
|
1247
|
+
|
|
1248
|
+
this.handleResults(geojson)
|
|
1249
|
+
},
|
|
1250
|
+
|
|
1251
|
+
search: function () {
|
|
1252
|
+
const pattern = /^(?<lat>[-+]?\d{1,2}[.,]\d+)\s*[ ,]\s*(?<lng>[-+]?\d{1,3}[.,]\d+)$/
|
|
1253
|
+
if (pattern.test(this.input.value)) {
|
|
1254
|
+
this.hide()
|
|
1255
|
+
const { lat, lng } = pattern.exec(this.input.value).groups
|
|
1256
|
+
const latlng = L.latLng(lat, lng)
|
|
1257
|
+
if (latlng.isValid()) {
|
|
1258
|
+
this.reverse.doReverse(latlng)
|
|
1259
|
+
} else {
|
|
1260
|
+
this.map.ui.alert({ content: 'Invalid latitude or longitude', mode: 'error' })
|
|
1261
|
+
}
|
|
1262
|
+
return
|
|
1263
|
+
}
|
|
1264
|
+
// Only numbers, abort.
|
|
1265
|
+
if (/^[\d .,]*$/.test(this.input.value)) return
|
|
1266
|
+
// Do normal search
|
|
1267
|
+
L.PhotonSearch.prototype.search.call(this)
|
|
1359
1268
|
},
|
|
1360
1269
|
|
|
1361
1270
|
onBlur: function (e) {
|
|
@@ -1503,77 +1412,6 @@ L.U.ContextMenu = L.Map.ContextMenu.extend({
|
|
|
1503
1412
|
},
|
|
1504
1413
|
})
|
|
1505
1414
|
|
|
1506
|
-
L.U.IframeExporter = L.Evented.extend({
|
|
1507
|
-
options: {
|
|
1508
|
-
includeFullScreenLink: true,
|
|
1509
|
-
currentView: false,
|
|
1510
|
-
keepCurrentDatalayers: false,
|
|
1511
|
-
viewCurrentFeature: false,
|
|
1512
|
-
},
|
|
1513
|
-
|
|
1514
|
-
queryString: {
|
|
1515
|
-
scaleControl: false,
|
|
1516
|
-
miniMap: false,
|
|
1517
|
-
scrollWheelZoom: false,
|
|
1518
|
-
zoomControl: true,
|
|
1519
|
-
editMode: 'disabled',
|
|
1520
|
-
moreControl: true,
|
|
1521
|
-
searchControl: null,
|
|
1522
|
-
tilelayersControl: null,
|
|
1523
|
-
embedControl: null,
|
|
1524
|
-
datalayersControl: true,
|
|
1525
|
-
onLoadPanel: 'none',
|
|
1526
|
-
captionBar: false,
|
|
1527
|
-
captionMenus: true,
|
|
1528
|
-
},
|
|
1529
|
-
|
|
1530
|
-
dimensions: {
|
|
1531
|
-
width: '100%',
|
|
1532
|
-
height: '300px',
|
|
1533
|
-
},
|
|
1534
|
-
|
|
1535
|
-
initialize: function (map) {
|
|
1536
|
-
this.map = map
|
|
1537
|
-
this.baseUrl = L.Util.getBaseUrl()
|
|
1538
|
-
// Use map default, not generic default
|
|
1539
|
-
this.queryString.onLoadPanel = this.map.options.onLoadPanel
|
|
1540
|
-
},
|
|
1541
|
-
|
|
1542
|
-
getMap: function () {
|
|
1543
|
-
return this.map
|
|
1544
|
-
},
|
|
1545
|
-
|
|
1546
|
-
buildUrl: function (options) {
|
|
1547
|
-
const datalayers = []
|
|
1548
|
-
if (this.options.viewCurrentFeature && this.map.currentFeature) {
|
|
1549
|
-
this.queryString.feature = this.map.currentFeature.getSlug()
|
|
1550
|
-
}
|
|
1551
|
-
if (this.options.keepCurrentDatalayers) {
|
|
1552
|
-
this.map.eachDataLayer((datalayer) => {
|
|
1553
|
-
if (datalayer.isVisible() && datalayer.umap_id) {
|
|
1554
|
-
datalayers.push(datalayer.umap_id)
|
|
1555
|
-
}
|
|
1556
|
-
})
|
|
1557
|
-
this.queryString.datalayers = datalayers.join(',')
|
|
1558
|
-
} else {
|
|
1559
|
-
delete this.queryString.datalayers
|
|
1560
|
-
}
|
|
1561
|
-
const currentView = this.options.currentView ? window.location.hash : ''
|
|
1562
|
-
const queryString = L.extend({}, this.queryString, options)
|
|
1563
|
-
return `${this.baseUrl}?${L.Util.buildQueryString(queryString)}${currentView}`
|
|
1564
|
-
},
|
|
1565
|
-
|
|
1566
|
-
build: function () {
|
|
1567
|
-
const iframeUrl = this.buildUrl()
|
|
1568
|
-
let code = `<iframe width="${this.dimensions.width}" height="${this.dimensions.height}" frameborder="0" allowfullscreen allow="geolocation" src="${iframeUrl}"></iframe>`
|
|
1569
|
-
if (this.options.includeFullScreenLink) {
|
|
1570
|
-
const fullUrl = this.buildUrl({ scrollWheelZoom: true })
|
|
1571
|
-
code += `<p><a href="${fullUrl}">${L._('See full screen')}</a></p>`
|
|
1572
|
-
}
|
|
1573
|
-
return code
|
|
1574
|
-
},
|
|
1575
|
-
})
|
|
1576
|
-
|
|
1577
1415
|
L.U.Editable = L.Editable.extend({
|
|
1578
1416
|
initialize: function (map, options) {
|
|
1579
1417
|
L.Editable.prototype.initialize.call(this, map, options)
|
umap/static/umap/js/umap.core.js
CHANGED
|
@@ -262,6 +262,18 @@ L.Util.hasVar = (value) => {
|
|
|
262
262
|
return typeof value === 'string' && value.indexOf('{') != -1
|
|
263
263
|
}
|
|
264
264
|
|
|
265
|
+
L.Util.isPath = function (value) {
|
|
266
|
+
return value && value.length && value.startsWith('/')
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
L.Util.isRemoteUrl = function (value) {
|
|
270
|
+
return value && value.length && value.startsWith('http')
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
L.Util.isDataImage = function (value) {
|
|
274
|
+
return value && value.length && value.startsWith('data:image')
|
|
275
|
+
}
|
|
276
|
+
|
|
265
277
|
L.Util.copyToClipboard = function (textToCopy) {
|
|
266
278
|
// https://stackoverflow.com/a/65996386
|
|
267
279
|
// Navigator clipboard api needs a secure context (https)
|
|
@@ -346,6 +358,24 @@ L.DomUtil.createLink = (className, container, content, url, target, title) => {
|
|
|
346
358
|
return el
|
|
347
359
|
}
|
|
348
360
|
|
|
361
|
+
L.DomUtil.createCopiableInput = (parent, label, value) => {
|
|
362
|
+
const wrapper = L.DomUtil.add('div', 'copiable-input', parent)
|
|
363
|
+
const labelEl = L.DomUtil.add('label', '', wrapper, label)
|
|
364
|
+
const input = L.DomUtil.add('input', '', labelEl)
|
|
365
|
+
input.type = 'text'
|
|
366
|
+
input.readOnly = true
|
|
367
|
+
input.value = value
|
|
368
|
+
const button = L.DomUtil.createButton(
|
|
369
|
+
'',
|
|
370
|
+
wrapper,
|
|
371
|
+
'',
|
|
372
|
+
() => L.Util.copyToClipboard(input.value),
|
|
373
|
+
this
|
|
374
|
+
)
|
|
375
|
+
button.title = L._('copy')
|
|
376
|
+
return input
|
|
377
|
+
}
|
|
378
|
+
|
|
349
379
|
L.DomUtil.classIf = (el, className, bool) => {
|
|
350
380
|
if (bool) L.DomUtil.addClass(el, className)
|
|
351
381
|
else L.DomUtil.removeClass(el, className)
|
|
@@ -373,8 +403,8 @@ L.DomUtil.after = (target, el) => {
|
|
|
373
403
|
}
|
|
374
404
|
|
|
375
405
|
L.DomUtil.RGBRegex = /rgb *\( *([0-9]{1,3}) *, *([0-9]{1,3}) *, *([0-9]{1,3}) *\)/
|
|
376
|
-
L.DomUtil.TextColorFromBackgroundColor = (el) => {
|
|
377
|
-
return L.DomUtil.contrastedColor(el) ? '#ffffff' : '#000000'
|
|
406
|
+
L.DomUtil.TextColorFromBackgroundColor = (el, bgcolor) => {
|
|
407
|
+
return L.DomUtil.contrastedColor(el, bgcolor) ? '#ffffff' : '#000000'
|
|
378
408
|
}
|
|
379
409
|
const _CACHE_CONSTRAST = {}
|
|
380
410
|
L.DomUtil.contrastedColor = (el, bgcolor) => {
|
|
@@ -436,60 +466,62 @@ L.U.Keys = {
|
|
|
436
466
|
}
|
|
437
467
|
|
|
438
468
|
L.U.Help = L.Class.extend({
|
|
439
|
-
|
|
440
469
|
SHORTCUTS: {
|
|
441
470
|
DRAW_MARKER: {
|
|
442
|
-
shortcut:'Modifier+M',
|
|
443
|
-
label: L._('Draw a marker')
|
|
471
|
+
shortcut: 'Modifier+M',
|
|
472
|
+
label: L._('Draw a marker'),
|
|
444
473
|
},
|
|
445
474
|
DRAW_LINE: {
|
|
446
|
-
shortcut:'Modifier+L',
|
|
447
|
-
label: L._('Draw a polyline')
|
|
475
|
+
shortcut: 'Modifier+L',
|
|
476
|
+
label: L._('Draw a polyline'),
|
|
448
477
|
},
|
|
449
478
|
DRAW_POLYGON: {
|
|
450
|
-
shortcut:'Modifier+P',
|
|
451
|
-
label: L._('Draw a polygon')
|
|
479
|
+
shortcut: 'Modifier+P',
|
|
480
|
+
label: L._('Draw a polygon'),
|
|
452
481
|
},
|
|
453
482
|
TOGGLE_EDIT: {
|
|
454
|
-
shortcut:'Modifier+E',
|
|
455
|
-
label: L._('Toggle edit mode')
|
|
483
|
+
shortcut: 'Modifier+E',
|
|
484
|
+
label: L._('Toggle edit mode'),
|
|
456
485
|
},
|
|
457
486
|
STOP_EDIT: {
|
|
458
|
-
shortcut:'Modifier+E',
|
|
459
|
-
label: L._('Stop editing')
|
|
487
|
+
shortcut: 'Modifier+E',
|
|
488
|
+
label: L._('Stop editing'),
|
|
460
489
|
},
|
|
461
490
|
SAVE_MAP: {
|
|
462
|
-
shortcut:'Modifier+S',
|
|
463
|
-
label: L._('Save map')
|
|
491
|
+
shortcut: 'Modifier+S',
|
|
492
|
+
label: L._('Save map'),
|
|
464
493
|
},
|
|
465
494
|
IMPORT_PANEL: {
|
|
466
|
-
shortcut:'Modifier+I',
|
|
467
|
-
label: L._('Import data')
|
|
495
|
+
shortcut: 'Modifier+I',
|
|
496
|
+
label: L._('Import data'),
|
|
468
497
|
},
|
|
469
498
|
SEARCH: {
|
|
470
|
-
shortcut:'Modifier+F',
|
|
471
|
-
label: L._('Search location')
|
|
499
|
+
shortcut: 'Modifier+F',
|
|
500
|
+
label: L._('Search location'),
|
|
472
501
|
},
|
|
473
502
|
CANCEL: {
|
|
474
|
-
shortcut:'Modifier+Z',
|
|
475
|
-
label: L._('Cancel edits')
|
|
503
|
+
shortcut: 'Modifier+Z',
|
|
504
|
+
label: L._('Cancel edits'),
|
|
476
505
|
},
|
|
477
506
|
PREVIEW: {
|
|
478
|
-
shortcut:'Modifier+E',
|
|
479
|
-
label: L._('Back to preview')
|
|
507
|
+
shortcut: 'Modifier+E',
|
|
508
|
+
label: L._('Back to preview'),
|
|
480
509
|
},
|
|
481
510
|
SAVE: {
|
|
482
|
-
shortcut:'Modifier+S',
|
|
483
|
-
label: L._('Save current edits')
|
|
511
|
+
shortcut: 'Modifier+S',
|
|
512
|
+
label: L._('Save current edits'),
|
|
484
513
|
},
|
|
485
514
|
},
|
|
486
515
|
|
|
487
|
-
displayLabel: function (action, withKbdTag=true) {
|
|
488
|
-
let {shortcut, label} = this.SHORTCUTS[action]
|
|
516
|
+
displayLabel: function (action, withKbdTag = true) {
|
|
517
|
+
let { shortcut, label } = this.SHORTCUTS[action]
|
|
489
518
|
const modifier = this.isMacOS ? 'Cmd' : 'Ctrl'
|
|
490
519
|
shortcut = shortcut.replace('Modifier', modifier)
|
|
491
520
|
if (withKbdTag) {
|
|
492
|
-
shortcut = shortcut
|
|
521
|
+
shortcut = shortcut
|
|
522
|
+
.split('+')
|
|
523
|
+
.map((el) => `<kbd>${el}</kbd>`)
|
|
524
|
+
.join('+')
|
|
493
525
|
label += ` ${shortcut}`
|
|
494
526
|
} else {
|
|
495
527
|
label += ` (${shortcut})`
|
|
@@ -515,7 +547,9 @@ L.U.Help = L.Class.extend({
|
|
|
515
547
|
const label = L.DomUtil.create('span', '', closeButton)
|
|
516
548
|
label.title = label.textContent = L._('Close')
|
|
517
549
|
this.content = L.DomUtil.create('div', 'umap-help-content', this.box)
|
|
518
|
-
this.isMacOS = /mac/i.test(
|
|
550
|
+
this.isMacOS = /mac/i.test(
|
|
551
|
+
navigator.userAgentData ? navigator.userAgentData.platform : navigator.platform
|
|
552
|
+
)
|
|
519
553
|
},
|
|
520
554
|
|
|
521
555
|
onKeyDown: function (e) {
|
|
@@ -708,7 +742,9 @@ L.U.Help = L.Class.extend({
|
|
|
708
742
|
facetKey: L._(
|
|
709
743
|
'Comma separated list of properties to use for facet search (eg.: mykey,otherkey). To control label, add it after a | (eg.: mykey|My Key,otherkey|Other Key)'
|
|
710
744
|
),
|
|
711
|
-
interactive: L._(
|
|
745
|
+
interactive: L._(
|
|
746
|
+
'If false, the polygon or line will act as a part of the underlying map.'
|
|
747
|
+
),
|
|
712
748
|
outlink: L._('Define link to open in a new window on polygon click.'),
|
|
713
749
|
dynamicRemoteData: L._('Fetch data each time map view changes.'),
|
|
714
750
|
proxyRemoteData: L._("To use if remote server doesn't allow cross domain (slower)"),
|
|
@@ -372,16 +372,20 @@ L.FormBuilder.PopupContent = L.FormBuilder.Select.extend({
|
|
|
372
372
|
['Table', L._('Table')],
|
|
373
373
|
['GeoRSSImage', L._('GeoRSS (title + image)')],
|
|
374
374
|
['GeoRSSLink', L._('GeoRSS (only link)')],
|
|
375
|
+
['OSM', L._('OpenStreetMap')],
|
|
375
376
|
],
|
|
376
377
|
})
|
|
377
378
|
|
|
378
379
|
L.FormBuilder.LayerTypeChooser = L.FormBuilder.Select.extend({
|
|
379
|
-
|
|
380
|
-
[
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
380
|
+
getOptions: function () {
|
|
381
|
+
const layer_classes = [
|
|
382
|
+
L.U.Layer.Default,
|
|
383
|
+
L.U.Layer.Cluster,
|
|
384
|
+
L.U.Layer.Heat,
|
|
385
|
+
L.U.Layer.Choropleth,
|
|
386
|
+
]
|
|
387
|
+
return layer_classes.map((class_) => [class_.TYPE, class_.NAME])
|
|
388
|
+
},
|
|
385
389
|
})
|
|
386
390
|
|
|
387
391
|
L.FormBuilder.SlideshowDelay = L.FormBuilder.IntSelect.extend({
|
|
@@ -538,8 +542,8 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
|
|
538
542
|
this.footer.innerHTML = ''
|
|
539
543
|
this.buildTabs()
|
|
540
544
|
const value = this.value()
|
|
541
|
-
if (!value ||
|
|
542
|
-
else if (value.
|
|
545
|
+
if (!value || L.Util.isPath(value)) this.showSymbolsTab()
|
|
546
|
+
else if (L.Util.isRemoteUrl(value) || L.Util.isDataImage(value)) this.showURLTab()
|
|
543
547
|
else this.showCharsTab()
|
|
544
548
|
const closeButton = L.DomUtil.createButton(
|
|
545
549
|
'button action-button',
|
|
@@ -596,20 +600,6 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
|
|
596
600
|
this.body.innerHTML = ''
|
|
597
601
|
},
|
|
598
602
|
|
|
599
|
-
isPath: function () {
|
|
600
|
-
const value = this.value()
|
|
601
|
-
return value && value.length && value.startsWith('/')
|
|
602
|
-
},
|
|
603
|
-
|
|
604
|
-
isRemoteUrl: function () {
|
|
605
|
-
const value = this.value()
|
|
606
|
-
return value && value.length && value.startsWith('http')
|
|
607
|
-
},
|
|
608
|
-
|
|
609
|
-
isImg: function () {
|
|
610
|
-
return this.isPath() || this.isRemoteUrl()
|
|
611
|
-
},
|
|
612
|
-
|
|
613
603
|
updatePreview: function () {
|
|
614
604
|
this.buttons.innerHTML = ''
|
|
615
605
|
if (this.isDefault()) return
|
|
@@ -617,13 +607,7 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
|
|
617
607
|
// Do not try to render URL with variables
|
|
618
608
|
const box = L.DomUtil.create('div', 'umap-pictogram-choice', this.buttons)
|
|
619
609
|
L.DomEvent.on(box, 'click', this.onDefine, this)
|
|
620
|
-
|
|
621
|
-
const img = L.DomUtil.create('img', '', box)
|
|
622
|
-
img.src = this.value()
|
|
623
|
-
} else {
|
|
624
|
-
const el = L.DomUtil.create('span', '', box)
|
|
625
|
-
el.textContent = this.value()
|
|
626
|
-
}
|
|
610
|
+
const icon = L.U.Icon.makeIconElement(this.value(), box)
|
|
627
611
|
}
|
|
628
612
|
this.button = L.DomUtil.createButton(
|
|
629
613
|
'button action-button',
|
|
@@ -723,7 +707,7 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
|
|
723
707
|
|
|
724
708
|
showCharsTab: function () {
|
|
725
709
|
this.openTab('chars')
|
|
726
|
-
const value = !
|
|
710
|
+
const value = !L.U.Icon.isImg(this.value()) ? this.value() : null
|
|
727
711
|
const input = this.buildInput(this.body, value)
|
|
728
712
|
input.placeholder = L._('Type char or paste emoji')
|
|
729
713
|
input.type = 'text'
|
|
@@ -731,7 +715,10 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
|
|
731
715
|
|
|
732
716
|
showURLTab: function () {
|
|
733
717
|
this.openTab('url')
|
|
734
|
-
const value =
|
|
718
|
+
const value =
|
|
719
|
+
L.Util.isRemoteUrl(this.value()) || L.Util.isDataImage(this.value())
|
|
720
|
+
? this.value()
|
|
721
|
+
: null
|
|
735
722
|
const input = this.buildInput(this.body, value)
|
|
736
723
|
input.placeholder = L._('Add image URL')
|
|
737
724
|
input.type = 'url'
|