umap-project 2.4.1__py3-none-any.whl → 2.5.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.
Files changed (199) hide show
  1. umap/__init__.py +1 -1
  2. umap/locale/el/LC_MESSAGES/django.mo +0 -0
  3. umap/locale/el/LC_MESSAGES/django.po +145 -90
  4. umap/locale/en/LC_MESSAGES/django.po +13 -13
  5. umap/locale/eu/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/eu/LC_MESSAGES/django.po +145 -89
  7. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  8. umap/locale/hu/LC_MESSAGES/django.po +100 -50
  9. umap/static/umap/base.css +5 -2
  10. umap/static/umap/content.css +2 -2
  11. umap/static/umap/css/contextmenu.css +11 -0
  12. umap/static/umap/css/dialog.css +25 -4
  13. umap/static/umap/css/importers.css +2 -0
  14. umap/static/umap/css/panel.css +6 -4
  15. umap/static/umap/css/slideshow.css +69 -0
  16. umap/static/umap/css/tableeditor.css +69 -0
  17. umap/static/umap/css/tooltip.css +3 -3
  18. umap/static/umap/img/16-white.svg +4 -0
  19. umap/static/umap/img/source/16-white.svg +5 -1
  20. umap/static/umap/js/components/alerts/alert.css +11 -11
  21. umap/static/umap/js/components/alerts/alert.js +1 -1
  22. umap/static/umap/js/modules/autocomplete.js +27 -5
  23. umap/static/umap/js/modules/browser.js +20 -14
  24. umap/static/umap/js/modules/caption.js +4 -4
  25. umap/static/umap/js/modules/dompurify.js +2 -3
  26. umap/static/umap/js/modules/facets.js +53 -17
  27. umap/static/umap/js/modules/formatter.js +153 -0
  28. umap/static/umap/js/modules/global.js +25 -16
  29. umap/static/umap/js/modules/help.js +26 -26
  30. umap/static/umap/js/modules/importer.js +10 -10
  31. umap/static/umap/js/modules/importers/communesfr.js +3 -1
  32. umap/static/umap/js/modules/importers/datasets.js +8 -6
  33. umap/static/umap/js/modules/importers/geodatamine.js +14 -14
  34. umap/static/umap/js/modules/importers/overpass.js +19 -15
  35. umap/static/umap/js/modules/orderable.js +2 -2
  36. umap/static/umap/js/modules/request.js +1 -1
  37. umap/static/umap/js/modules/rules.js +26 -11
  38. umap/static/umap/js/modules/schema.js +16 -12
  39. umap/static/umap/js/{umap.share.js → modules/share.js} +58 -103
  40. umap/static/umap/js/modules/slideshow.js +141 -0
  41. umap/static/umap/js/modules/sync/engine.js +3 -3
  42. umap/static/umap/js/modules/sync/updaters.js +10 -11
  43. umap/static/umap/js/modules/sync/websocket.js +1 -1
  44. umap/static/umap/js/modules/tableeditor.js +329 -0
  45. umap/static/umap/js/modules/ui/base.js +93 -0
  46. umap/static/umap/js/modules/ui/contextmenu.js +50 -0
  47. umap/static/umap/js/modules/ui/dialog.js +169 -31
  48. umap/static/umap/js/modules/ui/panel.js +7 -5
  49. umap/static/umap/js/modules/ui/tooltip.js +7 -77
  50. umap/static/umap/js/modules/urls.js +1 -2
  51. umap/static/umap/js/modules/utils.js +36 -16
  52. umap/static/umap/js/umap.controls.js +27 -29
  53. umap/static/umap/js/umap.core.js +19 -15
  54. umap/static/umap/js/umap.datalayer.permissions.js +15 -18
  55. umap/static/umap/js/umap.features.js +113 -131
  56. umap/static/umap/js/umap.forms.js +203 -228
  57. umap/static/umap/js/umap.icon.js +17 -22
  58. umap/static/umap/js/umap.js +117 -107
  59. umap/static/umap/js/umap.layer.js +374 -324
  60. umap/static/umap/js/umap.permissions.js +7 -10
  61. umap/static/umap/js/umap.popup.js +20 -20
  62. umap/static/umap/locale/am_ET.js +22 -5
  63. umap/static/umap/locale/am_ET.json +22 -5
  64. umap/static/umap/locale/ar.js +22 -5
  65. umap/static/umap/locale/ar.json +22 -5
  66. umap/static/umap/locale/ast.js +22 -5
  67. umap/static/umap/locale/ast.json +22 -5
  68. umap/static/umap/locale/bg.js +22 -5
  69. umap/static/umap/locale/bg.json +22 -5
  70. umap/static/umap/locale/br.js +22 -5
  71. umap/static/umap/locale/br.json +22 -5
  72. umap/static/umap/locale/ca.js +56 -39
  73. umap/static/umap/locale/ca.json +56 -39
  74. umap/static/umap/locale/cs_CZ.js +22 -5
  75. umap/static/umap/locale/cs_CZ.json +22 -5
  76. umap/static/umap/locale/da.js +22 -5
  77. umap/static/umap/locale/da.json +22 -5
  78. umap/static/umap/locale/de.js +22 -5
  79. umap/static/umap/locale/de.json +22 -5
  80. umap/static/umap/locale/el.js +27 -10
  81. umap/static/umap/locale/el.json +27 -10
  82. umap/static/umap/locale/en.js +22 -6
  83. umap/static/umap/locale/en.json +22 -6
  84. umap/static/umap/locale/en_US.json +22 -5
  85. umap/static/umap/locale/es.js +22 -6
  86. umap/static/umap/locale/es.json +22 -6
  87. umap/static/umap/locale/et.js +22 -5
  88. umap/static/umap/locale/et.json +22 -5
  89. umap/static/umap/locale/eu.js +167 -150
  90. umap/static/umap/locale/eu.json +167 -150
  91. umap/static/umap/locale/fa_IR.js +22 -5
  92. umap/static/umap/locale/fa_IR.json +22 -5
  93. umap/static/umap/locale/fi.js +22 -5
  94. umap/static/umap/locale/fi.json +22 -5
  95. umap/static/umap/locale/fr.js +22 -6
  96. umap/static/umap/locale/fr.json +22 -6
  97. umap/static/umap/locale/gl.js +22 -5
  98. umap/static/umap/locale/gl.json +22 -5
  99. umap/static/umap/locale/he.js +22 -5
  100. umap/static/umap/locale/he.json +22 -5
  101. umap/static/umap/locale/hr.js +22 -5
  102. umap/static/umap/locale/hr.json +22 -5
  103. umap/static/umap/locale/hu.js +89 -72
  104. umap/static/umap/locale/hu.json +89 -72
  105. umap/static/umap/locale/id.js +22 -5
  106. umap/static/umap/locale/id.json +22 -5
  107. umap/static/umap/locale/is.js +22 -5
  108. umap/static/umap/locale/is.json +22 -5
  109. umap/static/umap/locale/it.js +22 -5
  110. umap/static/umap/locale/it.json +22 -5
  111. umap/static/umap/locale/ja.js +22 -5
  112. umap/static/umap/locale/ja.json +22 -5
  113. umap/static/umap/locale/ko.js +22 -5
  114. umap/static/umap/locale/ko.json +22 -5
  115. umap/static/umap/locale/lt.js +22 -5
  116. umap/static/umap/locale/lt.json +22 -5
  117. umap/static/umap/locale/ms.js +22 -5
  118. umap/static/umap/locale/ms.json +22 -5
  119. umap/static/umap/locale/nl.js +22 -5
  120. umap/static/umap/locale/nl.json +22 -5
  121. umap/static/umap/locale/no.js +22 -5
  122. umap/static/umap/locale/no.json +22 -5
  123. umap/static/umap/locale/pl.js +22 -5
  124. umap/static/umap/locale/pl.json +22 -5
  125. umap/static/umap/locale/pl_PL.json +22 -5
  126. umap/static/umap/locale/pt.js +22 -6
  127. umap/static/umap/locale/pt.json +22 -6
  128. umap/static/umap/locale/pt_BR.js +22 -5
  129. umap/static/umap/locale/pt_BR.json +22 -5
  130. umap/static/umap/locale/pt_PT.js +22 -5
  131. umap/static/umap/locale/pt_PT.json +22 -5
  132. umap/static/umap/locale/ro.js +22 -5
  133. umap/static/umap/locale/ro.json +22 -5
  134. umap/static/umap/locale/ru.js +22 -5
  135. umap/static/umap/locale/ru.json +22 -5
  136. umap/static/umap/locale/sk_SK.js +22 -5
  137. umap/static/umap/locale/sk_SK.json +22 -5
  138. umap/static/umap/locale/sl.js +22 -5
  139. umap/static/umap/locale/sl.json +22 -5
  140. umap/static/umap/locale/sr.js +22 -5
  141. umap/static/umap/locale/sr.json +22 -5
  142. umap/static/umap/locale/sv.js +22 -5
  143. umap/static/umap/locale/sv.json +22 -5
  144. umap/static/umap/locale/th_TH.js +22 -5
  145. umap/static/umap/locale/th_TH.json +22 -5
  146. umap/static/umap/locale/tr.js +22 -5
  147. umap/static/umap/locale/tr.json +22 -5
  148. umap/static/umap/locale/uk_UA.js +22 -5
  149. umap/static/umap/locale/uk_UA.json +22 -5
  150. umap/static/umap/locale/vi.js +22 -5
  151. umap/static/umap/locale/vi.json +22 -5
  152. umap/static/umap/locale/vi_VN.json +22 -5
  153. umap/static/umap/locale/zh.js +22 -5
  154. umap/static/umap/locale/zh.json +22 -5
  155. umap/static/umap/locale/zh_CN.json +22 -5
  156. umap/static/umap/locale/zh_TW.Big5.json +22 -5
  157. umap/static/umap/locale/zh_TW.js +22 -5
  158. umap/static/umap/locale/zh_TW.json +22 -5
  159. umap/static/umap/map.css +9 -153
  160. umap/static/umap/vars.css +15 -0
  161. umap/static/umap/vendors/dompurify/purify.es.js +5 -59
  162. umap/static/umap/vendors/dompurify/purify.es.mjs.map +1 -1
  163. umap/static/umap/vendors/formbuilder/Leaflet.FormBuilder.js +410 -428
  164. umap/static/umap/vendors/geojson-to-gpx/index.js +155 -0
  165. umap/static/umap/vendors/osmtogeojson/osmtogeojson.js +1 -2
  166. umap/static/umap/vendors/togeojson/togeojson.es.js +1109 -0
  167. umap/static/umap/vendors/togeojson/{togeojson.umd.js.map → togeojson.es.mjs.map} +1 -1
  168. umap/static/umap/vendors/tokml/tokml.es.js +895 -0
  169. umap/static/umap/vendors/tokml/tokml.es.mjs.map +1 -0
  170. umap/storage.py +6 -2
  171. umap/templates/umap/components/alerts/alert.html +3 -3
  172. umap/templates/umap/css.html +3 -0
  173. umap/templates/umap/js.html +0 -6
  174. umap/tests/fixtures/categorized_highway.geojson +1 -0
  175. umap/tests/fixtures/test_import_osm_relation.json +130 -0
  176. umap/tests/integration/conftest.py +8 -1
  177. umap/tests/integration/test_browser.py +3 -2
  178. umap/tests/integration/test_categorized_layer.py +141 -0
  179. umap/tests/integration/test_conditional_rules.py +21 -0
  180. umap/tests/integration/test_datalayer.py +9 -4
  181. umap/tests/integration/test_edit_datalayer.py +1 -0
  182. umap/tests/integration/test_edit_polygon.py +1 -1
  183. umap/tests/integration/test_export_map.py +2 -3
  184. umap/tests/integration/test_import.py +22 -0
  185. umap/tests/integration/test_map_preview.py +36 -2
  186. umap/tests/integration/test_tableeditor.py +158 -4
  187. umap/tests/integration/test_websocket_sync.py +2 -2
  188. umap/tests/test_views.py +2 -2
  189. umap/views.py +3 -2
  190. {umap_project-2.4.1.dist-info → umap_project-2.5.0.dist-info}/METADATA +8 -8
  191. {umap_project-2.4.1.dist-info → umap_project-2.5.0.dist-info}/RECORD +194 -184
  192. umap/static/umap/js/umap.slideshow.js +0 -165
  193. umap/static/umap/js/umap.tableeditor.js +0 -118
  194. umap/static/umap/vendors/togeojson/togeojson.umd.js +0 -2
  195. umap/static/umap/vendors/togpx/togpx.js +0 -547
  196. umap/static/umap/vendors/tokml/tokml.js +0 -343
  197. {umap_project-2.4.1.dist-info → umap_project-2.5.0.dist-info}/WHEEL +0 -0
  198. {umap_project-2.4.1.dist-info → umap_project-2.5.0.dist-info}/entry_points.txt +0 -0
  199. {umap_project-2.4.1.dist-info → umap_project-2.5.0.dist-info}/licenses/LICENSE +0 -0
@@ -12,12 +12,12 @@ U.Icon = L.DivIcon.extend({
12
12
  options = L.Util.extend({}, default_options, options)
13
13
  L.Icon.prototype.initialize.call(this, options)
14
14
  this.feature = this.options.feature
15
- if (this.feature && this.feature.isReadOnly()) {
15
+ if (this.feature?.isReadOnly()) {
16
16
  this.options.className += ' readonly'
17
17
  }
18
18
  },
19
19
 
20
- _setRecent: function (url) {
20
+ _setRecent: (url) => {
21
21
  if (U.Utils.hasVar(url)) return
22
22
  if (url === U.SCHEMA.iconUrl.default) return
23
23
  if (U.Icon.RECENT.indexOf(url) === -1) {
@@ -27,7 +27,7 @@ U.Icon = L.DivIcon.extend({
27
27
 
28
28
  _getIconUrl: function (name) {
29
29
  let url
30
- if (this.feature && this.feature._getIconUrl(name)) {
30
+ if (this.feature?._getIconUrl(name)) {
31
31
  url = this.feature._getIconUrl(name)
32
32
  this._setRecent(url)
33
33
  } else {
@@ -49,14 +49,10 @@ U.Icon = L.DivIcon.extend({
49
49
  return this.map.getDefaultOption('iconOpacity')
50
50
  },
51
51
 
52
- formatUrl: function (url, feature) {
53
- return U.Utils.greedyTemplate(
54
- url || '',
55
- feature ? feature.extendedProperties() : {}
56
- )
57
- },
52
+ formatUrl: (url, feature) =>
53
+ U.Utils.greedyTemplate(url || '', feature ? feature.extendedProperties() : {}),
58
54
 
59
- onAdd: function () {},
55
+ onAdd: () => {},
60
56
  })
61
57
 
62
58
  U.Icon.Default = U.Icon.extend({
@@ -74,8 +70,8 @@ U.Icon.Default = U.Icon.extend({
74
70
 
75
71
  _setIconStyles: function (img, name) {
76
72
  U.Icon.prototype._setIconStyles.call(this, img, name)
77
- const color = this._getColor(),
78
- opacity = this._getOpacity()
73
+ const color = this._getColor()
74
+ const opacity = this._getOpacity()
79
75
  this.elements.container.style.backgroundColor = color
80
76
  this.elements.arrow.style.borderTopColor = color
81
77
  this.elements.container.style.opacity = opacity
@@ -189,10 +185,10 @@ U.Icon.Cluster = L.DivIcon.extend({
189
185
  },
190
186
 
191
187
  createIcon: function () {
192
- const container = L.DomUtil.create('div', 'leaflet-marker-icon marker-cluster'),
193
- div = L.DomUtil.create('div', '', container),
194
- span = L.DomUtil.create('span', '', div),
195
- backgroundColor = this.datalayer.getColor()
188
+ const container = L.DomUtil.create('div', 'leaflet-marker-icon marker-cluster')
189
+ const div = L.DomUtil.create('div', '', container)
190
+ const span = L.DomUtil.create('span', '', div)
191
+ const backgroundColor = this.datalayer.getColor()
196
192
  span.textContent = this.cluster.getChildCount()
197
193
  div.style.backgroundColor = backgroundColor
198
194
  return container
@@ -201,18 +197,17 @@ U.Icon.Cluster = L.DivIcon.extend({
201
197
  computeTextColor: function (el) {
202
198
  let color
203
199
  const backgroundColor = this.datalayer.getColor()
204
- if (this.datalayer.options.cluster && this.datalayer.options.cluster.textColor) {
200
+ if (this.datalayer.options.cluster?.textColor) {
205
201
  color = this.datalayer.options.cluster.textColor
206
202
  }
207
203
  return color || L.DomUtil.TextColorFromBackgroundColor(el, backgroundColor)
208
204
  },
209
205
  })
210
206
 
211
- U.Icon.isImg = function (src) {
212
- return U.Utils.isPath(src) || U.Utils.isRemoteUrl(src) || U.Utils.isDataImage(src)
213
- }
207
+ U.Icon.isImg = (src) =>
208
+ U.Utils.isPath(src) || U.Utils.isRemoteUrl(src) || U.Utils.isDataImage(src)
214
209
 
215
- U.Icon.makeIconElement = function (src, parent) {
210
+ U.Icon.makeIconElement = (src, parent) => {
216
211
  let icon
217
212
  if (U.Icon.isImg(src)) {
218
213
  icon = L.DomUtil.create('img')
@@ -225,7 +220,7 @@ U.Icon.makeIconElement = function (src, parent) {
225
220
  return icon
226
221
  }
227
222
 
228
- U.Icon.setIconContrast = function (icon, parent, src, bgcolor) {
223
+ U.Icon.setIconContrast = (icon, parent, src, bgcolor) => {
229
224
  /*
230
225
  * icon: the element we'll adapt the style, it can be an image or text
231
226
  * parent: the element we'll consider to decide whether to adapt the style,
@@ -13,7 +13,7 @@ L.Map.mergeOptions({
13
13
  // we cannot rely on this because of the y is overriden by Leaflet
14
14
  // See https://github.com/Leaflet/Leaflet/pull/9201
15
15
  // And let's remove this -y when this PR is merged and released.
16
- demoTileInfos: { 's': 'a', 'z': 9, 'x': 265, 'y': 181, '-y': 181, 'r': '' },
16
+ demoTileInfos: { s: 'a', z: 9, x: 265, y: 181, '-y': 181, r: '' },
17
17
  licences: [],
18
18
  licence: '',
19
19
  enableMarkerDraw: true,
@@ -29,7 +29,7 @@ L.Map.mergeOptions({
29
29
  U.Map = L.Map.extend({
30
30
  includes: [ControlsMixin],
31
31
 
32
- initialize: function (el, geojson) {
32
+ initialize: async function (el, geojson) {
33
33
  this.sync_engine = new U.SyncEngine(this)
34
34
  this.sync = this.sync_engine.proxy(this)
35
35
  // Locale name (pt_PT, en_US…)
@@ -56,8 +56,8 @@ U.Map = L.Map.extend({
56
56
  this.urls = new U.URLs(this.options.urls)
57
57
 
58
58
  this.panel = new U.Panel(this)
59
+ this.dialog = new U.Dialog({ className: 'dark' })
59
60
  this.tooltip = new U.Tooltip(this._controlContainer)
60
- this.dialog = new U.Dialog(this._controlContainer)
61
61
  if (this.hasEditMode()) {
62
62
  this.editPanel = new U.EditPanel(this)
63
63
  this.fullPanel = new U.FullPanel(this)
@@ -83,18 +83,15 @@ U.Map = L.Map.extend({
83
83
  }
84
84
 
85
85
  let editedFeature = null
86
- const self = this
87
86
  try {
88
87
  Object.defineProperty(this, 'editedFeature', {
89
- get: function () {
90
- return editedFeature
91
- },
92
- set: function (feature) {
88
+ get: () => editedFeature,
89
+ set: (feature) => {
93
90
  if (editedFeature && editedFeature !== feature) {
94
91
  editedFeature.endEdit()
95
92
  }
96
93
  editedFeature = feature
97
- self.fire('seteditedfeature')
94
+ this.fire('seteditedfeature')
98
95
  },
99
96
  })
100
97
  } catch (e) {
@@ -102,11 +99,7 @@ U.Map = L.Map.extend({
102
99
  }
103
100
 
104
101
  // Retrocompat
105
- if (
106
- this.options.slideshow &&
107
- this.options.slideshow.delay &&
108
- this.options.slideshow.active === undefined
109
- ) {
102
+ if (this.options.slideshow?.delay && this.options.slideshow.active === undefined) {
110
103
  this.options.slideshow.active = true
111
104
  }
112
105
  if (this.options.advancedFilterKey) {
@@ -123,6 +116,8 @@ U.Map = L.Map.extend({
123
116
  // Needed for actions labels
124
117
  this.help = new U.Help(this)
125
118
 
119
+ this.formatter = new U.Formatter(this)
120
+
126
121
  this.initControls()
127
122
  // Needs locate control and hash to exist
128
123
  this.initCenter()
@@ -156,9 +151,7 @@ U.Map = L.Map.extend({
156
151
  let isDirty = false // self status
157
152
  try {
158
153
  Object.defineProperty(this, 'isDirty', {
159
- get: function () {
160
- return isDirty
161
- },
154
+ get: () => isDirty,
162
155
  set: function (status) {
163
156
  isDirty = status
164
157
  this.checkDirty()
@@ -183,20 +176,7 @@ U.Map = L.Map.extend({
183
176
  }
184
177
  this._default_extent = true
185
178
  this.options.name = L._('Untitled map')
186
- let data = L.Util.queryString('data', null)
187
- let dataUrl = L.Util.queryString('dataUrl', null)
188
- const dataFormat = L.Util.queryString('dataFormat', 'geojson')
189
- if (dataUrl) {
190
- dataUrl = decodeURIComponent(dataUrl)
191
- dataUrl = this.localizeUrl(dataUrl)
192
- dataUrl = this.proxyUrl(dataUrl)
193
- const datalayer = this.createDataLayer()
194
- datalayer.importFromUrl(dataUrl, dataFormat)
195
- } else if (data) {
196
- data = decodeURIComponent(data)
197
- const datalayer = this.createDataLayer()
198
- datalayer.importRaw(data, dataFormat)
199
- }
179
+ await this.loadDataFromQueryString()
200
180
  }
201
181
 
202
182
  this.slideshow = new U.Slideshow(this, this.options.slideshow)
@@ -207,6 +187,7 @@ U.Map = L.Map.extend({
207
187
  }
208
188
 
209
189
  this.initShortcuts()
190
+ if (!this.options.noControl) this.initCaptionBar()
210
191
  this.onceDataLoaded(this.setViewFromQueryString)
211
192
 
212
193
  window.onbeforeunload = () => (this.editEnabled && this.isDirty) || null
@@ -216,8 +197,8 @@ U.Map = L.Map.extend({
216
197
  },
217
198
 
218
199
  initSyncEngine: async function () {
219
- if (this.options.websocketEnabled == false) return
220
- if (this.options.syncEnabled != true) {
200
+ if (this.options.websocketEnabled === false) return
201
+ if (this.options.syncEnabled !== true) {
221
202
  this.sync.stop()
222
203
  } else {
223
204
  const ws_token_uri = this.urls.get('map_websocket_auth_token', {
@@ -235,9 +216,9 @@ U.Map = L.Map.extend({
235
216
  },
236
217
 
237
218
  render: function (fields) {
238
- let impacts = U.Utils.getImpactsFromSchema(fields)
219
+ const impacts = U.Utils.getImpactsFromSchema(fields)
239
220
 
240
- for (let impact of impacts) {
221
+ for (const impact of impacts) {
241
222
  switch (impact) {
242
223
  case 'ui':
243
224
  this.initCaptionBar()
@@ -274,7 +255,7 @@ U.Map = L.Map.extend({
274
255
  })
275
256
  },
276
257
 
277
- setOptionsFromQueryString: function (options) {
258
+ setOptionsFromQueryString: (options) => {
278
259
  // This is not an editable option
279
260
  L.Util.setFromQueryString(options, 'editMode')
280
261
  // FIXME retrocompat
@@ -301,9 +282,28 @@ U.Map = L.Map.extend({
301
282
  }
302
283
  },
303
284
 
304
- setViewFromQueryString: function () {
285
+ loadDataFromQueryString: async function () {
286
+ let data = L.Util.queryString('data', null)
287
+ const url = new URL(window.location.href)
288
+ const dataUrls = new URLSearchParams(url.search).getAll('dataUrl')
289
+ const dataFormat = L.Util.queryString('dataFormat', 'geojson')
290
+ if (dataUrls.length) {
291
+ for (let dataUrl of dataUrls) {
292
+ dataUrl = decodeURIComponent(dataUrl)
293
+ dataUrl = this.localizeUrl(dataUrl)
294
+ dataUrl = this.proxyUrl(dataUrl)
295
+ const datalayer = this.createDataLayer()
296
+ await datalayer.importFromUrl(dataUrl, dataFormat)
297
+ }
298
+ } else if (data) {
299
+ data = decodeURIComponent(data)
300
+ const datalayer = this.createDataLayer()
301
+ await datalayer.importRaw(data, dataFormat)
302
+ }
303
+ },
304
+
305
+ setViewFromQueryString: async function () {
305
306
  if (this.options.noControl) return
306
- this.initCaptionBar()
307
307
  if (L.Util.queryString('share')) {
308
308
  this.share.open()
309
309
  } else if (this.options.onLoadPanel === 'databrowser') {
@@ -341,7 +341,7 @@ U.Map = L.Map.extend({
341
341
 
342
342
  // Merge the given schema with the default one
343
343
  // Missing keys inside the schema are merged with the default ones.
344
- overrideSchema: function (schema) {
344
+ overrideSchema: (schema) => {
345
345
  for (const [key, extra] of Object.entries(schema)) {
346
346
  U.SCHEMA[key] = L.extend({}, U.SCHEMA[key], extra)
347
347
  }
@@ -419,9 +419,7 @@ U.Map = L.Map.extend({
419
419
  },
420
420
 
421
421
  renderControls: function () {
422
- const hasSlideshow = Boolean(
423
- this.options.slideshow && this.options.slideshow.active
424
- )
422
+ const hasSlideshow = Boolean(this.options.slideshow?.active)
425
423
  const barEnabled = this.options.captionBar || hasSlideshow
426
424
  document.body.classList.toggle('umap-caption-bar-enabled', barEnabled)
427
425
  document.body.classList.toggle('umap-slideshow-enabled', hasSlideshow)
@@ -449,7 +447,9 @@ U.Map = L.Map.extend({
449
447
  }
450
448
  })
451
449
  }
452
- let name, status, control
450
+ let name
451
+ let status
452
+ let control
453
453
  for (let i = 0; i < this.HIDDABLE_CONTROLS.length; i++) {
454
454
  name = this.HIDDABLE_CONTROLS[i]
455
455
  status = this.getOption(`${name}Control`)
@@ -470,7 +470,8 @@ U.Map = L.Map.extend({
470
470
  initDataLayers: async function (datalayers) {
471
471
  datalayers = datalayers || this.options.datalayers
472
472
  for (const options of datalayers) {
473
- this.createDataLayer(options)
473
+ // `false` to not propagate syncing elements served from uMap
474
+ this.createDataLayer(options, false)
474
475
  }
475
476
  await this.loadDataLayers()
476
477
  },
@@ -544,18 +545,16 @@ U.Map = L.Map.extend({
544
545
  initShortcuts: function () {
545
546
  const globalShortcuts = function (e) {
546
547
  if (e.key === 'Escape') {
547
- if (this.dialog.visible) {
548
- this.dialog.close()
549
- } else if (this.importer.dialog.visible) {
548
+ if (this.importer.dialog.visible) {
550
549
  this.importer.dialog.close()
551
550
  } else if (this.editEnabled && this.editTools.drawing()) {
552
551
  this.editTools.stopDrawing()
553
552
  } else if (this.measureTools.enabled()) {
554
553
  this.measureTools.stopDrawing()
555
- } else if (this.editPanel?.isOpen()) {
556
- this.editPanel?.close()
557
554
  } else if (this.fullPanel?.isOpen()) {
558
555
  this.fullPanel?.close()
556
+ } else if (this.editPanel?.isOpen()) {
557
+ this.editPanel?.close()
559
558
  } else if (this.panel.isOpen()) {
560
559
  this.panel.close()
561
560
  }
@@ -624,7 +623,7 @@ U.Map = L.Map.extend({
624
623
  initTileLayers: function () {
625
624
  this.tilelayers = []
626
625
  for (const props of this.options.tilelayers) {
627
- let layer = this.createTileLayer(props)
626
+ const layer = this.createTileLayer(props)
628
627
  this.tilelayers.push(layer)
629
628
  if (
630
629
  this.options.tilelayer &&
@@ -634,11 +633,7 @@ U.Map = L.Map.extend({
634
633
  this.options.tilelayer.attribution = props.attribution
635
634
  }
636
635
  }
637
- if (
638
- this.options.tilelayer &&
639
- this.options.tilelayer.url_template &&
640
- this.options.tilelayer.attribution
641
- ) {
636
+ if (this.options.tilelayer?.url_template && this.options.tilelayer.attribution) {
642
637
  this.customTilelayer = this.createTileLayer(this.options.tilelayer)
643
638
  this.selectTileLayer(this.customTilelayer)
644
639
  } else {
@@ -647,9 +642,7 @@ U.Map = L.Map.extend({
647
642
  if (this._controls) this._controls.tilelayers.setLayers()
648
643
  },
649
644
 
650
- createTileLayer: function (tilelayer) {
651
- return new L.TileLayer(tilelayer.url_template, tilelayer)
652
- },
645
+ createTileLayer: (tilelayer) => new L.TileLayer(tilelayer.url_template, tilelayer),
653
646
 
654
647
  selectTileLayer: function (tilelayer) {
655
648
  if (tilelayer === this.selected_tilelayer) {
@@ -663,13 +656,13 @@ U.Map = L.Map.extend({
663
656
  }
664
657
  this.selected_tilelayer = tilelayer
665
658
  if (
666
- !isNaN(this.selected_tilelayer.options.minZoom) &&
659
+ !Number.isNaN(this.selected_tilelayer.options.minZoom) &&
667
660
  this.getZoom() < this.selected_tilelayer.options.minZoom
668
661
  ) {
669
662
  this.setZoom(this.selected_tilelayer.options.minZoom)
670
663
  }
671
664
  if (
672
- !isNaN(this.selected_tilelayer.options.maxZoom) &&
665
+ !Number.isNaN(this.selected_tilelayer.options.maxZoom) &&
673
666
  this.getZoom() > this.selected_tilelayer.options.maxZoom
674
667
  ) {
675
668
  this.setZoom(this.selected_tilelayer.options.maxZoom)
@@ -756,7 +749,7 @@ U.Map = L.Map.extend({
756
749
  }
757
750
  },
758
751
 
759
- latLng: function (a, b, c) {
752
+ latLng: (a, b, c) => {
760
753
  // manage geojson case and call original method
761
754
  if (!(a instanceof L.LatLng) && a.coordinates) {
762
755
  // Guess it's a geojson
@@ -766,11 +759,16 @@ U.Map = L.Map.extend({
766
759
  },
767
760
 
768
761
  handleLimitBounds: function () {
769
- const south = parseFloat(this.options.limitBounds.south),
770
- west = parseFloat(this.options.limitBounds.west),
771
- north = parseFloat(this.options.limitBounds.north),
772
- east = parseFloat(this.options.limitBounds.east)
773
- if (!isNaN(south) && !isNaN(west) && !isNaN(north) && !isNaN(east)) {
762
+ const south = Number.parseFloat(this.options.limitBounds.south)
763
+ const west = Number.parseFloat(this.options.limitBounds.west)
764
+ const north = Number.parseFloat(this.options.limitBounds.north)
765
+ const east = Number.parseFloat(this.options.limitBounds.east)
766
+ if (
767
+ !Number.isNaN(south) &&
768
+ !Number.isNaN(west) &&
769
+ !Number.isNaN(north) &&
770
+ !Number.isNaN(east)
771
+ ) {
774
772
  const bounds = L.latLngBounds([
775
773
  [south, west],
776
774
  [north, east],
@@ -800,7 +798,7 @@ U.Map = L.Map.extend({
800
798
  return L.Map.prototype.setMaxBounds.call(this, bounds)
801
799
  },
802
800
 
803
- createDataLayer: function (options = {}, sync) {
801
+ createDataLayer: function (options = {}, sync = true) {
804
802
  options.name = options.name || `${L._('Layer')} ${this.datalayers_index.length + 1}`
805
803
  const datalayer = new U.DataLayer(this, options, sync)
806
804
 
@@ -815,9 +813,7 @@ U.Map = L.Map.extend({
815
813
  datalayer.edit()
816
814
  },
817
815
 
818
- getDefaultOption: function (option) {
819
- return U.SCHEMA[option] && U.SCHEMA[option].default
820
- },
816
+ getDefaultOption: (option) => U.SCHEMA[option]?.default,
821
817
 
822
818
  getOption: function (option, feature) {
823
819
  if (feature) {
@@ -841,11 +837,10 @@ U.Map = L.Map.extend({
841
837
  },
842
838
 
843
839
  updateTileLayers: function () {
844
- const self = this,
845
- callback = (tilelayer) => {
846
- self.options.tilelayer = tilelayer.toJSON()
847
- self.isDirty = true
848
- }
840
+ const callback = (tilelayer) => {
841
+ this.options.tilelayer = tilelayer.toJSON()
842
+ this.isDirty = true
843
+ }
849
844
  if (this._controls.tilelayersChooser)
850
845
  this._controls.tilelayersChooser.openSwitcher({
851
846
  callback: callback,
@@ -893,7 +888,7 @@ U.Map = L.Map.extend({
893
888
 
894
889
  importFromUrl: async function (uri) {
895
890
  const response = await this.request.get(uri)
896
- if (response && response.ok) {
891
+ if (response?.ok) {
897
892
  this.importRaw(await response.text())
898
893
  }
899
894
  },
@@ -911,14 +906,13 @@ U.Map = L.Map.extend({
911
906
  }
912
907
 
913
908
  if (importedData.geometry) this.options.center = this.latLng(importedData.geometry)
914
- const self = this
915
909
  importedData.layers.forEach((geojson) => {
916
910
  if (!geojson._umap_options && geojson._storage) {
917
911
  geojson._umap_options = geojson._storage
918
912
  delete geojson._storage
919
913
  }
920
914
  delete geojson._umap_options?.id // Never trust an id at this stage
921
- const dataLayer = self.createDataLayer(geojson._umap_options)
915
+ const dataLayer = this.createDataLayer(geojson._umap_options)
922
916
  dataLayer.fromUmapGeoJSON(geojson)
923
917
  })
924
918
 
@@ -936,11 +930,10 @@ U.Map = L.Map.extend({
936
930
  importFromFile: function (file) {
937
931
  const reader = new FileReader()
938
932
  reader.readAsText(file)
939
- const self = this
940
933
  reader.onload = (e) => {
941
934
  const rawData = e.target.result
942
935
  try {
943
- self.importRaw(rawData)
936
+ this.importRaw(rawData)
944
937
  } catch (e) {
945
938
  console.error('Error importing data', e)
946
939
  U.Alert.error(L._('Invalid umap data in {filename}', { filename: file.name }))
@@ -1146,7 +1139,8 @@ U.Map = L.Map.extend({
1146
1139
  // (edit and viewing)
1147
1140
  // cf https://github.com/umap-project/umap/issues/585
1148
1141
  defaultEditDataLayer: function () {
1149
- let datalayer, fallback
1142
+ let datalayer
1143
+ let fallback
1150
1144
  datalayer = this.lastUsedDataLayer
1151
1145
  if (
1152
1146
  datalayer &&
@@ -1172,7 +1166,7 @@ U.Map = L.Map.extend({
1172
1166
  },
1173
1167
 
1174
1168
  getDataLayerByUmapId: function (umap_id) {
1175
- return this.findDataLayer((d) => d.umap_id == umap_id)
1169
+ return this.findDataLayer((d) => d.umap_id === umap_id)
1176
1170
  },
1177
1171
 
1178
1172
  _editControls: function (container) {
@@ -1354,7 +1348,7 @@ U.Map = L.Map.extend({
1354
1348
  handler: 'BlurInput',
1355
1349
  helpText: `${L._('Supported scheme')}: http://{s}.domain.com/{z}/{x}/{y}.png`,
1356
1350
  placeholder: 'url',
1357
- helpText: L._('Background overlay url'),
1351
+ label: L._('Background overlay url'),
1358
1352
  type: 'url',
1359
1353
  },
1360
1354
  ],
@@ -1475,12 +1469,8 @@ U.Map = L.Map.extend({
1475
1469
  { handler: 'Switch', label: L._('Autostart when map is loaded') },
1476
1470
  ],
1477
1471
  ]
1478
- const slideshowHandler = function () {
1479
- this.slideshow.setOptions(this.options.slideshow)
1480
- }
1481
1472
  const slideshowBuilder = new U.FormBuilder(this, slideshowFields, {
1482
- callback: slideshowHandler,
1483
- callbackContext: this,
1473
+ callback: () => this.slideshow.setOptions(this.options.slideshow),
1484
1474
  })
1485
1475
  slideshow.appendChild(slideshowBuilder.build())
1486
1476
  },
@@ -1505,8 +1495,15 @@ U.Map = L.Map.extend({
1505
1495
  L.DomUtil.createButton(
1506
1496
  'button umap-empty',
1507
1497
  advancedButtons,
1508
- L._('Empty'),
1509
- this.empty,
1498
+ L._('Clear data'),
1499
+ this.emptyDataLayers,
1500
+ this
1501
+ )
1502
+ L.DomUtil.createButton(
1503
+ 'button umap-empty',
1504
+ advancedButtons,
1505
+ L._('Remove layers'),
1506
+ this.removeDataLayers,
1510
1507
  this
1511
1508
  )
1512
1509
  }
@@ -1517,13 +1514,6 @@ U.Map = L.Map.extend({
1517
1514
  this.clone,
1518
1515
  this
1519
1516
  )
1520
- L.DomUtil.createButton(
1521
- 'button umap-empty',
1522
- advancedButtons,
1523
- L._('Delete all layers'),
1524
- this.empty,
1525
- this
1526
- )
1527
1517
  L.DomUtil.createButton(
1528
1518
  'button umap-download',
1529
1519
  advancedButtons,
@@ -1611,11 +1601,11 @@ U.Map = L.Map.extend({
1611
1601
 
1612
1602
  initCaptionBar: function () {
1613
1603
  const container = L.DomUtil.create(
1614
- 'div',
1615
- 'umap-caption-bar',
1616
- this._controlContainer
1617
- ),
1618
- name = L.DomUtil.create('h3', '', container)
1604
+ 'div',
1605
+ 'umap-caption-bar',
1606
+ this._controlContainer
1607
+ )
1608
+ const name = L.DomUtil.create('h3', '', container)
1619
1609
  L.DomEvent.disableClickPropagation(container)
1620
1610
  this.permissions.addOwnerLink('span', container)
1621
1611
  if (this.getOption('captionMenus')) {
@@ -1652,9 +1642,12 @@ U.Map = L.Map.extend({
1652
1642
  },
1653
1643
 
1654
1644
  askForReset: function (e) {
1655
- if (!confirm(L._('Are you sure you want to cancel your changes?'))) return
1656
- this.reset()
1657
- this.disableEdit()
1645
+ this.dialog
1646
+ .confirm(L._('Are you sure you want to cancel your changes?'))
1647
+ .then(() => {
1648
+ this.reset()
1649
+ this.disableEdit()
1650
+ })
1658
1651
  },
1659
1652
 
1660
1653
  startMarker: function () {
@@ -1687,12 +1680,18 @@ U.Map = L.Map.extend({
1687
1680
  }
1688
1681
  },
1689
1682
 
1690
- empty: function () {
1683
+ removeDataLayers: function () {
1691
1684
  this.eachDataLayerReverse((datalayer) => {
1692
1685
  datalayer._delete()
1693
1686
  })
1694
1687
  },
1695
1688
 
1689
+ emptyDataLayers: function () {
1690
+ this.eachDataLayerReverse((datalayer) => {
1691
+ datalayer.empty()
1692
+ })
1693
+ },
1694
+
1696
1695
  initLoader: function () {
1697
1696
  this.loader = new L.Control.Loading()
1698
1697
  this.loader.onAdd(this)
@@ -1721,7 +1720,7 @@ U.Map = L.Map.extend({
1721
1720
  },
1722
1721
  })
1723
1722
  }
1724
- if (e && e.relatedTarget) {
1723
+ if (e?.relatedTarget) {
1725
1724
  if (e.relatedTarget.getContextMenuItems) {
1726
1725
  items = items.concat(e.relatedTarget.getContextMenuItems(e))
1727
1726
  }
@@ -1892,4 +1891,15 @@ U.Map = L.Map.extend({
1892
1891
  })
1893
1892
  await this.server.post(sendLink, {}, formData)
1894
1893
  },
1894
+
1895
+ allProperties: function () {
1896
+ return [].concat(...this.datalayers_index.map((dl) => dl._propertiesIndex))
1897
+ },
1898
+
1899
+ sortedValues: function (property) {
1900
+ return []
1901
+ .concat(...this.datalayers_index.map((dl) => dl.sortedValues(property)))
1902
+ .filter((val, idx, arr) => arr.indexOf(val) === idx)
1903
+ .sort(U.Utils.naturalSort)
1904
+ },
1895
1905
  })