umap-project 2.7.2__py3-none-any.whl → 2.8.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (293) hide show
  1. umap/__init__.py +1 -1
  2. umap/forms.py +4 -14
  3. umap/locale/am_ET/LC_MESSAGES/django.mo +0 -0
  4. umap/locale/am_ET/LC_MESSAGES/django.po +278 -151
  5. umap/locale/ar/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/ar/LC_MESSAGES/django.po +335 -141
  7. umap/locale/bg/LC_MESSAGES/django.mo +0 -0
  8. umap/locale/bg/LC_MESSAGES/django.po +279 -152
  9. umap/locale/br/LC_MESSAGES/django.mo +0 -0
  10. umap/locale/br/LC_MESSAGES/django.po +95 -79
  11. umap/locale/ca/LC_MESSAGES/django.mo +0 -0
  12. umap/locale/ca/LC_MESSAGES/django.po +85 -68
  13. umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
  14. umap/locale/cs_CZ/LC_MESSAGES/django.po +78 -66
  15. umap/locale/da/LC_MESSAGES/django.mo +0 -0
  16. umap/locale/da/LC_MESSAGES/django.po +280 -153
  17. umap/locale/de/LC_MESSAGES/django.mo +0 -0
  18. umap/locale/de/LC_MESSAGES/django.po +80 -64
  19. umap/locale/el/LC_MESSAGES/django.mo +0 -0
  20. umap/locale/el/LC_MESSAGES/django.po +82 -66
  21. umap/locale/en/LC_MESSAGES/django.po +73 -61
  22. umap/locale/es/LC_MESSAGES/django.mo +0 -0
  23. umap/locale/es/LC_MESSAGES/django.po +75 -63
  24. umap/locale/et/LC_MESSAGES/django.mo +0 -0
  25. umap/locale/et/LC_MESSAGES/django.po +280 -153
  26. umap/locale/eu/LC_MESSAGES/django.mo +0 -0
  27. umap/locale/eu/LC_MESSAGES/django.po +82 -66
  28. umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
  29. umap/locale/fa_IR/LC_MESSAGES/django.po +80 -64
  30. umap/locale/fi/LC_MESSAGES/django.mo +0 -0
  31. umap/locale/fi/LC_MESSAGES/django.po +278 -151
  32. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  33. umap/locale/fr/LC_MESSAGES/django.po +75 -63
  34. umap/locale/gl/LC_MESSAGES/django.mo +0 -0
  35. umap/locale/gl/LC_MESSAGES/django.po +280 -153
  36. umap/locale/he/LC_MESSAGES/django.mo +0 -0
  37. umap/locale/he/LC_MESSAGES/django.po +281 -154
  38. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  39. umap/locale/hu/LC_MESSAGES/django.po +80 -64
  40. umap/locale/is/LC_MESSAGES/django.mo +0 -0
  41. umap/locale/is/LC_MESSAGES/django.po +280 -153
  42. umap/locale/it/LC_MESSAGES/django.mo +0 -0
  43. umap/locale/it/LC_MESSAGES/django.po +82 -66
  44. umap/locale/ja/LC_MESSAGES/django.mo +0 -0
  45. umap/locale/ja/LC_MESSAGES/django.po +280 -153
  46. umap/locale/ko/LC_MESSAGES/django.mo +0 -0
  47. umap/locale/ko/LC_MESSAGES/django.po +280 -153
  48. umap/locale/lt/LC_MESSAGES/django.mo +0 -0
  49. umap/locale/lt/LC_MESSAGES/django.po +280 -153
  50. umap/locale/ms/LC_MESSAGES/django.mo +0 -0
  51. umap/locale/ms/LC_MESSAGES/django.po +82 -66
  52. umap/locale/nl/LC_MESSAGES/django.mo +0 -0
  53. umap/locale/nl/LC_MESSAGES/django.po +280 -153
  54. umap/locale/pl/LC_MESSAGES/django.mo +0 -0
  55. umap/locale/pl/LC_MESSAGES/django.po +82 -66
  56. umap/locale/pt/LC_MESSAGES/django.mo +0 -0
  57. umap/locale/pt/LC_MESSAGES/django.po +75 -63
  58. umap/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
  59. umap/locale/pt_BR/LC_MESSAGES/django.po +280 -153
  60. umap/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
  61. umap/locale/pt_PT/LC_MESSAGES/django.po +280 -153
  62. umap/locale/ru/LC_MESSAGES/django.mo +0 -0
  63. umap/locale/ru/LC_MESSAGES/django.po +280 -153
  64. umap/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  65. umap/locale/sk_SK/LC_MESSAGES/django.po +280 -153
  66. umap/locale/sl/LC_MESSAGES/django.mo +0 -0
  67. umap/locale/sl/LC_MESSAGES/django.po +280 -153
  68. umap/locale/sr/LC_MESSAGES/django.mo +0 -0
  69. umap/locale/sr/LC_MESSAGES/django.po +280 -153
  70. umap/locale/sv/LC_MESSAGES/django.mo +0 -0
  71. umap/locale/sv/LC_MESSAGES/django.po +81 -65
  72. umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
  73. umap/locale/th_TH/LC_MESSAGES/django.po +257 -185
  74. umap/locale/tr/LC_MESSAGES/django.mo +0 -0
  75. umap/locale/tr/LC_MESSAGES/django.po +280 -153
  76. umap/locale/uk_UA/LC_MESSAGES/django.mo +0 -0
  77. umap/locale/uk_UA/LC_MESSAGES/django.po +280 -153
  78. umap/locale/vi/LC_MESSAGES/django.mo +0 -0
  79. umap/locale/vi/LC_MESSAGES/django.po +278 -151
  80. umap/locale/zh/LC_MESSAGES/django.mo +0 -0
  81. umap/locale/zh/LC_MESSAGES/django.po +278 -151
  82. umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
  83. umap/locale/zh_TW/LC_MESSAGES/django.po +97 -81
  84. umap/management/commands/empty_trash.py +35 -0
  85. umap/management/commands/migrate_to_S3.py +29 -0
  86. umap/migrations/0023_alter_datalayer_uuid.py +19 -0
  87. umap/migrations/0024_alter_map_share_status.py +30 -0
  88. umap/migrations/0025_alter_datalayer_geojson.py +24 -0
  89. umap/models.py +68 -116
  90. umap/settings/base.py +23 -3
  91. umap/settings/local_s3.py +45 -0
  92. umap/static/umap/base.css +3 -603
  93. umap/static/umap/content.css +5 -3
  94. umap/static/umap/css/bar.css +202 -0
  95. umap/static/umap/css/form.css +620 -0
  96. umap/static/umap/css/icon.css +21 -1
  97. umap/static/umap/css/popup.css +125 -0
  98. umap/static/umap/img/16-white.svg +16 -4
  99. umap/static/umap/img/16.svg +1 -1
  100. umap/static/umap/img/source/16-white.svg +46 -45
  101. umap/static/umap/img/source/16.svg +1 -753
  102. umap/static/umap/js/components/fragment.js +3 -1
  103. umap/static/umap/js/modules/browser.js +20 -19
  104. umap/static/umap/js/modules/caption.js +21 -22
  105. umap/static/umap/js/modules/data/features.js +120 -78
  106. umap/static/umap/js/modules/data/layer.js +195 -153
  107. umap/static/umap/js/modules/facets.js +9 -9
  108. umap/static/umap/js/modules/formatter.js +5 -5
  109. umap/static/umap/js/modules/global.js +4 -52
  110. umap/static/umap/js/modules/help.js +18 -21
  111. umap/static/umap/js/modules/importer.js +133 -56
  112. umap/static/umap/js/modules/importers/cadastrefr.js +4 -0
  113. umap/static/umap/js/modules/importers/geodatamine.js +3 -3
  114. umap/static/umap/js/modules/importers/overpass.js +5 -0
  115. umap/static/umap/js/modules/permissions.js +85 -87
  116. umap/static/umap/js/modules/rendering/icon.js +2 -1
  117. umap/static/umap/js/modules/rendering/layers/base.js +15 -15
  118. umap/static/umap/js/modules/rendering/layers/classified.js +1 -1
  119. umap/static/umap/js/modules/rendering/layers/cluster.js +1 -1
  120. umap/static/umap/js/modules/rendering/layers/heat.js +1 -1
  121. umap/static/umap/js/modules/rendering/map.js +390 -0
  122. umap/static/umap/js/modules/rendering/popup.js +19 -19
  123. umap/static/umap/js/modules/rendering/template.js +88 -21
  124. umap/static/umap/js/modules/rendering/ui.js +63 -14
  125. umap/static/umap/js/modules/request.js +2 -2
  126. umap/static/umap/js/modules/rules.js +22 -25
  127. umap/static/umap/js/modules/saving.js +47 -0
  128. umap/static/umap/js/modules/schema.js +6 -0
  129. umap/static/umap/js/modules/share.js +21 -24
  130. umap/static/umap/js/modules/slideshow.js +24 -20
  131. umap/static/umap/js/modules/sync/updaters.js +7 -9
  132. umap/static/umap/js/modules/tableeditor.js +20 -19
  133. umap/static/umap/js/modules/ui/bar.js +196 -0
  134. umap/static/umap/js/modules/ui/dialog.js +6 -1
  135. umap/static/umap/js/modules/ui/panel.js +10 -9
  136. umap/static/umap/js/modules/umap.js +1691 -0
  137. umap/static/umap/js/modules/urls.js +2 -2
  138. umap/static/umap/js/modules/utils.js +22 -6
  139. umap/static/umap/js/umap.controls.js +81 -305
  140. umap/static/umap/js/umap.core.js +29 -50
  141. umap/static/umap/js/umap.forms.js +78 -27
  142. umap/static/umap/keycloak.png +0 -0
  143. umap/static/umap/locale/am_ET.js +26 -10
  144. umap/static/umap/locale/am_ET.json +26 -10
  145. umap/static/umap/locale/ar.js +26 -10
  146. umap/static/umap/locale/ar.json +26 -10
  147. umap/static/umap/locale/ast.js +26 -10
  148. umap/static/umap/locale/ast.json +26 -10
  149. umap/static/umap/locale/bg.js +26 -10
  150. umap/static/umap/locale/bg.json +26 -10
  151. umap/static/umap/locale/br.js +27 -20
  152. umap/static/umap/locale/br.json +27 -20
  153. umap/static/umap/locale/ca.js +32 -29
  154. umap/static/umap/locale/ca.json +32 -29
  155. umap/static/umap/locale/cs_CZ.js +24 -17
  156. umap/static/umap/locale/cs_CZ.json +24 -17
  157. umap/static/umap/locale/da.js +26 -10
  158. umap/static/umap/locale/da.json +26 -10
  159. umap/static/umap/locale/de.js +21 -14
  160. umap/static/umap/locale/de.json +21 -14
  161. umap/static/umap/locale/el.js +28 -12
  162. umap/static/umap/locale/el.json +28 -12
  163. umap/static/umap/locale/en.js +14 -9
  164. umap/static/umap/locale/en.json +14 -9
  165. umap/static/umap/locale/en_US.json +26 -10
  166. umap/static/umap/locale/es.js +16 -13
  167. umap/static/umap/locale/es.json +16 -13
  168. umap/static/umap/locale/et.js +26 -10
  169. umap/static/umap/locale/et.json +26 -10
  170. umap/static/umap/locale/eu.js +16 -9
  171. umap/static/umap/locale/eu.json +16 -9
  172. umap/static/umap/locale/fa_IR.js +16 -9
  173. umap/static/umap/locale/fa_IR.json +16 -9
  174. umap/static/umap/locale/fi.js +26 -10
  175. umap/static/umap/locale/fi.json +26 -10
  176. umap/static/umap/locale/fr.js +14 -9
  177. umap/static/umap/locale/fr.json +14 -9
  178. umap/static/umap/locale/gl.js +26 -10
  179. umap/static/umap/locale/gl.json +26 -10
  180. umap/static/umap/locale/he.js +26 -10
  181. umap/static/umap/locale/he.json +26 -10
  182. umap/static/umap/locale/hr.js +26 -10
  183. umap/static/umap/locale/hr.json +26 -10
  184. umap/static/umap/locale/hu.js +16 -9
  185. umap/static/umap/locale/hu.json +16 -9
  186. umap/static/umap/locale/id.js +26 -10
  187. umap/static/umap/locale/id.json +26 -10
  188. umap/static/umap/locale/is.js +26 -10
  189. umap/static/umap/locale/is.json +26 -10
  190. umap/static/umap/locale/it.js +26 -10
  191. umap/static/umap/locale/it.json +26 -10
  192. umap/static/umap/locale/ja.js +26 -10
  193. umap/static/umap/locale/ja.json +26 -10
  194. umap/static/umap/locale/ko.js +26 -10
  195. umap/static/umap/locale/ko.json +26 -10
  196. umap/static/umap/locale/lt.js +26 -10
  197. umap/static/umap/locale/lt.json +26 -10
  198. umap/static/umap/locale/ms.js +28 -12
  199. umap/static/umap/locale/ms.json +28 -12
  200. umap/static/umap/locale/nl.js +28 -12
  201. umap/static/umap/locale/nl.json +28 -12
  202. umap/static/umap/locale/no.js +26 -10
  203. umap/static/umap/locale/no.json +26 -10
  204. umap/static/umap/locale/pl.js +28 -12
  205. umap/static/umap/locale/pl.json +28 -12
  206. umap/static/umap/locale/pl_PL.json +26 -10
  207. umap/static/umap/locale/pt.js +16 -9
  208. umap/static/umap/locale/pt.json +16 -9
  209. umap/static/umap/locale/pt_BR.js +26 -10
  210. umap/static/umap/locale/pt_BR.json +26 -10
  211. umap/static/umap/locale/pt_PT.js +16 -9
  212. umap/static/umap/locale/pt_PT.json +16 -9
  213. umap/static/umap/locale/ro.js +26 -10
  214. umap/static/umap/locale/ro.json +26 -10
  215. umap/static/umap/locale/ru.js +26 -10
  216. umap/static/umap/locale/ru.json +26 -10
  217. umap/static/umap/locale/si.js +7 -7
  218. umap/static/umap/locale/si.json +7 -7
  219. umap/static/umap/locale/sk_SK.js +26 -10
  220. umap/static/umap/locale/sk_SK.json +26 -10
  221. umap/static/umap/locale/sl.js +26 -10
  222. umap/static/umap/locale/sl.json +26 -10
  223. umap/static/umap/locale/sr.js +26 -10
  224. umap/static/umap/locale/sr.json +26 -10
  225. umap/static/umap/locale/sv.js +27 -11
  226. umap/static/umap/locale/sv.json +27 -11
  227. umap/static/umap/locale/th_TH.js +28 -12
  228. umap/static/umap/locale/th_TH.json +28 -12
  229. umap/static/umap/locale/tr.js +26 -10
  230. umap/static/umap/locale/tr.json +26 -10
  231. umap/static/umap/locale/uk_UA.js +26 -10
  232. umap/static/umap/locale/uk_UA.json +26 -10
  233. umap/static/umap/locale/vi.js +26 -10
  234. umap/static/umap/locale/vi.json +26 -10
  235. umap/static/umap/locale/vi_VN.json +26 -10
  236. umap/static/umap/locale/zh.js +26 -10
  237. umap/static/umap/locale/zh.json +26 -10
  238. umap/static/umap/locale/zh_CN.json +26 -10
  239. umap/static/umap/locale/zh_TW.Big5.json +26 -10
  240. umap/static/umap/locale/zh_TW.js +34 -27
  241. umap/static/umap/locale/zh_TW.json +34 -27
  242. umap/static/umap/map.css +39 -530
  243. umap/static/umap/unittests/URLs.js +15 -15
  244. umap/static/umap/unittests/utils.js +23 -1
  245. umap/static/umap/vars.css +2 -1
  246. umap/static/umap/vendors/formbuilder/Leaflet.FormBuilder.js +5 -1
  247. umap/storage/__init__.py +3 -0
  248. umap/storage/fs.py +101 -0
  249. umap/storage/s3.py +61 -0
  250. umap/templates/base.html +2 -0
  251. umap/templates/registration/login.html +7 -6
  252. umap/templates/umap/components/alerts/alert.html +4 -0
  253. umap/templates/umap/css.html +6 -0
  254. umap/templates/umap/js.html +3 -2
  255. umap/templates/umap/map_init.html +6 -5
  256. umap/templates/umap/user_dashboard.html +20 -19
  257. umap/tests/base.py +11 -1
  258. umap/tests/fixtures/empty_tile.png +0 -0
  259. umap/tests/fixtures/test_upload_simple_marker.json +19 -0
  260. umap/tests/integration/conftest.py +4 -1
  261. umap/tests/integration/test_anonymous_owned_map.py +18 -10
  262. umap/tests/integration/test_browser.py +16 -1
  263. umap/tests/integration/test_dashboard.py +1 -1
  264. umap/tests/integration/test_edit_datalayer.py +29 -7
  265. umap/tests/integration/test_import.py +28 -4
  266. umap/tests/integration/test_optimistic_merge.py +31 -8
  267. umap/tests/integration/test_owned_map.py +22 -16
  268. umap/tests/integration/test_popup.py +44 -0
  269. umap/tests/integration/test_save.py +35 -0
  270. umap/tests/integration/test_view_marker.py +12 -0
  271. umap/tests/integration/test_view_polyline.py +257 -0
  272. umap/tests/integration/test_websocket_sync.py +81 -9
  273. umap/tests/test_dashboard.py +82 -0
  274. umap/tests/test_datalayer.py +6 -7
  275. umap/tests/test_datalayer_s3.py +135 -0
  276. umap/tests/test_datalayer_views.py +28 -10
  277. umap/tests/test_empty_trash.py +34 -0
  278. umap/tests/test_map.py +12 -3
  279. umap/tests/test_map_views.py +69 -37
  280. umap/tests/test_statics.py +1 -1
  281. umap/tests/test_team_views.py +35 -1
  282. umap/tests/test_views.py +31 -52
  283. umap/urls.py +3 -3
  284. umap/views.py +126 -90
  285. {umap_project-2.7.2.dist-info → umap_project-2.8.0.dist-info}/METADATA +16 -14
  286. {umap_project-2.7.2.dist-info → umap_project-2.8.0.dist-info}/RECORD +290 -269
  287. {umap_project-2.7.2.dist-info → umap_project-2.8.0.dist-info}/WHEEL +1 -1
  288. umap/management/commands/purge_purgatory.py +0 -28
  289. umap/static/umap/js/umap.js +0 -1903
  290. umap/tests/test_purge_purgatory.py +0 -25
  291. /umap/{storage.py → storage/staticfiles.py} +0 -0
  292. {umap_project-2.7.2.dist-info → umap_project-2.8.0.dist-info}/entry_points.txt +0 -0
  293. {umap_project-2.7.2.dist-info → umap_project-2.8.0.dist-info}/licenses/LICENSE +0 -0
@@ -52,7 +52,7 @@ const FeatureMixin = {
52
52
  onClick: function (event) {
53
53
  if (this._map.measureTools?.enabled()) return
54
54
  this._popupHandlersAdded = true // Prevent leaflet from managing event
55
- if (!this._map.editEnabled) {
55
+ if (!this._map._umap.editEnabled) {
56
56
  this.feature.view(event)
57
57
  } else if (!this.feature.isReadOnly()) {
58
58
  if (event.originalEvent.shiftKey) {
@@ -75,7 +75,7 @@ const FeatureMixin = {
75
75
 
76
76
  resetTooltip: function () {
77
77
  if (!this.feature.hasGeom()) return
78
- const displayName = this.feature.getDisplayName(null)
78
+ const displayName = this.feature.getDisplayName()
79
79
  let showLabel = this.feature.getOption('showLabel')
80
80
  const oldLabelHover = this.feature.getOption('labelHover')
81
81
 
@@ -96,8 +96,8 @@ const FeatureMixin = {
96
96
  DomEvent.stop(event)
97
97
  const items = this.feature
98
98
  .getContextMenuItems(event)
99
- .concat(this._map.getContextMenuItems(event))
100
- this._map.contextmenu.open(event.originalEvent, items)
99
+ .concat(this._map._umap.getSharedContextMenuItems(event))
100
+ this._map._umap.contextmenu.open(event.originalEvent, items)
101
101
  },
102
102
 
103
103
  onCommit: function () {
@@ -134,7 +134,7 @@ const PointMixin = {
134
134
 
135
135
  _enableDragging: function () {
136
136
  // TODO: start dragging after 1 second on mouse down
137
- if (this._map.editEnabled) {
137
+ if (this._map._umap.editEnabled) {
138
138
  if (!this.editEnabled()) this.enableEdit()
139
139
  // Enabling dragging on the marker override the Draggable._OnDown
140
140
  // event, which, as it stopPropagation, refrain the call of
@@ -146,7 +146,7 @@ const PointMixin = {
146
146
  },
147
147
 
148
148
  _disableDragging: function () {
149
- if (this._map.editEnabled) {
149
+ if (this._map._umap.editEnabled) {
150
150
  if (this.editor?.drawing) return // when creating a new marker, the mouse can trigger the mouseover/mouseout event
151
151
  // do not listen to them
152
152
  this.disableEdit()
@@ -238,11 +238,15 @@ export const LeafletMarker = Marker.extend({
238
238
  },
239
239
 
240
240
  highlight: function () {
241
- DomUtil.addClass(this.options.icon.elements.main, 'umap-icon-active')
241
+ this.feature.activate()
242
+ this._redraw()
243
+ this._bringToFront()
242
244
  },
243
245
 
244
246
  resetHighlight: function () {
245
- DomUtil.removeClass(this.options.icon.elements.main, 'umap-icon-active')
247
+ this.feature.deactivate()
248
+ this._redraw()
249
+ this._resetZIndex()
246
250
  },
247
251
 
248
252
  getPopupToolbarAnchor: function () {
@@ -253,21 +257,26 @@ export const LeafletMarker = Marker.extend({
253
257
  const PathMixin = {
254
258
  _onMouseOver: function () {
255
259
  if (this._map.measureTools?.enabled()) {
256
- this._map.tooltip.open({ content: this.getMeasure(), anchor: this })
257
- } else if (this._map.editEnabled && !this._map.editedFeature) {
258
- this._map.tooltip.open({ content: translate('Click to edit'), anchor: this })
260
+ this._map._umap.tooltip.open({ content: this.getMeasure(), anchor: this })
261
+ } else if (this._map._umap.editEnabled && !this._map._umap.editedFeature) {
262
+ this._map._umap.tooltip.open({
263
+ content: translate('Click to edit'),
264
+ anchor: this,
265
+ })
259
266
  }
260
267
  },
261
268
 
262
269
  makeGeometryEditable: function () {
263
- if (this._map.editedFeature !== this.feature) {
270
+ if (this._map._umap.editedFeature !== this.feature) {
264
271
  this.disableEdit()
265
272
  return
266
273
  }
267
274
  this._map.once('moveend', this.makeGeometryEditable, this)
268
275
  const pointsCount = this._parts.reduce((acc, part) => acc + part.length, 0)
269
276
  if (pointsCount > 100 && this._map.getZoom() < this._map.getMaxZoom()) {
270
- this._map.tooltip.open({ content: L._('Please zoom in to edit the geometry') })
277
+ this._map._umap.tooltip.open({
278
+ content: L._('Please zoom in to edit the geometry'),
279
+ })
271
280
  this.disableEdit()
272
281
  } else {
273
282
  this.enableEdit()
@@ -380,10 +389,50 @@ export const LeafletPolyline = Polyline.extend({
380
389
  },
381
390
 
382
391
  getMeasure: function (shape) {
392
+ let shapes
393
+ if (shape) {
394
+ shapes = [shape]
395
+ } else if (LineUtil.isFlat(this._latlngs)) {
396
+ shapes = [this._latlngs]
397
+ } else {
398
+ shapes = this._latlngs
399
+ }
383
400
  // FIXME: compute from data in feature (with TurfJS)
384
- const length = L.GeoUtil.lineLength(this._map, shape || this._defaultShape())
401
+ const length = shapes.reduce(
402
+ (acc, shape) => acc + L.GeoUtil.lineLength(this._map, shape),
403
+ 0
404
+ )
385
405
  return L.GeoUtil.readableDistance(length, this._map.measureTools.getMeasureUnit())
386
406
  },
407
+
408
+ getElevation: function () {
409
+ const lineElevation = (latlngs) => {
410
+ let gain = 0
411
+ let loss = 0
412
+ for (let i = 0, n = latlngs.length - 1; i < n; i++) {
413
+ const fromAlt = latlngs[i].alt
414
+ const toAlt = latlngs[i + 1].alt
415
+ if (fromAlt === undefined || toAlt === undefined) continue
416
+ if (fromAlt > toAlt) loss += fromAlt - toAlt
417
+ else gain += toAlt - fromAlt
418
+ }
419
+ return [gain, loss]
420
+ }
421
+ let shapes
422
+ if (LineUtil.isFlat(this._latlngs)) {
423
+ shapes = [this._latlngs]
424
+ } else {
425
+ shapes = this._latlngs
426
+ }
427
+ let totalGain = 0
428
+ let totalLoss = 0
429
+ for (const shape of shapes) {
430
+ const [gain, loss] = lineElevation(shape)
431
+ totalGain += gain
432
+ totalLoss += loss
433
+ }
434
+ return [Math.round(totalGain), Math.round(totalLoss)]
435
+ },
387
436
  })
388
437
 
389
438
  export const LeafletPolygon = Polygon.extend({
@@ -47,8 +47,8 @@ class BaseRequest {
47
47
  // In case of error, an alert is sent, but non 20X status are not handled
48
48
  // The consumer must check the response status by hand
49
49
  export class Request extends BaseRequest {
50
- fire(name, params) {
51
- document.body.dispatchEvent(new CustomEvent(name, params))
50
+ fire(name, detail) {
51
+ document.body.dispatchEvent(new CustomEvent(name, { detail }))
52
52
  }
53
53
 
54
54
  async _fetch(method, uri, headers, data) {
@@ -2,6 +2,7 @@ import { DomEvent, DomUtil, stamp } from '../../vendors/leaflet/leaflet-src.esm.
2
2
  import { translate } from './i18n.js'
3
3
  import * as Utils from './utils.js'
4
4
  import { AutocompleteDatalist } from './autocomplete.js'
5
+ import Orderable from './orderable.js'
5
6
 
6
7
  const EMPTY_VALUES = ['', undefined, null]
7
8
 
@@ -21,10 +22,10 @@ class Rule {
21
22
 
22
23
  set isDirty(status) {
23
24
  this._isDirty = status
24
- if (status) this.map.isDirty = status
25
+ if (status) this._umap.isDirty = status
25
26
  }
26
27
 
27
- constructor(map, condition = '', options = {}) {
28
+ constructor(umap, condition = '', options = {}) {
28
29
  // TODO make this public properties when browser coverage is ok
29
30
  // cf https://caniuse.com/?search=public%20class%20field
30
31
  this._condition = null
@@ -37,14 +38,14 @@ class Rule {
37
38
  ['!=', this.not_equal],
38
39
  ['=', this.equal],
39
40
  ]
40
- this.map = map
41
+ this._umap = umap
41
42
  this.active = true
42
43
  this.options = options
43
44
  this.condition = condition
44
45
  }
45
46
 
46
47
  render(fields) {
47
- this.map.render(fields)
48
+ this._umap.render(fields)
48
49
  }
49
50
 
50
51
  equal(other) {
@@ -101,10 +102,6 @@ class Rule {
101
102
  return this.operator(this.cast(props[this.key]))
102
103
  }
103
104
 
104
- getMap() {
105
- return this.map
106
- }
107
-
108
105
  getOption(option) {
109
106
  return this.options[option]
110
107
  }
@@ -136,7 +133,7 @@ class Rule {
136
133
  const defaultShapeProperties = DomUtil.add('div', '', container)
137
134
  defaultShapeProperties.appendChild(builder.build())
138
135
  const autocomplete = new AutocompleteDatalist(builder.helpers.condition.input)
139
- const properties = this.map.allProperties()
136
+ const properties = this._umap.allProperties()
140
137
  autocomplete.suggestions = properties
141
138
  autocomplete.input.addEventListener('input', (event) => {
142
139
  const value = event.target.value
@@ -144,12 +141,12 @@ class Rule {
144
141
  autocomplete.suggestions = [`${value}=`, `${value}!=`, `${value}>`, `${value}<`]
145
142
  } else if (value.endsWith('=')) {
146
143
  const key = value.split('!')[0].split('=')[0]
147
- autocomplete.suggestions = this.map
144
+ autocomplete.suggestions = this._umap
148
145
  .sortedValues(key)
149
146
  .map((str) => `${value}${str || ''}`)
150
147
  }
151
148
  })
152
- this.map.editPanel.open({ content: container })
149
+ this._umap.editPanel.open({ content: container })
153
150
  }
154
151
 
155
152
  renderToolbox(row) {
@@ -176,7 +173,7 @@ class Rule {
176
173
  function () {
177
174
  if (!confirm(translate('Are you sure you want to delete this rule?'))) return
178
175
  this._delete()
179
- this.map.editPanel.close()
176
+ this._umap.editPanel.close()
180
177
  },
181
178
  this
182
179
  )
@@ -186,27 +183,27 @@ class Rule {
186
183
  DomEvent.on(toggle, 'click', () => {
187
184
  this.active = !this.active
188
185
  row.classList.toggle('off', !this.active)
189
- this.map.render(['rules'])
186
+ this._umap.render(['rules'])
190
187
  })
191
188
  }
192
189
 
193
190
  _delete() {
194
- this.map.rules.rules = this.map.rules.rules.filter((rule) => rule !== this)
191
+ this._umap.rules.rules = this._umap.rules.rules.filter((rule) => rule !== this)
195
192
  }
196
193
  }
197
194
 
198
195
  export default class Rules {
199
- constructor(map) {
200
- this.map = map
196
+ constructor(umap) {
197
+ this._umap = umap
201
198
  this.rules = []
202
- this.loadRules()
199
+ this.load()
203
200
  }
204
201
 
205
- loadRules() {
206
- if (!this.map.options.rules?.length) return
207
- for (const { condition, options } of this.map.options.rules) {
202
+ load() {
203
+ if (!this._umap.properties.rules?.length) return
204
+ for (const { condition, options } of this._umap.properties.rules) {
208
205
  if (!condition) continue
209
- this.rules.push(new Rule(this.map, condition, options))
206
+ this.rules.push(new Rule(this._umap, condition, options))
210
207
  }
211
208
  }
212
209
 
@@ -225,7 +222,7 @@ export default class Rules {
225
222
  else newIdx = referenceIdx + 1
226
223
  this.rules.splice(newIdx, 0, moved)
227
224
  moved.isDirty = true
228
- this.map.render(['rules'])
225
+ this._umap.render(['rules'])
229
226
  }
230
227
 
231
228
  edit(container) {
@@ -236,21 +233,21 @@ export default class Rules {
236
233
  rule.renderToolbox(DomUtil.create('li', 'orderable', ul))
237
234
  }
238
235
 
239
- const orderable = new U.Orderable(ul, this.onReorder.bind(this))
236
+ const orderable = new Orderable(ul, this.onReorder.bind(this))
240
237
  }
241
238
 
242
239
  DomUtil.createButton('umap-add', body, translate('Add rule'), this.addRule, this)
243
240
  }
244
241
 
245
242
  addRule() {
246
- const rule = new Rule(this.map)
243
+ const rule = new Rule(this._umap)
247
244
  rule.isDirty = true
248
245
  this.rules.push(rule)
249
246
  rule.edit(map)
250
247
  }
251
248
 
252
249
  commit() {
253
- this.map.options.rules = this.rules.map((rule) => {
250
+ this._umap.properties.rules = this.rules.map((rule) => {
254
251
  return {
255
252
  condition: rule.condition,
256
253
  options: rule.options,
@@ -0,0 +1,47 @@
1
+ const _queue = new Set()
2
+
3
+ export let isDirty = false
4
+
5
+ export async function save() {
6
+ for (const obj of _queue) {
7
+ const ok = await obj.save()
8
+ if (!ok) break
9
+ remove(obj)
10
+ }
11
+ }
12
+
13
+ function add(obj) {
14
+ _queue.add(obj)
15
+ onUpdate()
16
+ }
17
+
18
+ function remove(obj) {
19
+ _queue.delete(obj)
20
+ onUpdate()
21
+ }
22
+
23
+ function has(obj) {
24
+ return _queue.has(obj)
25
+ }
26
+
27
+ function onUpdate() {
28
+ isDirty = Boolean(_queue.size)
29
+ document.body.classList.toggle('umap-is-dirty', isDirty)
30
+ }
31
+
32
+ export class ServerStored {
33
+ set isDirty(status) {
34
+ if (status) {
35
+ add(this)
36
+ } else {
37
+ remove(this)
38
+ }
39
+ this.onDirty(status)
40
+ }
41
+
42
+ get isDirty() {
43
+ return has(this)
44
+ }
45
+
46
+ onDirty(status) {}
47
+ }
@@ -404,6 +404,7 @@ export const SCHEMA = {
404
404
  ['GeoRSSImage', translate('GeoRSS (title + image)')],
405
405
  ['GeoRSSLink', translate('GeoRSS (only link)')],
406
406
  ['OSM', translate('OpenStreetMap')],
407
+ ['Wikipedia', translate('Wikipedia')],
407
408
  ],
408
409
  default: 'Default',
409
410
  },
@@ -563,4 +564,9 @@ export const SCHEMA = {
563
564
  type: Object,
564
565
  impacts: ['data'],
565
566
  },
567
+
568
+ _referenceVersion: {
569
+ type: Number,
570
+ impacts: ['data'],
571
+ },
566
572
  }
@@ -4,8 +4,8 @@ import { translate } from './i18n.js'
4
4
  import * as Utils from './utils.js'
5
5
 
6
6
  export default class Share {
7
- constructor(map) {
8
- this.map = map
7
+ constructor(umap) {
8
+ this._umap = umap
9
9
  }
10
10
 
11
11
  build() {
@@ -22,11 +22,11 @@ export default class Share {
22
22
  window.location.protocol + Utils.getBaseUrl()
23
23
  )
24
24
 
25
- if (this.map.options.shortUrl) {
25
+ if (this._umap.properties.shortUrl) {
26
26
  DomUtil.createCopiableInput(
27
27
  this.container,
28
28
  translate('Short link'),
29
- this.map.options.shortUrl
29
+ this._umap.properties.shortUrl
30
30
  )
31
31
  }
32
32
 
@@ -60,8 +60,8 @@ export default class Share {
60
60
  this.container,
61
61
  translate('All data and settings of the map')
62
62
  )
63
- const downloadUrl = Utils.template(this.map.options.urls.map_download, {
64
- map_id: this.map.options.umap_id,
63
+ const downloadUrl = this._umap.urls.get('map_download', {
64
+ map_id: this._umap.id,
65
65
  })
66
66
  const link = Utils.loadTemplate(`
67
67
  <div>
@@ -115,10 +115,11 @@ export default class Share {
115
115
  'queryString.captionBar',
116
116
  'queryString.captionMenus',
117
117
  ]
118
- for (let i = 0; i < this.map.HIDDABLE_CONTROLS.length; i++) {
119
- UIFields.push(`queryString.${this.map.HIDDABLE_CONTROLS[i]}Control`)
118
+ // TODO: move HIDDABLE_CONTROLS to SCHEMA ?
119
+ for (const name of this._umap._leafletMap.HIDDABLE_CONTROLS) {
120
+ UIFields.push(`queryString.${name}Control`)
120
121
  }
121
- const iframeExporter = new IframeExporter(this.map)
122
+ const iframeExporter = new IframeExporter(this._umap)
122
123
  const buildIframeCode = () => {
123
124
  iframe.textContent = iframeExporter.build()
124
125
  exportUrl.value = window.location.protocol + iframeExporter.buildUrl()
@@ -136,13 +137,13 @@ export default class Share {
136
137
 
137
138
  open() {
138
139
  if (!this.container) this.build()
139
- this.map.panel.open({ content: this.container })
140
+ this._umap.panel.open({ content: this.container })
140
141
  }
141
142
 
142
143
  async format(mode) {
143
144
  const type = EXPORT_FORMATS[mode]
144
- const content = await type.formatter(this.map)
145
- const filename = Utils.slugify(this.map.options.name) + type.ext
145
+ const content = await type.formatter(this._umap)
146
+ const filename = Utils.slugify(this._umap.properties.name) + type.ext
146
147
  return { content, filetype: type.filetype, filename }
147
148
  }
148
149
 
@@ -161,8 +162,8 @@ export default class Share {
161
162
  }
162
163
 
163
164
  class IframeExporter {
164
- constructor(map) {
165
- this.map = map
165
+ constructor(umap) {
166
+ this._umap = umap
166
167
  this.baseUrl = Utils.getBaseUrl()
167
168
  this.options = {
168
169
  includeFullScreenLink: true,
@@ -192,24 +193,20 @@ class IframeExporter {
192
193
  height: '300px',
193
194
  }
194
195
  // Use map default, not generic default
195
- this.queryString.onLoadPanel = this.map.getOption('onLoadPanel')
196
- }
197
-
198
- getMap() {
199
- return this.map
196
+ this.queryString.onLoadPanel = this._umap.getProperty('onLoadPanel')
200
197
  }
201
198
 
202
199
  buildUrl(options) {
203
200
  const datalayers = []
204
- if (this.options.viewCurrentFeature && this.map.currentFeature) {
205
- this.queryString.feature = this.map.currentFeature.getSlug()
201
+ if (this.options.viewCurrentFeature && this._umap.currentFeature) {
202
+ this.queryString.feature = this._umap.currentFeature.getSlug()
206
203
  } else {
207
204
  delete this.queryString.feature
208
205
  }
209
206
  if (this.options.keepCurrentDatalayers) {
210
- this.map.eachDataLayer((datalayer) => {
211
- if (datalayer.isVisible() && datalayer.umap_id) {
212
- datalayers.push(datalayer.umap_id)
207
+ this._umap.eachDataLayer((datalayer) => {
208
+ if (datalayer.isVisible() && datalayer.createdOnServer) {
209
+ datalayers.push(datalayer.id)
213
210
  }
214
211
  })
215
212
  this.queryString.datalayers = datalayers.join(',')
@@ -13,26 +13,22 @@ const TOOLBOX_TEMPLATE = `
13
13
  `
14
14
 
15
15
  export default class Slideshow extends WithTemplate {
16
- constructor(map, options) {
16
+ constructor(umap, leafletMap, properties) {
17
17
  super()
18
- this.map = map
18
+ this._umap = umap
19
19
  this._id = null
20
20
  this.CLASSNAME = 'umap-slideshow-active'
21
- this.setOptions(options)
21
+ this.load()
22
22
  this._current = null
23
23
 
24
- if (this.options.autoplay) {
25
- this.map.onceDataLoaded(function () {
24
+ if (this.properties.autoplay) {
25
+ this._umap.onceDataLoaded(function () {
26
26
  this.play()
27
27
  }, this)
28
28
  }
29
- this.map.on(
30
- 'edit:enabled',
31
- function () {
32
- this.stop()
33
- },
34
- this
35
- )
29
+ leafletMap.on('edit:enabled', () => {
30
+ this.stop()
31
+ })
36
32
  }
37
33
 
38
34
  set current(feature) {
@@ -54,22 +50,26 @@ export default class Slideshow extends WithTemplate {
54
50
  return this.current.getNext()
55
51
  }
56
52
 
57
- setOptions(options) {
58
- this.options = Object.assign(
53
+ load() {
54
+ this.setProperties(this._umap.properties.slideshow)
55
+ }
56
+
57
+ setProperties(properties = {}) {
58
+ this.properties = Object.assign(
59
59
  {
60
60
  delay: 5000,
61
61
  autoplay: false,
62
62
  },
63
- options
63
+ properties
64
64
  )
65
65
  }
66
66
 
67
67
  defaultDatalayer() {
68
- return this.map.findDataLayer((d) => d.canBrowse())
68
+ return this._umap.findDataLayer((d) => d.canBrowse())
69
69
  }
70
70
 
71
71
  startSpinner() {
72
- const time = Number.parseInt(this.options.delay, 10)
72
+ const time = Number.parseInt(this.properties.delay, 10)
73
73
  if (!time) return
74
74
  const css = `rotation ${time / 1000}s infinite linear`
75
75
  const spinner = document.querySelector('.umap-slideshow-toolbox .play .spinner')
@@ -81,11 +81,15 @@ export default class Slideshow extends WithTemplate {
81
81
  spinner.style.animation = 'none'
82
82
  }
83
83
 
84
+ isEnabled() {
85
+ return Boolean(this.properties.active)
86
+ }
87
+
84
88
  play() {
85
89
  if (this._id) return
86
- if (this.map.editEnabled || !this.map.options.slideshow.active) return
90
+ if (this._umap.editEnabled || !this.isEnabled()) return
87
91
  L.DomUtil.addClass(document.body, this.CLASSNAME)
88
- this._id = window.setInterval(L.bind(this.loop, this), this.options.delay)
92
+ this._id = window.setInterval(L.bind(this.loop, this), this.properties.delay)
89
93
  this.startSpinner()
90
94
  this.loop()
91
95
  }
@@ -123,7 +127,7 @@ export default class Slideshow extends WithTemplate {
123
127
 
124
128
  step() {
125
129
  if (!this.current) return this.stop()
126
- this.current.zoomTo({ easing: this.options.easing })
130
+ this.current.zoomTo({ easing: this.properties.easing })
127
131
  this.current.view()
128
132
  }
129
133
 
@@ -6,8 +6,8 @@ import { fieldInSchema } from '../utils.js'
6
6
  */
7
7
 
8
8
  class BaseUpdater {
9
- constructor(map) {
10
- this.map = map
9
+ constructor(umap) {
10
+ this._umap = umap
11
11
  }
12
12
 
13
13
  updateObjectValue(obj, key, value) {
@@ -32,8 +32,7 @@ class BaseUpdater {
32
32
  }
33
33
 
34
34
  getDataLayerFromID(layerId) {
35
- if (layerId) return this.map.getDataLayerByUmapId(layerId)
36
- return this.map.defaultEditDataLayer()
35
+ return this._umap.getDataLayerByUmapId(layerId)
37
36
  }
38
37
 
39
38
  applyMessage(payload) {
@@ -45,18 +44,17 @@ class BaseUpdater {
45
44
  export class MapUpdater extends BaseUpdater {
46
45
  update({ key, value }) {
47
46
  if (fieldInSchema(key)) {
48
- this.updateObjectValue(this.map, key, value)
47
+ this.updateObjectValue(this._umap, key, value)
49
48
  }
50
49
 
51
- this.map.render([key])
50
+ this._umap.render([key])
52
51
  }
53
52
  }
54
53
 
55
54
  export class DataLayerUpdater extends BaseUpdater {
56
55
  upsert({ value }) {
57
- // Inserts does not happen (we use multiple updates instead).
58
- this.map.createDataLayer(value, false)
59
- this.map.render([])
56
+ // Upsert only happens when a new datalayer is created.
57
+ this._umap.createDataLayer(value, false)
60
58
  }
61
59
 
62
60
  update({ key, metadata, value }) {