umap-project 2.5.0__py3-none-any.whl → 2.6.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of umap-project might be problematic. Click here for more details.

Files changed (276) hide show
  1. umap/__init__.py +1 -1
  2. umap/admin.py +6 -1
  3. umap/context_processors.py +2 -1
  4. umap/decorators.py +13 -2
  5. umap/forms.py +26 -2
  6. umap/locale/br/LC_MESSAGES/django.mo +0 -0
  7. umap/locale/br/LC_MESSAGES/django.po +252 -146
  8. umap/locale/ca/LC_MESSAGES/django.mo +0 -0
  9. umap/locale/ca/LC_MESSAGES/django.po +274 -162
  10. umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
  11. umap/locale/cs_CZ/LC_MESSAGES/django.po +261 -150
  12. umap/locale/de/LC_MESSAGES/django.mo +0 -0
  13. umap/locale/de/LC_MESSAGES/django.po +299 -187
  14. umap/locale/el/LC_MESSAGES/django.mo +0 -0
  15. umap/locale/el/LC_MESSAGES/django.po +215 -159
  16. umap/locale/en/LC_MESSAGES/django.po +211 -155
  17. umap/locale/es/LC_MESSAGES/django.mo +0 -0
  18. umap/locale/es/LC_MESSAGES/django.po +255 -144
  19. umap/locale/eu/LC_MESSAGES/django.mo +0 -0
  20. umap/locale/eu/LC_MESSAGES/django.po +254 -198
  21. umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
  22. umap/locale/fa_IR/LC_MESSAGES/django.po +347 -235
  23. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  24. umap/locale/fr/LC_MESSAGES/django.po +216 -160
  25. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  26. umap/locale/hu/LC_MESSAGES/django.po +215 -159
  27. umap/locale/it/LC_MESSAGES/django.mo +0 -0
  28. umap/locale/it/LC_MESSAGES/django.po +252 -146
  29. umap/locale/ms/LC_MESSAGES/django.mo +0 -0
  30. umap/locale/ms/LC_MESSAGES/django.po +252 -146
  31. umap/locale/pl/LC_MESSAGES/django.mo +0 -0
  32. umap/locale/pl/LC_MESSAGES/django.po +254 -148
  33. umap/locale/pt/LC_MESSAGES/django.mo +0 -0
  34. umap/locale/pt/LC_MESSAGES/django.po +215 -159
  35. umap/locale/sv/LC_MESSAGES/django.mo +0 -0
  36. umap/locale/sv/LC_MESSAGES/django.po +254 -143
  37. umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
  38. umap/locale/th_TH/LC_MESSAGES/django.po +125 -70
  39. umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
  40. umap/locale/zh_TW/LC_MESSAGES/django.po +256 -145
  41. umap/migrations/0022_add_team.py +94 -0
  42. umap/models.py +45 -10
  43. umap/settings/__init__.py +2 -0
  44. umap/settings/base.py +9 -2
  45. umap/static/umap/base.css +32 -41
  46. umap/static/umap/content.css +19 -25
  47. umap/static/umap/css/icon.css +63 -37
  48. umap/static/umap/css/importers.css +1 -1
  49. umap/static/umap/css/slideshow.css +7 -5
  50. umap/static/umap/css/tableeditor.css +4 -3
  51. umap/static/umap/img/16-white.svg +1 -4
  52. umap/static/umap/img/16.svg +2 -6
  53. umap/static/umap/img/24-white.svg +4 -4
  54. umap/static/umap/img/24.svg +6 -6
  55. umap/static/umap/img/source/16-white.svg +2 -5
  56. umap/static/umap/img/source/16.svg +3 -7
  57. umap/static/umap/img/source/24-white.svg +7 -14
  58. umap/static/umap/img/source/24.svg +10 -17
  59. umap/static/umap/js/components/alerts/alert.css +20 -8
  60. umap/static/umap/js/modules/autocomplete.js +8 -12
  61. umap/static/umap/js/modules/browser.js +4 -3
  62. umap/static/umap/js/modules/caption.js +9 -11
  63. umap/static/umap/js/modules/data/features.js +993 -0
  64. umap/static/umap/js/modules/data/layer.js +1210 -0
  65. umap/static/umap/js/modules/formatter.js +12 -3
  66. umap/static/umap/js/modules/global.js +21 -5
  67. umap/static/umap/js/modules/importers/overpass.js +22 -8
  68. umap/static/umap/js/modules/permissions.js +280 -0
  69. umap/static/umap/js/{umap.icon.js → modules/rendering/icon.js} +77 -56
  70. umap/static/umap/js/modules/rendering/layers/base.js +105 -0
  71. umap/static/umap/js/modules/rendering/layers/classified.js +484 -0
  72. umap/static/umap/js/modules/rendering/layers/cluster.js +103 -0
  73. umap/static/umap/js/modules/rendering/layers/heat.js +182 -0
  74. umap/static/umap/js/modules/rendering/popup.js +99 -0
  75. umap/static/umap/js/modules/rendering/template.js +217 -0
  76. umap/static/umap/js/modules/rendering/ui.js +610 -0
  77. umap/static/umap/js/modules/rules.js +16 -3
  78. umap/static/umap/js/modules/schema.js +25 -1
  79. umap/static/umap/js/modules/share.js +66 -45
  80. umap/static/umap/js/modules/sync/updaters.js +9 -10
  81. umap/static/umap/js/modules/tableeditor.js +7 -7
  82. umap/static/umap/js/modules/ui/dialog.js +8 -4
  83. umap/static/umap/js/modules/utils.js +22 -13
  84. umap/static/umap/js/umap.controls.js +80 -146
  85. umap/static/umap/js/umap.core.js +9 -9
  86. umap/static/umap/js/umap.forms.js +41 -17
  87. umap/static/umap/js/umap.js +72 -65
  88. umap/static/umap/locale/am_ET.js +8 -2
  89. umap/static/umap/locale/am_ET.json +8 -2
  90. umap/static/umap/locale/ar.js +8 -2
  91. umap/static/umap/locale/ar.json +8 -2
  92. umap/static/umap/locale/ast.js +8 -2
  93. umap/static/umap/locale/ast.json +8 -2
  94. umap/static/umap/locale/bg.js +8 -2
  95. umap/static/umap/locale/bg.json +8 -2
  96. umap/static/umap/locale/br.js +42 -36
  97. umap/static/umap/locale/br.json +42 -36
  98. umap/static/umap/locale/ca.js +67 -61
  99. umap/static/umap/locale/ca.json +67 -61
  100. umap/static/umap/locale/cs_CZ.js +8 -2
  101. umap/static/umap/locale/cs_CZ.json +8 -2
  102. umap/static/umap/locale/da.js +8 -2
  103. umap/static/umap/locale/da.json +8 -2
  104. umap/static/umap/locale/de.js +143 -137
  105. umap/static/umap/locale/de.json +143 -137
  106. umap/static/umap/locale/el.js +54 -48
  107. umap/static/umap/locale/el.json +54 -48
  108. umap/static/umap/locale/en.js +10 -2
  109. umap/static/umap/locale/en.json +10 -2
  110. umap/static/umap/locale/en_US.json +8 -2
  111. umap/static/umap/locale/es.js +8 -2
  112. umap/static/umap/locale/es.json +8 -2
  113. umap/static/umap/locale/et.js +8 -2
  114. umap/static/umap/locale/et.json +8 -2
  115. umap/static/umap/locale/eu.js +346 -338
  116. umap/static/umap/locale/eu.json +346 -338
  117. umap/static/umap/locale/fa_IR.js +415 -407
  118. umap/static/umap/locale/fa_IR.json +415 -407
  119. umap/static/umap/locale/fi.js +8 -2
  120. umap/static/umap/locale/fi.json +8 -2
  121. umap/static/umap/locale/fr.js +11 -3
  122. umap/static/umap/locale/fr.json +11 -3
  123. umap/static/umap/locale/gl.js +8 -2
  124. umap/static/umap/locale/gl.json +8 -2
  125. umap/static/umap/locale/he.js +8 -2
  126. umap/static/umap/locale/he.json +8 -2
  127. umap/static/umap/locale/hr.js +8 -2
  128. umap/static/umap/locale/hr.json +8 -2
  129. umap/static/umap/locale/hu.js +31 -23
  130. umap/static/umap/locale/hu.json +31 -23
  131. umap/static/umap/locale/id.js +8 -2
  132. umap/static/umap/locale/id.json +8 -2
  133. umap/static/umap/locale/is.js +8 -2
  134. umap/static/umap/locale/is.json +8 -2
  135. umap/static/umap/locale/it.js +8 -2
  136. umap/static/umap/locale/it.json +8 -2
  137. umap/static/umap/locale/ja.js +8 -2
  138. umap/static/umap/locale/ja.json +8 -2
  139. umap/static/umap/locale/ko.js +8 -2
  140. umap/static/umap/locale/ko.json +8 -2
  141. umap/static/umap/locale/lt.js +8 -2
  142. umap/static/umap/locale/lt.json +8 -2
  143. umap/static/umap/locale/ms.js +8 -2
  144. umap/static/umap/locale/ms.json +8 -2
  145. umap/static/umap/locale/nl.js +8 -2
  146. umap/static/umap/locale/nl.json +8 -2
  147. umap/static/umap/locale/no.js +8 -2
  148. umap/static/umap/locale/no.json +8 -2
  149. umap/static/umap/locale/pl.js +54 -48
  150. umap/static/umap/locale/pl.json +54 -48
  151. umap/static/umap/locale/pl_PL.json +8 -2
  152. umap/static/umap/locale/pt.js +24 -18
  153. umap/static/umap/locale/pt.json +24 -18
  154. umap/static/umap/locale/pt_BR.js +8 -2
  155. umap/static/umap/locale/pt_BR.json +8 -2
  156. umap/static/umap/locale/pt_PT.js +214 -208
  157. umap/static/umap/locale/pt_PT.json +214 -208
  158. umap/static/umap/locale/ro.js +8 -2
  159. umap/static/umap/locale/ro.json +8 -2
  160. umap/static/umap/locale/ru.js +8 -2
  161. umap/static/umap/locale/ru.json +8 -2
  162. umap/static/umap/locale/sk_SK.js +8 -2
  163. umap/static/umap/locale/sk_SK.json +8 -2
  164. umap/static/umap/locale/sl.js +8 -2
  165. umap/static/umap/locale/sl.json +8 -2
  166. umap/static/umap/locale/sr.js +8 -2
  167. umap/static/umap/locale/sr.json +8 -2
  168. umap/static/umap/locale/sv.js +8 -2
  169. umap/static/umap/locale/sv.json +8 -2
  170. umap/static/umap/locale/th_TH.js +33 -27
  171. umap/static/umap/locale/th_TH.json +33 -27
  172. umap/static/umap/locale/tr.js +8 -2
  173. umap/static/umap/locale/tr.json +8 -2
  174. umap/static/umap/locale/uk_UA.js +8 -2
  175. umap/static/umap/locale/uk_UA.json +8 -2
  176. umap/static/umap/locale/vi.js +8 -2
  177. umap/static/umap/locale/vi.json +8 -2
  178. umap/static/umap/locale/vi_VN.json +8 -2
  179. umap/static/umap/locale/zh.js +8 -2
  180. umap/static/umap/locale/zh.json +8 -2
  181. umap/static/umap/locale/zh_CN.json +8 -2
  182. umap/static/umap/locale/zh_TW.Big5.json +8 -2
  183. umap/static/umap/locale/zh_TW.js +102 -96
  184. umap/static/umap/locale/zh_TW.json +102 -96
  185. umap/static/umap/map.css +111 -108
  186. umap/static/umap/nav.css +19 -10
  187. umap/static/umap/unittests/utils.js +230 -107
  188. umap/static/umap/vars.css +1 -0
  189. umap/static/umap/vendors/csv2geojson/csv2geojson.js +62 -40
  190. umap/static/umap/vendors/editable/Leaflet.Editable.js +2079 -1937
  191. umap/storage.py +4 -3
  192. umap/templates/404.html +5 -1
  193. umap/templates/500.html +3 -1
  194. umap/templates/auth/user_detail.html +8 -2
  195. umap/templates/auth/user_form.html +19 -10
  196. umap/templates/auth/user_stars.html +8 -2
  197. umap/templates/base.html +1 -0
  198. umap/templates/registration/login.html +18 -3
  199. umap/templates/umap/about.html +1 -0
  200. umap/templates/umap/about_summary.html +22 -7
  201. umap/templates/umap/components/alerts/alert.html +42 -21
  202. umap/templates/umap/content.html +2 -0
  203. umap/templates/umap/content_footer.html +7 -3
  204. umap/templates/umap/css.html +1 -0
  205. umap/templates/umap/dashboard_menu.html +15 -0
  206. umap/templates/umap/home.html +14 -4
  207. umap/templates/umap/js.html +4 -9
  208. umap/templates/umap/login_popup_end.html +10 -4
  209. umap/templates/umap/map_detail.html +8 -2
  210. umap/templates/umap/map_fragment.html +3 -1
  211. umap/templates/umap/map_init.html +2 -1
  212. umap/templates/umap/map_list.html +6 -3
  213. umap/templates/umap/map_table.html +36 -12
  214. umap/templates/umap/messages.html +0 -1
  215. umap/templates/umap/navigation.html +2 -1
  216. umap/templates/umap/password_change.html +5 -1
  217. umap/templates/umap/password_change_done.html +8 -2
  218. umap/templates/umap/search.html +8 -2
  219. umap/templates/umap/search_bar.html +1 -0
  220. umap/templates/umap/team_confirm_delete.html +19 -0
  221. umap/templates/umap/team_detail.html +27 -0
  222. umap/templates/umap/team_form.html +60 -0
  223. umap/templates/umap/user_dashboard.html +7 -9
  224. umap/templates/umap/user_teams.html +51 -0
  225. umap/tests/base.py +8 -1
  226. umap/tests/conftest.py +6 -0
  227. umap/tests/fixtures/test_circles_layer.geojson +219 -0
  228. umap/tests/fixtures/test_upload_georss.xml +20 -0
  229. umap/tests/integration/conftest.py +18 -4
  230. umap/tests/integration/helpers.py +12 -0
  231. umap/tests/integration/test_anonymous_owned_map.py +23 -0
  232. umap/tests/integration/test_basics.py +29 -0
  233. umap/tests/integration/test_browser.py +20 -0
  234. umap/tests/integration/test_caption.py +20 -0
  235. umap/tests/integration/test_circles_layer.py +69 -0
  236. umap/tests/integration/test_conditional_rules.py +102 -17
  237. umap/tests/integration/test_draw_polygon.py +138 -13
  238. umap/tests/integration/test_draw_polyline.py +8 -18
  239. umap/tests/integration/test_edit_datalayer.py +3 -3
  240. umap/tests/integration/test_import.py +124 -5
  241. umap/tests/integration/test_owned_map.py +21 -13
  242. umap/tests/integration/test_querystring.py +7 -0
  243. umap/tests/integration/test_team.py +47 -0
  244. umap/tests/integration/test_tilelayer.py +19 -2
  245. umap/tests/integration/test_view_marker.py +28 -1
  246. umap/tests/integration/test_websocket_sync.py +5 -5
  247. umap/tests/test_datalayer.py +32 -7
  248. umap/tests/test_datalayer_views.py +1 -1
  249. umap/tests/test_map.py +30 -4
  250. umap/tests/test_map_views.py +2 -2
  251. umap/tests/test_statics.py +40 -0
  252. umap/tests/test_team_views.py +131 -0
  253. umap/tests/test_views.py +15 -1
  254. umap/urls.py +23 -13
  255. umap/views.py +116 -10
  256. {umap_project-2.5.0.dist-info → umap_project-2.6.0.dist-info}/METADATA +14 -14
  257. {umap_project-2.5.0.dist-info → umap_project-2.6.0.dist-info}/RECORD +260 -253
  258. umap/static/umap/js/umap.datalayer.permissions.js +0 -70
  259. umap/static/umap/js/umap.features.js +0 -1290
  260. umap/static/umap/js/umap.layer.js +0 -1837
  261. umap/static/umap/js/umap.permissions.js +0 -208
  262. umap/static/umap/js/umap.popup.js +0 -341
  263. umap/static/umap/test/TableEditor.js +0 -104
  264. umap/static/umap/vendors/leaflet/leaflet-src.js +0 -14512
  265. umap/static/umap/vendors/leaflet/leaflet-src.js.map +0 -1
  266. umap/static/umap/vendors/leaflet/leaflet.js +0 -6
  267. umap/static/umap/vendors/leaflet/leaflet.js.map +0 -1
  268. umap/static/umap/vendors/markercluster/WhereAreTheJavascriptFiles.txt +0 -5
  269. umap/static/umap/vendors/markercluster/leaflet.markercluster-src.js +0 -2718
  270. umap/static/umap/vendors/markercluster/leaflet.markercluster-src.js.map +0 -1
  271. umap/static/umap/vendors/toolbar/leaflet.toolbar-src.css +0 -117
  272. umap/static/umap/vendors/toolbar/leaflet.toolbar-src.js +0 -365
  273. umap/tests/integration/test_statics.py +0 -47
  274. {umap_project-2.5.0.dist-info → umap_project-2.6.0.dist-info}/WHEEL +0 -0
  275. {umap_project-2.5.0.dist-info → umap_project-2.6.0.dist-info}/entry_points.txt +0 -0
  276. {umap_project-2.5.0.dist-info → umap_project-2.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -57,6 +57,10 @@ export const SCHEMA = {
57
57
  type: Object,
58
58
  impacts: ['data'],
59
59
  },
60
+ circles: {
61
+ type: Object,
62
+ impacts: ['data'],
63
+ },
60
64
  cluster: {
61
65
  type: Object,
62
66
  impacts: ['data'],
@@ -77,7 +81,7 @@ export const SCHEMA = {
77
81
  impacts: ['ui'],
78
82
  nullable: true,
79
83
  handler: 'DataLayersControl',
80
- label: translate('Display the data layers control'),
84
+ label: translate('Display the open browser control'),
81
85
  default: true,
82
86
  },
83
87
  defaultView: {
@@ -112,6 +116,7 @@ export const SCHEMA = {
112
116
  type: Boolean,
113
117
  impacts: [],
114
118
  default: false,
119
+ label: translate('Animated transitions'),
115
120
  },
116
121
  editinosmControl: {
117
122
  type: Boolean,
@@ -130,6 +135,9 @@ export const SCHEMA = {
130
135
  facetKey: {
131
136
  type: String,
132
137
  impacts: ['ui'],
138
+ helpEntries: ['facetKey'],
139
+ placeholder: translate('Example: key1,key2|Label 2,key3|Label 3|checkbox'),
140
+ label: translate('Filters keys'),
133
141
  },
134
142
  fill: {
135
143
  type: Boolean,
@@ -160,6 +168,10 @@ export const SCHEMA = {
160
168
  filterKey: {
161
169
  type: String,
162
170
  impacts: [],
171
+ helpEntries: ['filterKey'],
172
+ placeholder: translate('Default: name'),
173
+ label: translate('Search keys'),
174
+ inheritable: true,
163
175
  },
164
176
  fromZoom: {
165
177
  type: Number,
@@ -279,6 +291,11 @@ export const SCHEMA = {
279
291
  nullable: true,
280
292
  label: translate('Display the measure control'),
281
293
  },
294
+ mask: {
295
+ type: Boolean,
296
+ impacts: ['data'],
297
+ label: translate('Display the polygon inverted'),
298
+ },
282
299
  miniMap: {
283
300
  type: Boolean,
284
301
  impacts: ['ui'],
@@ -437,6 +454,9 @@ export const SCHEMA = {
437
454
  slugKey: {
438
455
  type: String,
439
456
  impacts: [],
457
+ helpEntries: ['slugKey'],
458
+ placeholder: translate('Default: name'),
459
+ label: translate('Feature identifier key'),
440
460
  },
441
461
  smoothFactor: {
442
462
  type: Number,
@@ -452,6 +472,10 @@ export const SCHEMA = {
452
472
  sortKey: {
453
473
  type: String,
454
474
  impacts: ['datalayer-index', 'data'],
475
+ helpEntries: ['sortKey'],
476
+ placeholder: translate('Default: name'),
477
+ label: translate('Sort key'),
478
+ inheritable: true,
455
479
  },
456
480
  starControl: {
457
481
  type: Boolean,
@@ -1,4 +1,7 @@
1
+ import { DomUtil } from '../../vendors/leaflet/leaflet-src.esm.js'
1
2
  import { EXPORT_FORMATS } from './formatter.js'
3
+ import { translate } from './i18n.js'
4
+ import * as Utils from './utils.js'
2
5
 
3
6
  export default class Share {
4
7
  constructor(map) {
@@ -6,85 +9,103 @@ export default class Share {
6
9
  }
7
10
 
8
11
  build() {
9
- this.container = L.DomUtil.create('div', '')
10
- this.title = L.DomUtil.createTitle(
12
+ this.container = DomUtil.create('div', '')
13
+ this.title = DomUtil.createTitle(
11
14
  this.container,
12
- L._('Share and download'),
15
+ translate('Share and download'),
13
16
  'icon-share'
14
17
  )
15
18
 
16
- L.DomUtil.createCopiableInput(
19
+ DomUtil.createCopiableInput(
17
20
  this.container,
18
- L._('Link to view the map'),
19
- window.location.protocol + U.Utils.getBaseUrl()
21
+ translate('Link to view the map'),
22
+ window.location.protocol + Utils.getBaseUrl()
20
23
  )
21
24
 
22
25
  if (this.map.options.shortUrl) {
23
- L.DomUtil.createCopiableInput(
26
+ DomUtil.createCopiableInput(
24
27
  this.container,
25
- L._('Short link'),
28
+ translate('Short link'),
26
29
  this.map.options.shortUrl
27
30
  )
28
31
  }
29
32
 
30
- L.DomUtil.create('hr', '', this.container)
33
+ DomUtil.create('hr', '', this.container)
31
34
 
32
- L.DomUtil.add('h4', '', this.container, L._('Download'))
33
- L.DomUtil.add('small', 'label', this.container, L._("Only visible layers' data"))
35
+ DomUtil.add('h4', '', this.container, translate('Download'))
36
+ DomUtil.add(
37
+ 'small',
38
+ 'label',
39
+ this.container,
40
+ translate("Only visible layers' data")
41
+ )
42
+ const list = document.createElement('ul')
43
+ list.classList.add('downloads')
44
+ this.container.appendChild(list)
34
45
  for (const format of Object.keys(EXPORT_FORMATS)) {
35
- L.DomUtil.createButton('download-file', this.container, format, () =>
36
- this.download(format)
37
- )
46
+ const button = Utils.loadTemplate(`
47
+ <li>
48
+ <button class="flat" type="button">
49
+ <i class="icon icon-16 icon-download"></i>${format}
50
+ </button>
51
+ </li>
52
+ `)
53
+ button.addEventListener('click', () => this.download(format))
54
+ list.appendChild(button)
38
55
  }
39
- L.DomUtil.create('div', 'vspace', this.container)
40
- L.DomUtil.add(
56
+ DomUtil.create('div', 'vspace', this.container)
57
+ DomUtil.add(
41
58
  'small',
42
59
  'label',
43
60
  this.container,
44
- L._('All data and settings of the map')
61
+ translate('All data and settings of the map')
45
62
  )
46
- const downloadUrl = U.Utils.template(this.map.options.urls.map_download, {
63
+ const downloadUrl = Utils.template(this.map.options.urls.map_download, {
47
64
  map_id: this.map.options.umap_id,
48
65
  })
49
- const link = L.DomUtil.createLink(
50
- 'download-backup',
51
- this.container,
52
- L._('full backup'),
53
- downloadUrl
54
- )
55
- let name = this.map.options.name || 'data'
56
- name = name.replace(/[^a-z0-9]/gi, '_').toLowerCase()
57
- link.setAttribute('download', `${name}.umap`)
58
- L.DomUtil.create('hr', '', this.container)
59
-
60
- const embedTitle = L.DomUtil.add('h4', '', this.container, L._('Embed the map'))
61
- const iframe = L.DomUtil.create('textarea', 'umap-share-iframe', this.container)
62
- const urlTitle = L.DomUtil.add('h4', '', this.container, L._('Direct link'))
63
- const exportUrl = L.DomUtil.createCopiableInput(
66
+ const link = Utils.loadTemplate(`
67
+ <div>
68
+ <a href="${downloadUrl}">
69
+ <i class="icon icon-16 icon-backup"></i>${translate('full backup')}
70
+ </a>
71
+ </div>
72
+ `)
73
+ this.container.appendChild(link)
74
+ // File will be named by back-office
75
+ link.setAttribute('download', 'backup.umap')
76
+ DomUtil.create('hr', '', this.container)
77
+
78
+ const embedTitle = DomUtil.add('h4', '', this.container, translate('Embed the map'))
79
+ const iframe = DomUtil.create('textarea', 'umap-share-iframe', this.container)
80
+ const urlTitle = DomUtil.add('h4', '', this.container, translate('Direct link'))
81
+ const exportUrl = DomUtil.createCopiableInput(
64
82
  this.container,
65
- L._('Share this link to open a customized map view'),
83
+ translate('Share this link to open a customized map view'),
66
84
  ''
67
85
  )
68
86
 
69
87
  exportUrl.type = 'text'
70
88
  const UIFields = [
71
- ['dimensions.width', { handler: 'Input', label: L._('width') }],
72
- ['dimensions.height', { handler: 'Input', label: L._('height') }],
89
+ ['dimensions.width', { handler: 'Input', label: translate('width') }],
90
+ ['dimensions.height', { handler: 'Input', label: translate('height') }],
73
91
  [
74
92
  'options.includeFullScreenLink',
75
- { handler: 'Switch', label: L._('Include full screen link?') },
93
+ { handler: 'Switch', label: translate('Include full screen link?') },
76
94
  ],
77
95
  [
78
96
  'options.currentView',
79
- { handler: 'Switch', label: L._('Current view instead of default map view?') },
97
+ {
98
+ handler: 'Switch',
99
+ label: translate('Current view instead of default map view?'),
100
+ },
80
101
  ],
81
102
  [
82
103
  'options.keepCurrentDatalayers',
83
- { handler: 'Switch', label: L._('Keep current visible layers') },
104
+ { handler: 'Switch', label: translate('Keep current visible layers') },
84
105
  ],
85
106
  [
86
107
  'options.viewCurrentFeature',
87
- { handler: 'Switch', label: L._('Open current feature on load') },
108
+ { handler: 'Switch', label: translate('Open current feature on load') },
88
109
  ],
89
110
  'queryString.moreControl',
90
111
  'queryString.scrollWheelZoom',
@@ -106,9 +127,9 @@ export default class Share {
106
127
  const builder = new U.FormBuilder(iframeExporter, UIFields, {
107
128
  callback: buildIframeCode,
108
129
  })
109
- const iframeOptions = L.DomUtil.createFieldset(
130
+ const iframeOptions = DomUtil.createFieldset(
110
131
  this.container,
111
- L._('Embed and link options')
132
+ translate('Embed and link options')
112
133
  )
113
134
  iframeOptions.appendChild(builder.build())
114
135
  }
@@ -144,7 +165,7 @@ export default class Share {
144
165
  class IframeExporter {
145
166
  constructor(map) {
146
167
  this.map = map
147
- this.baseUrl = U.Utils.getBaseUrl()
168
+ this.baseUrl = Utils.getBaseUrl()
148
169
  this.options = {
149
170
  includeFullScreenLink: true,
150
171
  currentView: false,
@@ -199,7 +220,7 @@ class IframeExporter {
199
220
  }
200
221
  const currentView = this.options.currentView ? window.location.hash : ''
201
222
  const queryString = L.extend({}, this.queryString, options)
202
- return `${this.baseUrl}?${U.Utils.buildQueryString(queryString)}${currentView}`
223
+ return `${this.baseUrl}?${Utils.buildQueryString(queryString)}${currentView}`
203
224
  }
204
225
 
205
226
  build() {
@@ -207,7 +228,7 @@ class IframeExporter {
207
228
  let code = `<iframe width="${this.dimensions.width}" height="${this.dimensions.height}" frameborder="0" allowfullscreen allow="geolocation" src="${iframeUrl}"></iframe>`
208
229
  if (this.options.includeFullScreenLink) {
209
230
  const fullUrl = this.buildUrl({ scrollWheelZoom: true })
210
- code += `<p><a href="${fullUrl}">${L._('See full screen')}</a></p>`
231
+ code += `<p><a href="${fullUrl}">${translate('See full screen')}</a></p>`
211
232
  }
212
233
  return code
213
234
  }
@@ -71,15 +71,13 @@ export class FeatureUpdater extends BaseUpdater {
71
71
  upsert({ metadata, value }) {
72
72
  const { id, layerId } = metadata
73
73
  const datalayer = this.getDataLayerFromID(layerId)
74
- let feature = this.getFeatureFromMetadata(metadata, value)
75
-
76
- feature = datalayer.geoJSONToLeaflet({
77
- geometry: value.geometry,
78
- geojson: value,
79
- id,
80
- feature,
81
- })
82
- datalayer.addLayer(feature)
74
+ const feature = this.getFeatureFromMetadata(metadata, value)
75
+
76
+ if (feature) {
77
+ feature.geometry = value.geometry
78
+ } else {
79
+ datalayer.makeFeature(value)
80
+ }
83
81
  }
84
82
 
85
83
  // Update a property of an object
@@ -90,7 +88,8 @@ export class FeatureUpdater extends BaseUpdater {
90
88
  }
91
89
  if (key === 'geometry') {
92
90
  const datalayer = this.getDataLayerFromID(metadata.layerId)
93
- datalayer.geoJSONToLeaflet({ geometry: value, id: metadata.id, feature })
91
+ const feature = this.getFeatureFromMetadata(metadata, value)
92
+ feature.geometry = value
94
93
  } else {
95
94
  this.updateObjectValue(feature, key, value)
96
95
  feature.datalayer.indexProperties(feature)
@@ -89,15 +89,15 @@ export default class TableEditor extends WithTemplate {
89
89
  const bounds = this.map.getBounds()
90
90
  const inBbox = this.map.browser.options.inBbox
91
91
  let html = ''
92
- for (const feature of Object.values(this.datalayer._layers)) {
93
- if (feature.isFiltered()) continue
94
- if (inBbox && !feature.isOnScreen(bounds)) continue
92
+ this.datalayer.eachFeature((feature) => {
93
+ if (feature.isFiltered()) return
94
+ if (inBbox && !feature.isOnScreen(bounds)) return
95
95
  const tds = this.properties.map(
96
96
  (prop) =>
97
97
  `<td tabindex="0" data-property="${prop}">${feature.properties[prop] || ''}</td>`
98
98
  )
99
99
  html += `<tr data-feature="${feature.id}"><th><input type="checkbox" /></th>${tds.join('')}</tr>`
100
- }
100
+ })
101
101
  this.elements.body.innerHTML = html
102
102
  }
103
103
 
@@ -125,7 +125,7 @@ export default class TableEditor extends WithTemplate {
125
125
  .prompt(translate('Please enter the new name of this property'))
126
126
  .then(({ prompt }) => {
127
127
  if (!prompt || !this.validateName(prompt)) return
128
- this.datalayer.eachLayer((feature) => {
128
+ this.datalayer.eachFeature((feature) => {
129
129
  feature.renameProperty(property, prompt)
130
130
  })
131
131
  this.datalayer.deindexProperty(property)
@@ -140,7 +140,7 @@ export default class TableEditor extends WithTemplate {
140
140
  translate('Are you sure you want to delete this property on all the features?')
141
141
  )
142
142
  .then(() => {
143
- this.datalayer.eachLayer((feature) => {
143
+ this.datalayer.eachFeature((feature) => {
144
144
  feature.deleteProperty(property)
145
145
  })
146
146
  this.datalayer.deindexProperty(property)
@@ -318,7 +318,7 @@ export default class TableEditor extends WithTemplate {
318
318
  feature.del()
319
319
  }
320
320
  this.datalayer.show()
321
- this.datalayer.fire('datachanged')
321
+ this.datalayer.dataChanged()
322
322
  this.renderBody()
323
323
  if (this.map.browser.isOpen()) {
324
324
  this.map.browser.resetFilters()
@@ -97,9 +97,11 @@ export default class Dialog extends WithTemplate {
97
97
 
98
98
  currentZIndex() {
99
99
  return Math.max(
100
- ...Array.from(document.querySelectorAll('dialog')).map(
101
- (el) => window.getComputedStyle(el).getPropertyValue('z-index') || 0
102
- )
100
+ ...Array.from(document.querySelectorAll('dialog')).map((el) => {
101
+ const zIndex = window.getComputedStyle(el).getPropertyValue('z-index')
102
+ if (zIndex === 'auto') return 0
103
+ return zIndex || 0
104
+ })
103
105
  )
104
106
  }
105
107
 
@@ -127,7 +129,9 @@ export default class Dialog extends WithTemplate {
127
129
  this.hasFormData = this.elements.fieldset.elements.length > 0
128
130
 
129
131
  const currentZIndex = this.currentZIndex()
130
- if (currentZIndex) this.dialog.style.zIndex = currentZIndex + 1
132
+ if (currentZIndex) {
133
+ this.dialog.style.zIndex = currentZIndex + 1
134
+ }
131
135
 
132
136
  this.toggle(true)
133
137
 
@@ -240,12 +240,13 @@ export function greedyTemplate(str, data, ignore) {
240
240
  if (staticFallback !== undefined) {
241
241
  vars.push(staticFallback)
242
242
  }
243
- for (let i = 0; i < vars.length; i++) {
244
- path = vars[i]
245
- if (path.startsWith('"') && path.endsWith('"'))
243
+ for (const path of vars) {
244
+ if (path.startsWith('"') && path.endsWith('"')) {
246
245
  value = path.substring(1, path.length - 1) // static default value.
247
- else value = getValue(data, path.split('.'))
248
- if (value !== undefined) break
246
+ } else {
247
+ value = getValue(data, path.split('.'))
248
+ }
249
+ if (value !== undefined && value !== null) break
249
250
  }
250
251
  if (value === undefined) {
251
252
  if (ignore) value = str
@@ -301,6 +302,10 @@ export function flattenCoordinates(coords) {
301
302
  return coords
302
303
  }
303
304
 
305
+ export function polygonMustBeFlattened(coords) {
306
+ return coords.length === 1 && typeof coords?.[0]?.[0]?.[0] !== 'number'
307
+ }
308
+
304
309
  export function buildQueryString(params) {
305
310
  const query_string = []
306
311
  for (const key in params) {
@@ -381,19 +386,23 @@ export function toggleBadge(element, value) {
381
386
  export function loadTemplate(html) {
382
387
  const template = document.createElement('template')
383
388
  template.innerHTML = html
384
- .split('\n')
385
- .map((line) => line.trim())
386
- .join('')
387
389
  return template.content.firstElementChild
388
390
  }
389
391
 
392
+ export function loadTemplateWithRefs(html) {
393
+ const element = loadTemplate(html)
394
+ const elements = {}
395
+ for (const node of element.querySelectorAll('[data-ref]')) {
396
+ elements[node.dataset.ref] = node
397
+ }
398
+ return [element, elements]
399
+ }
400
+
390
401
  export class WithTemplate {
391
402
  loadTemplate(html) {
392
- this.element = loadTemplate(html)
393
- this.elements = {}
394
- for (const element of this.element.querySelectorAll('[data-ref]')) {
395
- this.elements[element.dataset.ref] = element
396
- }
403
+ const [element, elements] = loadTemplateWithRefs(html)
404
+ this.element = element
405
+ this.elements = elements
397
406
  return this.element
398
407
  }
399
408
  }