umap-project 2.6.2__py3-none-any.whl → 2.7.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.

Files changed (211) hide show
  1. umap/__init__.py +1 -1
  2. umap/admin.py +64 -1
  3. umap/asgi.py +15 -0
  4. umap/context_processors.py +1 -0
  5. umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/cs_CZ/LC_MESSAGES/django.po +96 -92
  7. umap/locale/de/LC_MESSAGES/django.mo +0 -0
  8. umap/locale/de/LC_MESSAGES/django.po +19 -18
  9. umap/locale/en/LC_MESSAGES/django.po +47 -43
  10. umap/locale/es/LC_MESSAGES/django.mo +0 -0
  11. umap/locale/es/LC_MESSAGES/django.po +134 -128
  12. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  13. umap/locale/fr/LC_MESSAGES/django.po +51 -47
  14. umap/locale/pt/LC_MESSAGES/django.mo +0 -0
  15. umap/locale/pt/LC_MESSAGES/django.po +64 -60
  16. umap/management/commands/clean_tilelayer.py +152 -0
  17. umap/management/commands/purge_purgatory.py +28 -0
  18. umap/models.py +27 -2
  19. umap/settings/base.py +3 -1
  20. umap/static/umap/base.css +4 -4
  21. umap/static/umap/css/contextmenu.css +6 -1
  22. umap/static/umap/css/icon.css +7 -2
  23. umap/static/umap/css/importers.css +4 -0
  24. umap/static/umap/img/16-white.svg +9 -2
  25. umap/static/umap/img/16.svg +1 -181
  26. umap/static/umap/img/24-white.svg +1 -0
  27. umap/static/umap/img/24.svg +1 -0
  28. umap/static/umap/img/importers/cadastrefr.svg +23 -0
  29. umap/static/umap/img/source/16-white.svg +10 -3
  30. umap/static/umap/img/source/16.svg +753 -197
  31. umap/static/umap/img/source/24-white.svg +3 -2
  32. umap/static/umap/img/source/24.svg +3 -2
  33. umap/static/umap/js/modules/autocomplete.js +7 -3
  34. umap/static/umap/js/modules/browser.js +55 -2
  35. umap/static/umap/js/modules/caption.js +16 -5
  36. umap/static/umap/js/modules/data/features.js +183 -8
  37. umap/static/umap/js/modules/data/layer.js +57 -40
  38. umap/static/umap/js/modules/formatter.js +3 -2
  39. umap/static/umap/js/modules/global.js +2 -0
  40. umap/static/umap/js/modules/importer.js +3 -0
  41. umap/static/umap/js/modules/importers/cadastrefr.js +62 -0
  42. umap/static/umap/js/modules/importers/communesfr.js +15 -3
  43. umap/static/umap/js/modules/permissions.js +123 -93
  44. umap/static/umap/js/modules/rendering/layers/classified.js +2 -0
  45. umap/static/umap/js/modules/rendering/ui.js +60 -213
  46. umap/static/umap/js/modules/share.js +1 -3
  47. umap/static/umap/js/modules/slideshow.js +1 -1
  48. umap/static/umap/js/modules/sync/engine.js +371 -14
  49. umap/static/umap/js/modules/sync/hlc.js +106 -0
  50. umap/static/umap/js/modules/sync/updaters.js +18 -6
  51. umap/static/umap/js/modules/sync/websocket.js +1 -1
  52. umap/static/umap/js/modules/tableeditor.js +1 -1
  53. umap/static/umap/js/modules/ui/base.js +2 -2
  54. umap/static/umap/js/modules/ui/contextmenu.js +51 -18
  55. umap/static/umap/js/modules/urls.js +5 -1
  56. umap/static/umap/js/modules/utils.js +28 -4
  57. umap/static/umap/js/umap.controls.js +76 -55
  58. umap/static/umap/js/umap.core.js +3 -3
  59. umap/static/umap/js/umap.forms.js +3 -1
  60. umap/static/umap/js/umap.js +115 -124
  61. umap/static/umap/locale/am_ET.js +2 -2
  62. umap/static/umap/locale/am_ET.json +2 -2
  63. umap/static/umap/locale/ar.js +2 -2
  64. umap/static/umap/locale/ar.json +2 -2
  65. umap/static/umap/locale/ast.js +2 -2
  66. umap/static/umap/locale/ast.json +2 -2
  67. umap/static/umap/locale/bg.js +2 -2
  68. umap/static/umap/locale/bg.json +2 -2
  69. umap/static/umap/locale/br.js +13 -4
  70. umap/static/umap/locale/br.json +13 -4
  71. umap/static/umap/locale/ca.js +30 -17
  72. umap/static/umap/locale/ca.json +30 -17
  73. umap/static/umap/locale/cs_CZ.js +89 -80
  74. umap/static/umap/locale/cs_CZ.json +89 -80
  75. umap/static/umap/locale/da.js +2 -2
  76. umap/static/umap/locale/da.json +2 -2
  77. umap/static/umap/locale/de.js +17 -8
  78. umap/static/umap/locale/de.json +17 -8
  79. umap/static/umap/locale/el.js +2 -2
  80. umap/static/umap/locale/el.json +2 -2
  81. umap/static/umap/locale/en.js +15 -4
  82. umap/static/umap/locale/en.json +15 -4
  83. umap/static/umap/locale/en_US.json +2 -2
  84. umap/static/umap/locale/es.js +338 -325
  85. umap/static/umap/locale/es.json +338 -325
  86. umap/static/umap/locale/et.js +2 -2
  87. umap/static/umap/locale/et.json +2 -2
  88. umap/static/umap/locale/eu.js +11 -4
  89. umap/static/umap/locale/eu.json +11 -4
  90. umap/static/umap/locale/fa_IR.js +11 -4
  91. umap/static/umap/locale/fa_IR.json +11 -4
  92. umap/static/umap/locale/fi.js +2 -2
  93. umap/static/umap/locale/fi.json +2 -2
  94. umap/static/umap/locale/fr.js +15 -4
  95. umap/static/umap/locale/fr.json +15 -4
  96. umap/static/umap/locale/gl.js +2 -2
  97. umap/static/umap/locale/gl.json +2 -2
  98. umap/static/umap/locale/he.js +2 -2
  99. umap/static/umap/locale/he.json +2 -2
  100. umap/static/umap/locale/hr.js +2 -2
  101. umap/static/umap/locale/hr.json +2 -2
  102. umap/static/umap/locale/hu.js +12 -5
  103. umap/static/umap/locale/hu.json +12 -5
  104. umap/static/umap/locale/id.js +2 -2
  105. umap/static/umap/locale/id.json +2 -2
  106. umap/static/umap/locale/is.js +2 -2
  107. umap/static/umap/locale/is.json +2 -2
  108. umap/static/umap/locale/it.js +2 -2
  109. umap/static/umap/locale/it.json +2 -2
  110. umap/static/umap/locale/ja.js +2 -2
  111. umap/static/umap/locale/ja.json +2 -2
  112. umap/static/umap/locale/ko.js +2 -2
  113. umap/static/umap/locale/ko.json +2 -2
  114. umap/static/umap/locale/lt.js +2 -2
  115. umap/static/umap/locale/lt.json +2 -2
  116. umap/static/umap/locale/ms.js +2 -2
  117. umap/static/umap/locale/ms.json +2 -2
  118. umap/static/umap/locale/nl.js +2 -2
  119. umap/static/umap/locale/nl.json +2 -2
  120. umap/static/umap/locale/no.js +2 -2
  121. umap/static/umap/locale/no.json +2 -2
  122. umap/static/umap/locale/pl.js +2 -2
  123. umap/static/umap/locale/pl.json +2 -2
  124. umap/static/umap/locale/pl_PL.json +2 -2
  125. umap/static/umap/locale/pt.js +19 -10
  126. umap/static/umap/locale/pt.json +19 -10
  127. umap/static/umap/locale/pt_BR.js +2 -2
  128. umap/static/umap/locale/pt_BR.json +2 -2
  129. umap/static/umap/locale/pt_PT.js +13 -4
  130. umap/static/umap/locale/pt_PT.json +13 -4
  131. umap/static/umap/locale/ro.js +2 -2
  132. umap/static/umap/locale/ro.json +2 -2
  133. umap/static/umap/locale/ru.js +2 -2
  134. umap/static/umap/locale/ru.json +2 -2
  135. umap/static/umap/locale/si.js +2 -2
  136. umap/static/umap/locale/si.json +2 -2
  137. umap/static/umap/locale/sk_SK.js +2 -2
  138. umap/static/umap/locale/sk_SK.json +2 -2
  139. umap/static/umap/locale/sl.js +2 -2
  140. umap/static/umap/locale/sl.json +2 -2
  141. umap/static/umap/locale/sr.js +2 -2
  142. umap/static/umap/locale/sr.json +2 -2
  143. umap/static/umap/locale/sv.js +2 -2
  144. umap/static/umap/locale/sv.json +2 -2
  145. umap/static/umap/locale/th_TH.js +2 -2
  146. umap/static/umap/locale/th_TH.json +2 -2
  147. umap/static/umap/locale/tr.js +2 -2
  148. umap/static/umap/locale/tr.json +2 -2
  149. umap/static/umap/locale/uk_UA.js +2 -2
  150. umap/static/umap/locale/uk_UA.json +2 -2
  151. umap/static/umap/locale/vi.js +2 -2
  152. umap/static/umap/locale/vi.json +2 -2
  153. umap/static/umap/locale/vi_VN.json +2 -2
  154. umap/static/umap/locale/zh.js +2 -2
  155. umap/static/umap/locale/zh.json +2 -2
  156. umap/static/umap/locale/zh_CN.json +2 -2
  157. umap/static/umap/locale/zh_TW.Big5.json +2 -2
  158. umap/static/umap/locale/zh_TW.js +13 -4
  159. umap/static/umap/locale/zh_TW.json +13 -4
  160. umap/static/umap/map.css +44 -29
  161. umap/static/umap/unittests/hlc.js +165 -0
  162. umap/static/umap/unittests/sync.js +321 -15
  163. umap/static/umap/unittests/utils.js +47 -0
  164. umap/static/umap/vars.css +2 -1
  165. umap/static/umap/vendors/colorbrewer/colorbrewer.js +309 -317
  166. umap/static/umap/vendors/dompurify/purify.es.js +15 -16
  167. umap/static/umap/vendors/dompurify/purify.es.mjs.map +1 -1
  168. umap/static/umap/vendors/georsstogeojson/GeoRSSToGeoJSON.js +111 -80
  169. umap/static/umap/vendors/locatecontrol/L.Control.Locate.min.js +2 -2
  170. umap/static/umap/vendors/locatecontrol/L.Control.Locate.min.js.map +1 -1
  171. umap/static/umap/vendors/simple-statistics/simple-statistics.min.js +1 -1
  172. umap/static/umap/vendors/simple-statistics/simple-statistics.min.js.map +1 -1
  173. umap/templates/umap/css.html +0 -2
  174. umap/templates/umap/dashboard_menu.html +4 -2
  175. umap/templates/umap/js.html +0 -5
  176. umap/templates/umap/map_detail.html +2 -2
  177. umap/tests/fixtures/test_upload_data.csv +2 -2
  178. umap/tests/integration/test_anonymous_owned_map.py +1 -0
  179. umap/tests/integration/test_basics.py +1 -1
  180. umap/tests/integration/test_browser.py +69 -7
  181. umap/tests/integration/test_caption.py +3 -3
  182. umap/tests/integration/test_circles_layer.py +12 -0
  183. umap/tests/integration/test_cluster.py +53 -0
  184. umap/tests/integration/test_datalayer.py +2 -1
  185. umap/tests/integration/test_draw_polygon.py +17 -9
  186. umap/tests/integration/test_draw_polyline.py +84 -7
  187. umap/tests/integration/test_edit_datalayer.py +5 -8
  188. umap/tests/integration/test_edit_map.py +2 -2
  189. umap/tests/integration/test_edit_marker.py +1 -1
  190. umap/tests/integration/test_facets_browser.py +3 -3
  191. umap/tests/integration/test_import.py +1 -0
  192. umap/tests/integration/test_map.py +1 -0
  193. umap/tests/integration/test_owned_map.py +1 -1
  194. umap/tests/integration/test_view_marker.py +63 -0
  195. umap/tests/integration/test_view_polygon.py +12 -12
  196. umap/tests/integration/test_websocket_sync.py +65 -3
  197. umap/tests/test_clean_tilelayer.py +83 -0
  198. umap/tests/test_datalayer.py +24 -0
  199. umap/tests/test_map_views.py +20 -0
  200. umap/tests/test_purge_purgatory.py +25 -0
  201. umap/tests/test_websocket_server.py +22 -0
  202. umap/urls.py +5 -1
  203. umap/views.py +6 -3
  204. umap/websocket_server.py +130 -27
  205. {umap_project-2.6.2.dist-info → umap_project-2.7.0.dist-info}/METADATA +18 -14
  206. {umap_project-2.6.2.dist-info → umap_project-2.7.0.dist-info}/RECORD +209 -200
  207. umap/static/umap/vendors/contextmenu/leaflet.contextmenu.min.css +0 -1
  208. umap/static/umap/vendors/contextmenu/leaflet.contextmenu.min.js +0 -7
  209. {umap_project-2.6.2.dist-info → umap_project-2.7.0.dist-info}/WHEEL +0 -0
  210. {umap_project-2.6.2.dist-info → umap_project-2.7.0.dist-info}/entry_points.txt +0 -0
  211. {umap_project-2.6.2.dist-info → umap_project-2.7.0.dist-info}/licenses/LICENSE +0 -0
@@ -58,6 +58,7 @@ U.Map = L.Map.extend({
58
58
  this.panel = new U.Panel(this)
59
59
  this.dialog = new U.Dialog({ className: 'dark' })
60
60
  this.tooltip = new U.Tooltip(this._controlContainer)
61
+ this.contextmenu = new U.ContextMenu()
61
62
  if (this.hasEditMode()) {
62
63
  this.editPanel = new U.EditPanel(this)
63
64
  this.fullPanel = new U.FullPanel(this)
@@ -109,10 +110,9 @@ U.Map = L.Map.extend({
109
110
  delete this.options.advancedFilterKey
110
111
  }
111
112
 
112
- // Global storage for retrieving datalayers and features
113
- this.datalayers = {}
114
- this.datalayers_index = []
115
- this.dirty_datalayers = []
113
+ // Global storage for retrieving datalayers and features.
114
+ this.datalayers = {} // All datalayers, including deleted.
115
+ this.datalayers_index = [] // Datalayers actually on the map and ordered.
116
116
  this.features_index = {}
117
117
 
118
118
  // Needed for actions labels
@@ -191,14 +191,17 @@ U.Map = L.Map.extend({
191
191
  this.renderEditToolbar()
192
192
  }
193
193
 
194
- this.initShortcuts()
195
- if (!this.options.noControl) this.initCaptionBar()
196
- this.onceDataLoaded(this.setViewFromQueryString)
194
+ if (!this.options.noControl) {
195
+ this.initShortcuts()
196
+ this.initCaptionBar()
197
+ this.on('contextmenu', this.onContextMenu)
198
+ this.onceDataLoaded(this.setViewFromQueryString)
199
+ this.on('click', this.closeInplaceToolbar)
200
+ this.propagate()
201
+ }
197
202
 
198
203
  window.onbeforeunload = () => (this.editEnabled && this.isDirty) || null
199
204
  this.backup()
200
- this.initContextMenu()
201
- this.on('click', this.closeInplaceToolbar)
202
205
  },
203
206
 
204
207
  initSyncEngine: async function () {
@@ -221,8 +224,12 @@ U.Map = L.Map.extend({
221
224
  },
222
225
 
223
226
  render: function (fields) {
224
- const impacts = U.Utils.getImpactsFromSchema(fields)
227
+ if (fields.includes('numberOfConnectedPeers')) {
228
+ this.renderEditToolbar()
229
+ this.propagate()
230
+ }
225
231
 
232
+ const impacts = U.Utils.getImpactsFromSchema(fields)
226
233
  for (const impact of impacts) {
227
234
  switch (impact) {
228
235
  case 'ui':
@@ -230,6 +237,7 @@ U.Map = L.Map.extend({
230
237
  this.renderEditToolbar()
231
238
  this.renderControls()
232
239
  this.browser.redraw()
240
+ this.propagate()
233
241
  break
234
242
  case 'data':
235
243
  this.redrawVisibleDataLayers()
@@ -486,7 +494,7 @@ U.Map = L.Map.extend({
486
494
  loadDataLayers: async function () {
487
495
  this.datalayersLoaded = true
488
496
  this.fire('datalayersloaded')
489
- for (const datalayer of Object.values(this.datalayers)) {
497
+ for (const datalayer of this.datalayers_index) {
490
498
  if (datalayer.showAtLoad()) await datalayer.show()
491
499
  }
492
500
  this.dataloaded = true
@@ -724,6 +732,10 @@ U.Map = L.Map.extend({
724
732
  }
725
733
  },
726
734
 
735
+ hasLayers: function () {
736
+ return Boolean(this.datalayers_index.length)
737
+ },
738
+
727
739
  fitDataBounds: function () {
728
740
  const bounds = this.getLayersBounds()
729
741
  if (!this.hasData() || !bounds.isValid()) return false
@@ -928,6 +940,7 @@ U.Map = L.Map.extend({
928
940
  if (mustReindex) datalayer.reindex()
929
941
  datalayer.redraw()
930
942
  })
943
+ this.propagate()
931
944
  this.fire('postsync')
932
945
  this.isDirty = true
933
946
  },
@@ -991,12 +1004,12 @@ U.Map = L.Map.extend({
991
1004
  if (this.editTools) this.editTools.stopDrawing()
992
1005
  this.resetOptions()
993
1006
  this.datalayers_index = [].concat(this._datalayers_index_bk)
994
- this.dirty_datalayers.slice().forEach((datalayer) => {
1007
+ // Iter over all datalayers, including deleted if any.
1008
+ for (const datalayer of Object.values(this.datalayers)) {
995
1009
  if (datalayer.isDeleted) datalayer.connectToMap()
996
- datalayer.reset()
997
- })
1010
+ if (datalayer.isDirty) datalayer.reset()
1011
+ }
998
1012
  this.ensurePanesOrder()
999
- this.dirty_datalayers = []
1000
1013
  this.initTileLayers()
1001
1014
  this.isDirty = false
1002
1015
  this.onDataLayersChanged()
@@ -1006,25 +1019,6 @@ U.Map = L.Map.extend({
1006
1019
  this._container.classList.toggle('umap-is-dirty', this.isDirty)
1007
1020
  },
1008
1021
 
1009
- addDirtyDatalayer: function (datalayer) {
1010
- if (this.dirty_datalayers.indexOf(datalayer) === -1) {
1011
- this.dirty_datalayers.push(datalayer)
1012
- this.isDirty = true
1013
- }
1014
- },
1015
-
1016
- removeDirtyDatalayer: function (datalayer) {
1017
- if (this.dirty_datalayers.indexOf(datalayer) !== -1) {
1018
- this.dirty_datalayers.splice(this.dirty_datalayers.indexOf(datalayer), 1)
1019
- this.checkDirty()
1020
- }
1021
- },
1022
-
1023
- continueSaving: function () {
1024
- if (this.dirty_datalayers.length) this.dirty_datalayers[0].save()
1025
- else this.fire('saved')
1026
- },
1027
-
1028
1022
  exportOptions: function () {
1029
1023
  const properties = {}
1030
1024
  for (const option of Object.keys(U.SCHEMA)) {
@@ -1054,19 +1048,16 @@ U.Map = L.Map.extend({
1054
1048
  return
1055
1049
  }
1056
1050
  if (data.login_required) {
1057
- window.onLogin = () => this.saveSelf()
1051
+ window.onLogin = () => this.save()
1058
1052
  window.open(data.login_required)
1059
1053
  return
1060
1054
  }
1061
- if (data.user?.id) {
1062
- this.options.user = data.user
1063
- this.renderEditToolbar()
1064
- }
1055
+ this.options.user = data.user
1065
1056
  if (!this.options.umap_id) {
1066
1057
  this.options.umap_id = data.id
1067
1058
  this.permissions.setOptions(data.permissions)
1068
1059
  this.permissions.commit()
1069
- if (data?.permissions?.anonymous_edit_url) {
1060
+ if (data.permissions?.anonymous_edit_url) {
1070
1061
  this.once('saved', () => {
1071
1062
  U.AlertCreation.info(
1072
1063
  L._('Your map has been created with an anonymous account!'),
@@ -1099,21 +1090,44 @@ U.Map = L.Map.extend({
1099
1090
  } else {
1100
1091
  window.location = data.url
1101
1092
  }
1102
- this.permissions.save()
1093
+ return true
1103
1094
  },
1104
1095
 
1105
- save: function () {
1096
+ save: async function () {
1106
1097
  if (!this.isDirty) return
1107
1098
  if (this._default_extent) this._setCenterAndZoom()
1108
1099
  this.backup()
1109
- this.once('saved', () => {
1110
- this.isDirty = false
1111
- })
1112
1100
  if (this.options.editMode === 'advanced') {
1113
1101
  // Only save the map if the user has the rights to do so.
1114
- this.saveSelf()
1115
- } else {
1116
- this.permissions.save()
1102
+ const ok = await this.saveSelf()
1103
+ if (!ok) return
1104
+ }
1105
+ await this.permissions.save()
1106
+ // Iter over all datalayers, including deleted.
1107
+ for (const datalayer of Object.values(this.datalayers)) {
1108
+ if (datalayer.isDirty) await datalayer.save()
1109
+ }
1110
+ this.isDirty = false
1111
+ // Do a blind render for now, as we are not sure what could
1112
+ // have changed, we'll be more subtil when we'll remove the
1113
+ // save action
1114
+ this.render(['name', 'user', 'permissions'])
1115
+ this.fire('saved')
1116
+ },
1117
+
1118
+ propagate: function () {
1119
+ let els = document.querySelectorAll('.map-name')
1120
+ for (const el of els) {
1121
+ el.textContent = this.getDisplayName()
1122
+ }
1123
+ const status = this.permissions.getShareStatusDisplay()
1124
+ els = document.querySelectorAll('.share-status')
1125
+ for (const el of els) {
1126
+ if (status) {
1127
+ el.textContent = L._('Visibility: {status}', {
1128
+ status: status,
1129
+ })
1130
+ }
1117
1131
  }
1118
1132
  },
1119
1133
 
@@ -1585,7 +1599,7 @@ U.Map = L.Map.extend({
1585
1599
  'umap-caption-bar',
1586
1600
  this._controlContainer
1587
1601
  )
1588
- const name = L.DomUtil.create('h3', '', container)
1602
+ const name = L.DomUtil.create('h3', 'map-name', container)
1589
1603
  L.DomEvent.disableClickPropagation(container)
1590
1604
  this.addAuthorLink('span', container)
1591
1605
  if (this.getOption('captionMenus')) {
@@ -1611,11 +1625,6 @@ U.Map = L.Map.extend({
1611
1625
  )
1612
1626
  }
1613
1627
  }
1614
- const setName = function () {
1615
- name.textContent = this.getDisplayName()
1616
- }
1617
- L.bind(setName, this)()
1618
- this.on('postsync', L.bind(setName, this))
1619
1628
  this.onceDatalayersLoaded(function () {
1620
1629
  this.slideshow.renderToolbox(container)
1621
1630
  })
@@ -1653,13 +1662,13 @@ U.Map = L.Map.extend({
1653
1662
  },
1654
1663
 
1655
1664
  clone: async function () {
1656
- if (
1657
- confirm(L._('Are you sure you want to clone this map and all its datalayers?'))
1658
- ) {
1659
- const url = this.urls.get('map_clone', { map_id: this.options.umap_id })
1660
- const [data, response, error] = await this.server.post(url)
1661
- if (data.redirect) window.location = data.redirect
1662
- }
1665
+ this.dialog
1666
+ .confirm(L._('Are you sure you want to clone this map and all its datalayers?'))
1667
+ .then(async () => {
1668
+ const url = this.urls.get('map_clone', { map_id: this.options.umap_id })
1669
+ const [data, response, error] = await this.server.post(url)
1670
+ if (data.redirect) window.location = data.redirect
1671
+ })
1663
1672
  },
1664
1673
 
1665
1674
  removeDataLayers: function () {
@@ -1679,118 +1688,100 @@ U.Map = L.Map.extend({
1679
1688
  this.loader.onAdd(this)
1680
1689
  },
1681
1690
 
1682
- initContextMenu: function () {
1683
- this.contextmenu = new U.ContextMenu(this)
1684
- this.contextmenu.enable()
1685
- },
1686
-
1687
- setContextMenuItems: function (e) {
1688
- let items = []
1689
- if (this._zoom !== this.getMaxZoom()) {
1690
- items.push({
1691
- text: L._('Zoom in'),
1692
- callback: function () {
1693
- this.zoomIn()
1694
- },
1695
- })
1696
- }
1697
- if (this._zoom !== this.getMinZoom()) {
1698
- items.push({
1699
- text: L._('Zoom out'),
1700
- callback: function () {
1701
- this.zoomOut()
1702
- },
1703
- })
1704
- }
1705
- if (e?.relatedTarget) {
1706
- if (e.relatedTarget.getContextMenuItems) {
1707
- items = items.concat(e.relatedTarget.getContextMenuItems(e))
1708
- }
1709
- }
1691
+ getOwnContextMenuItems: function (event) {
1692
+ const items = []
1710
1693
  if (this.hasEditMode()) {
1711
- items.push('-')
1712
1694
  if (this.editEnabled) {
1713
1695
  if (!this.isDirty) {
1714
1696
  items.push({
1715
- text: this.help.displayLabel('STOP_EDIT'),
1716
- callback: this.disableEdit,
1697
+ label: this.help.displayLabel('STOP_EDIT'),
1698
+ action: () => this.disableEdit(),
1717
1699
  })
1718
1700
  }
1719
1701
  if (this.options.enableMarkerDraw) {
1720
1702
  items.push({
1721
- text: this.help.displayLabel('DRAW_MARKER'),
1722
- callback: this.startMarker,
1723
- context: this,
1703
+ label: this.help.displayLabel('DRAW_MARKER'),
1704
+ action: () => this.startMarker(event),
1724
1705
  })
1725
1706
  }
1726
1707
  if (this.options.enablePolylineDraw) {
1727
1708
  items.push({
1728
- text: this.help.displayLabel('DRAW_POLYGON'),
1729
- callback: this.startPolygon,
1730
- context: this,
1709
+ label: this.help.displayLabel('DRAW_POLYGON'),
1710
+ action: () => this.startPolygon(event),
1731
1711
  })
1732
1712
  }
1733
1713
  if (this.options.enablePolygonDraw) {
1734
1714
  items.push({
1735
- text: this.help.displayLabel('DRAW_LINE'),
1736
- callback: this.startPolyline,
1737
- context: this,
1715
+ label: this.help.displayLabel('DRAW_LINE'),
1716
+ action: () => this.startPolyline(event),
1738
1717
  })
1739
1718
  }
1740
1719
  items.push('-')
1741
1720
  items.push({
1742
- text: L._('Help'),
1743
- callback: function () {
1744
- this.help.show('edit')
1745
- },
1721
+ label: L._('Help'),
1722
+ action: () => this.help.show('edit'),
1746
1723
  })
1747
1724
  } else {
1748
1725
  items.push({
1749
- text: this.help.displayLabel('TOGGLE_EDIT'),
1750
- callback: this.enableEdit,
1726
+ label: this.help.displayLabel('TOGGLE_EDIT'),
1727
+ action: () => this.enableEdit(),
1751
1728
  })
1752
1729
  }
1753
1730
  }
1731
+ if (items.length) {
1732
+ items.push('-')
1733
+ }
1754
1734
  items.push(
1755
- '-',
1756
1735
  {
1757
- text: L._('Open browser'),
1758
- callback: () => this.openBrowser('layers'),
1736
+ label: L._('Open browser'),
1737
+ action: () => this.openBrowser('layers'),
1759
1738
  },
1760
1739
  {
1761
- text: L._('Browse data'),
1762
- callback: () => this.openBrowser('data'),
1740
+ label: L._('Browse data'),
1741
+ action: () => this.openBrowser('data'),
1763
1742
  }
1764
1743
  )
1765
1744
  if (this.options.facetKey) {
1766
1745
  items.push({
1767
- text: L._('Filter data'),
1768
- callback: () => this.openBrowser('filters'),
1746
+ label: L._('Filter data'),
1747
+ action: () => this.openBrowser('filters'),
1769
1748
  })
1770
1749
  }
1771
1750
  items.push(
1772
1751
  {
1773
- text: L._('Open caption'),
1774
- callback: this.openCaption,
1752
+ label: L._('Open caption'),
1753
+ action: () => this.openCaption(),
1775
1754
  },
1776
1755
  {
1777
- text: this.help.displayLabel('SEARCH'),
1778
- callback: this.search,
1756
+ label: this.help.displayLabel('SEARCH'),
1757
+ action: () => this.search(),
1779
1758
  }
1780
1759
  )
1760
+ return items
1761
+ },
1762
+
1763
+ getContextMenuItems: function (event) {
1764
+ const items = []
1781
1765
  if (this.options.urls.routing) {
1782
1766
  items.push('-', {
1783
- text: L._('Directions from here'),
1784
- callback: this.openExternalRouting,
1767
+ label: L._('Directions from here'),
1768
+ action: () => this.openExternalRouting(event),
1785
1769
  })
1786
1770
  }
1787
1771
  if (this.options.urls.edit_in_osm) {
1788
1772
  items.push('-', {
1789
- text: L._('Edit in OpenStreetMap'),
1790
- callback: this.editInOSM,
1773
+ label: L._('Edit in OpenStreetMap'),
1774
+ action: () => this.editInOSM(event),
1791
1775
  })
1792
1776
  }
1793
- this.options.contextmenuItems = items
1777
+ return items
1778
+ },
1779
+
1780
+ onContextMenu: function (event) {
1781
+ const items = this.getOwnContextMenuItems(event).concat(
1782
+ this.getContextMenuItems(event)
1783
+ )
1784
+ this.contextmenu.open(event.originalEvent, items)
1794
1785
  },
1795
1786
 
1796
1787
  editInOSM: function (e) {
@@ -1850,7 +1841,7 @@ U.Map = L.Map.extend({
1850
1841
 
1851
1842
  getFeatureById: function (id) {
1852
1843
  let feature
1853
- for (const datalayer of Object.values(this.datalayers)) {
1844
+ for (const datalayer of this.datalayers_index) {
1854
1845
  feature = datalayer.getFeatureById(id)
1855
1846
  if (feature) return feature
1856
1847
  }
@@ -1,6 +1,6 @@
1
1
  const locale = {
2
- " (area: {measure})": "(area: {measure})",
3
- " (length: {measure})": "(length: {measure})",
2
+ "(area: {measure})": "(area: {measure})",
3
+ "(length: {measure})": "(length: {measure})",
4
4
  "# one hash for main heading": "# አንድ ፓውንድ ምልክት ለዋናው አርእስት",
5
5
  "## two hashes for second heading": "## ሁለት ፓውንድ ምልክቶች ለንዑስ አርእስቱ",
6
6
  "### three hashes for third heading": "### ሶስት ፓውንድ ምልክቶች ለሶስተኛው ደረጃ አርእስት",
@@ -1,6 +1,6 @@
1
1
  {
2
- " (area: {measure})": "(area: {measure})",
3
- " (length: {measure})": "(length: {measure})",
2
+ "(area: {measure})": "(area: {measure})",
3
+ "(length: {measure})": "(length: {measure})",
4
4
  "# one hash for main heading": "# አንድ ፓውንድ ምልክት ለዋናው አርእስት",
5
5
  "## two hashes for second heading": "## ሁለት ፓውንድ ምልክቶች ለንዑስ አርእስቱ",
6
6
  "### three hashes for third heading": "### ሶስት ፓውንድ ምልክቶች ለሶስተኛው ደረጃ አርእስት",
@@ -1,6 +1,6 @@
1
1
  const locale = {
2
- " (area: {measure})": "(area: {measure})",
3
- " (length: {measure})": "(length: {measure})",
2
+ "(area: {measure})": "(area: {measure})",
3
+ "(length: {measure})": "(length: {measure})",
4
4
  "# one hash for main heading": "# one hash for main heading",
5
5
  "## two hashes for second heading": "## two hashes for second heading",
6
6
  "### three hashes for third heading": "### three hashes for third heading",
@@ -1,6 +1,6 @@
1
1
  {
2
- " (area: {measure})": "(area: {measure})",
3
- " (length: {measure})": "(length: {measure})",
2
+ "(area: {measure})": "(area: {measure})",
3
+ "(length: {measure})": "(length: {measure})",
4
4
  "# one hash for main heading": "# one hash for main heading",
5
5
  "## two hashes for second heading": "## two hashes for second heading",
6
6
  "### three hashes for third heading": "### three hashes for third heading",
@@ -1,6 +1,6 @@
1
1
  const locale = {
2
- " (area: {measure})": "(area: {measure})",
3
- " (length: {measure})": "(length: {measure})",
2
+ "(area: {measure})": "(area: {measure})",
3
+ "(length: {measure})": "(length: {measure})",
4
4
  "# one hash for main heading": "# one hash for main heading",
5
5
  "## two hashes for second heading": "## two hashes for second heading",
6
6
  "### three hashes for third heading": "### three hashes for third heading",
@@ -1,6 +1,6 @@
1
1
  {
2
- " (area: {measure})": "(area: {measure})",
3
- " (length: {measure})": "(length: {measure})",
2
+ "(area: {measure})": "(area: {measure})",
3
+ "(length: {measure})": "(length: {measure})",
4
4
  "# one hash for main heading": "# one hash for main heading",
5
5
  "## two hashes for second heading": "## two hashes for second heading",
6
6
  "### three hashes for third heading": "### three hashes for third heading",
@@ -1,6 +1,6 @@
1
1
  const locale = {
2
- " (area: {measure})": "(area: {measure})",
3
- " (length: {measure})": "(length: {measure})",
2
+ "(area: {measure})": "(area: {measure})",
3
+ "(length: {measure})": "(length: {measure})",
4
4
  "# one hash for main heading": "# един хеш за главната позиция",
5
5
  "## two hashes for second heading": "два хеша за втората таблица",
6
6
  "### three hashes for third heading": "# # # Три хеша за трета позиция",
@@ -1,6 +1,6 @@
1
1
  {
2
- " (area: {measure})": "(area: {measure})",
3
- " (length: {measure})": "(length: {measure})",
2
+ "(area: {measure})": "(area: {measure})",
3
+ "(length: {measure})": "(length: {measure})",
4
4
  "# one hash for main heading": "# един хеш за главната позиция",
5
5
  "## two hashes for second heading": "два хеша за втората таблица",
6
6
  "### three hashes for third heading": "# # # Три хеша за трета позиция",
@@ -1,6 +1,6 @@
1
1
  const locale = {
2
- " (area: {measure})": "(gorread: {measure})",
3
- " (length: {measure})": "(pellder: {measure})",
2
+ "(area: {measure})": "(area: {measure})",
3
+ "(length: {measure})": "(length: {measure})",
4
4
  "# one hash for main heading": "# un diezenn evit an titl pennañ",
5
5
  "## two hashes for second heading": "## div ziezenn evit an eil titl",
6
6
  "### three hashes for third heading": "### teir diezenn evit an trede titl",
@@ -477,7 +477,6 @@ const locale = {
477
477
  "Search area": "Search area",
478
478
  "Type area name, or let empty to load data in current map view": "Type area name, or let empty to load data in current map view",
479
479
  "Data successfully imported!": "Roadennoù enporzhiet gant berzh!",
480
- "My Dashboard ({username})": "Ma Zaolenn-vourzh ({username})",
481
480
  "Clear data": "Skarzhañ ar roadennoù",
482
481
  "Remove layers": "Lemel ar gwiskadoù",
483
482
  "Categorized": "Dre rummad",
@@ -504,7 +503,17 @@ const locale = {
504
503
  "Property name to compute circles": "Property name to compute circles",
505
504
  "Min circle radius": "Min circle radius",
506
505
  "Max circle radius": "Max circle radius",
507
- "Display the open browser control": "Display the open browser control"
506
+ "Display the open browser control": "Display the open browser control",
507
+ "Copy as GeoJSON": "Copy as GeoJSON",
508
+ "Please zoom in to edit the geometry": "Please zoom in to edit the geometry",
509
+ "New map": "New map",
510
+ "My maps": "My maps",
511
+ "My teams": "My teams",
512
+ "My profile": "My profile",
513
+ "Type new owner's username": "Type new owner's username",
514
+ "Type editor's username": "Type editor's username",
515
+ "Map": "Map",
516
+ "Manage collaborators": "Manage collaborators"
508
517
  }
509
518
  L.registerLocale("br", locale)
510
519
  L.setLocale("br")
@@ -1,6 +1,6 @@
1
1
  {
2
- " (area: {measure})": "(gorread: {measure})",
3
- " (length: {measure})": "(pellder: {measure})",
2
+ "(area: {measure})": "(area: {measure})",
3
+ "(length: {measure})": "(length: {measure})",
4
4
  "# one hash for main heading": "# un diezenn evit an titl pennañ",
5
5
  "## two hashes for second heading": "## div ziezenn evit an eil titl",
6
6
  "### three hashes for third heading": "### teir diezenn evit an trede titl",
@@ -477,7 +477,6 @@
477
477
  "Search area": "Search area",
478
478
  "Type area name, or let empty to load data in current map view": "Type area name, or let empty to load data in current map view",
479
479
  "Data successfully imported!": "Roadennoù enporzhiet gant berzh!",
480
- "My Dashboard ({username})": "Ma Zaolenn-vourzh ({username})",
481
480
  "Clear data": "Skarzhañ ar roadennoù",
482
481
  "Remove layers": "Lemel ar gwiskadoù",
483
482
  "Categorized": "Dre rummad",
@@ -504,5 +503,15 @@
504
503
  "Property name to compute circles": "Property name to compute circles",
505
504
  "Min circle radius": "Min circle radius",
506
505
  "Max circle radius": "Max circle radius",
507
- "Display the open browser control": "Display the open browser control"
506
+ "Display the open browser control": "Display the open browser control",
507
+ "Copy as GeoJSON": "Copy as GeoJSON",
508
+ "Please zoom in to edit the geometry": "Please zoom in to edit the geometry",
509
+ "New map": "New map",
510
+ "My maps": "My maps",
511
+ "My teams": "My teams",
512
+ "My profile": "My profile",
513
+ "Type new owner's username": "Type new owner's username",
514
+ "Type editor's username": "Type editor's username",
515
+ "Map": "Map",
516
+ "Manage collaborators": "Manage collaborators"
508
517
  }