umap-project 3.4.0b3__py3-none-any.whl → 3.4.2__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 (185) hide show
  1. umap/__init__.py +1 -1
  2. umap/locale/da/LC_MESSAGES/django.mo +0 -0
  3. umap/locale/da/LC_MESSAGES/django.po +18 -14
  4. umap/locale/en/LC_MESSAGES/django.po +5 -1
  5. umap/locale/es/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/es/LC_MESSAGES/django.po +20 -16
  7. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  8. umap/locale/fr/LC_MESSAGES/django.po +18 -14
  9. umap/locale/pl/LC_MESSAGES/django.mo +0 -0
  10. umap/locale/pl/LC_MESSAGES/django.po +72 -71
  11. umap/static/umap/content.css +0 -3
  12. umap/static/umap/css/bar.css +9 -6
  13. umap/static/umap/css/form.css +25 -9
  14. umap/static/umap/css/popup.css +1 -0
  15. umap/static/umap/js/components/copiable.js +47 -0
  16. umap/static/umap/js/modules/autocomplete.js +31 -58
  17. umap/static/umap/js/modules/browser.js +4 -4
  18. umap/static/umap/js/modules/data/features.js +32 -35
  19. umap/static/umap/js/modules/data/fields.js +189 -23
  20. umap/static/umap/js/modules/data/layer.js +72 -87
  21. umap/static/umap/js/modules/domutils.js +21 -1
  22. umap/static/umap/js/modules/filters.js +13 -40
  23. umap/static/umap/js/modules/form/fields.js +4 -4
  24. umap/static/umap/js/modules/formatter.js +9 -1
  25. umap/static/umap/js/modules/help.js +12 -13
  26. umap/static/umap/js/modules/importer.js +17 -26
  27. umap/static/umap/js/modules/importers/banfr.js +0 -1
  28. umap/static/umap/js/modules/importers/cadastrefr.js +19 -19
  29. umap/static/umap/js/modules/importers/communesfr.js +7 -8
  30. umap/static/umap/js/modules/importers/datasets.js +14 -14
  31. umap/static/umap/js/modules/importers/geodatamine.js +20 -22
  32. umap/static/umap/js/modules/importers/opendata.js +10 -0
  33. umap/static/umap/js/modules/importers/overpass.js +19 -18
  34. umap/static/umap/js/modules/managers.js +1 -1
  35. umap/static/umap/js/modules/permissions.js +5 -3
  36. umap/static/umap/js/modules/rendering/controls.js +2 -2
  37. umap/static/umap/js/modules/rendering/icon.js +5 -9
  38. umap/static/umap/js/modules/rendering/layers/base.js +1 -1
  39. umap/static/umap/js/modules/rendering/layers/classified.js +15 -10
  40. umap/static/umap/js/modules/rendering/layers/heat.js +1 -0
  41. umap/static/umap/js/modules/rendering/map.js +22 -22
  42. umap/static/umap/js/modules/rendering/popup.js +6 -3
  43. umap/static/umap/js/modules/rendering/template.js +28 -34
  44. umap/static/umap/js/modules/rendering/ui.js +1 -2
  45. umap/static/umap/js/modules/rules.js +34 -41
  46. umap/static/umap/js/modules/schema.js +0 -7
  47. umap/static/umap/js/modules/share.js +36 -69
  48. umap/static/umap/js/modules/slideshow.js +3 -3
  49. umap/static/umap/js/modules/tableeditor.js +0 -1
  50. umap/static/umap/js/modules/ui/bar.js +51 -32
  51. umap/static/umap/js/modules/ui/panel.js +26 -21
  52. umap/static/umap/js/modules/ui/tooltip.js +1 -1
  53. umap/static/umap/js/modules/umap.js +75 -80
  54. umap/static/umap/js/modules/utils.js +12 -3
  55. umap/static/umap/js/umap.controls.js +33 -14
  56. umap/static/umap/locale/am_ET.js +6 -4
  57. umap/static/umap/locale/am_ET.json +6 -4
  58. umap/static/umap/locale/ar.js +6 -4
  59. umap/static/umap/locale/ar.json +6 -4
  60. umap/static/umap/locale/ast.js +6 -4
  61. umap/static/umap/locale/ast.json +6 -4
  62. umap/static/umap/locale/bg.js +6 -4
  63. umap/static/umap/locale/bg.json +6 -4
  64. umap/static/umap/locale/br.js +19 -8
  65. umap/static/umap/locale/br.json +19 -8
  66. umap/static/umap/locale/ca.js +6 -4
  67. umap/static/umap/locale/ca.json +6 -4
  68. umap/static/umap/locale/cs_CZ.js +7 -5
  69. umap/static/umap/locale/cs_CZ.json +7 -5
  70. umap/static/umap/locale/da.js +8 -6
  71. umap/static/umap/locale/da.json +8 -6
  72. umap/static/umap/locale/de.js +38 -36
  73. umap/static/umap/locale/de.json +38 -36
  74. umap/static/umap/locale/el.js +7 -5
  75. umap/static/umap/locale/el.json +7 -5
  76. umap/static/umap/locale/en.js +7 -5
  77. umap/static/umap/locale/en.json +7 -5
  78. umap/static/umap/locale/en_US.json +6 -4
  79. umap/static/umap/locale/es.js +19 -17
  80. umap/static/umap/locale/es.json +19 -17
  81. umap/static/umap/locale/et.js +7 -5
  82. umap/static/umap/locale/et.json +7 -5
  83. umap/static/umap/locale/eu.js +23 -21
  84. umap/static/umap/locale/eu.json +23 -21
  85. umap/static/umap/locale/fa_IR.js +7 -5
  86. umap/static/umap/locale/fa_IR.json +7 -5
  87. umap/static/umap/locale/fi.js +6 -4
  88. umap/static/umap/locale/fi.json +6 -4
  89. umap/static/umap/locale/fr.js +8 -6
  90. umap/static/umap/locale/fr.json +8 -6
  91. umap/static/umap/locale/gl.js +147 -145
  92. umap/static/umap/locale/gl.json +147 -145
  93. umap/static/umap/locale/he.js +6 -4
  94. umap/static/umap/locale/he.json +6 -4
  95. umap/static/umap/locale/hr.js +6 -4
  96. umap/static/umap/locale/hr.json +6 -4
  97. umap/static/umap/locale/hu.js +7 -5
  98. umap/static/umap/locale/hu.json +7 -5
  99. umap/static/umap/locale/id.js +6 -4
  100. umap/static/umap/locale/id.json +6 -4
  101. umap/static/umap/locale/is.js +7 -5
  102. umap/static/umap/locale/is.json +7 -5
  103. umap/static/umap/locale/it.js +7 -5
  104. umap/static/umap/locale/it.json +7 -5
  105. umap/static/umap/locale/ja.js +6 -4
  106. umap/static/umap/locale/ja.json +6 -4
  107. umap/static/umap/locale/ko.js +6 -4
  108. umap/static/umap/locale/ko.json +6 -4
  109. umap/static/umap/locale/lt.js +6 -4
  110. umap/static/umap/locale/lt.json +6 -4
  111. umap/static/umap/locale/ms.js +7 -5
  112. umap/static/umap/locale/ms.json +7 -5
  113. umap/static/umap/locale/nl.js +7 -5
  114. umap/static/umap/locale/nl.json +7 -5
  115. umap/static/umap/locale/no.js +6 -4
  116. umap/static/umap/locale/no.json +6 -4
  117. umap/static/umap/locale/pl.js +53 -51
  118. umap/static/umap/locale/pl.json +53 -51
  119. umap/static/umap/locale/pl_PL.json +6 -4
  120. umap/static/umap/locale/pt.js +7 -5
  121. umap/static/umap/locale/pt.json +7 -5
  122. umap/static/umap/locale/pt_BR.js +6 -4
  123. umap/static/umap/locale/pt_BR.json +6 -4
  124. umap/static/umap/locale/pt_PT.js +6 -4
  125. umap/static/umap/locale/pt_PT.json +6 -4
  126. umap/static/umap/locale/ro.js +6 -4
  127. umap/static/umap/locale/ro.json +6 -4
  128. umap/static/umap/locale/ru.js +6 -4
  129. umap/static/umap/locale/ru.json +6 -4
  130. umap/static/umap/locale/sk_SK.js +6 -4
  131. umap/static/umap/locale/sk_SK.json +6 -4
  132. umap/static/umap/locale/sl.js +6 -4
  133. umap/static/umap/locale/sl.json +6 -4
  134. umap/static/umap/locale/sr.js +6 -4
  135. umap/static/umap/locale/sr.json +6 -4
  136. umap/static/umap/locale/sv.js +6 -4
  137. umap/static/umap/locale/sv.json +6 -4
  138. umap/static/umap/locale/th_TH.js +6 -4
  139. umap/static/umap/locale/th_TH.json +6 -4
  140. umap/static/umap/locale/tr.js +6 -4
  141. umap/static/umap/locale/tr.json +6 -4
  142. umap/static/umap/locale/uk_UA.js +6 -4
  143. umap/static/umap/locale/uk_UA.json +6 -4
  144. umap/static/umap/locale/vi.js +6 -4
  145. umap/static/umap/locale/vi.json +6 -4
  146. umap/static/umap/locale/vi_VN.json +6 -4
  147. umap/static/umap/locale/zh.js +6 -4
  148. umap/static/umap/locale/zh.json +6 -4
  149. umap/static/umap/locale/zh_CN.json +6 -4
  150. umap/static/umap/locale/zh_TW.Big5.json +6 -4
  151. umap/static/umap/locale/zh_TW.js +20 -18
  152. umap/static/umap/locale/zh_TW.json +20 -18
  153. umap/static/umap/map.css +5 -4
  154. umap/static/umap/unittests/utils.js +7 -7
  155. umap/templates/umap/content_footer.html +1 -0
  156. umap/templates/umap/css.html +0 -2
  157. umap/templates/umap/js.html +1 -3
  158. umap/tests/integration/conftest.py +3 -2
  159. umap/tests/integration/test_anonymous_owned_map.py +1 -1
  160. umap/tests/integration/test_conditional_rules.py +106 -51
  161. umap/tests/integration/test_draw_polygon.py +4 -0
  162. umap/tests/integration/test_draw_polyline.py +11 -0
  163. umap/tests/integration/test_edit_datalayer.py +1 -1
  164. umap/tests/integration/test_fields.py +19 -0
  165. umap/tests/integration/test_iframe.py +1 -1
  166. umap/tests/integration/test_import.py +23 -0
  167. umap/tests/integration/test_map.py +2 -2
  168. umap/tests/integration/test_owned_map.py +2 -2
  169. umap/tests/integration/test_popup.py +31 -0
  170. umap/tests/integration/test_remote_data.py +4 -4
  171. umap/tests/integration/test_search.py +41 -0
  172. umap/tests/integration/test_share.py +2 -2
  173. umap/tests/integration/test_team.py +1 -1
  174. umap/tests/integration/test_websocket_sync.py +6 -1
  175. umap/tests/test_utils.py +4 -1
  176. umap/utils.py +1 -0
  177. {umap_project-3.4.0b3.dist-info → umap_project-3.4.2.dist-info}/METADATA +15 -15
  178. {umap_project-3.4.0b3.dist-info → umap_project-3.4.2.dist-info}/RECORD +181 -183
  179. umap/static/umap/js/umap.core.js +0 -93
  180. umap/static/umap/vendors/editinosm/Leaflet.EditInOSM.css +0 -46
  181. umap/static/umap/vendors/editinosm/Leaflet.EditInOSM.js +0 -240
  182. umap/static/umap/vendors/editinosm/edit-in-osm.png +0 -0
  183. {umap_project-3.4.0b3.dist-info → umap_project-3.4.2.dist-info}/WHEEL +0 -0
  184. {umap_project-3.4.0b3.dist-info → umap_project-3.4.2.dist-info}/entry_points.txt +0 -0
  185. {umap_project-3.4.0b3.dist-info → umap_project-3.4.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,12 +1,14 @@
1
- import { DomEvent, DomUtil } from '../../../vendors/leaflet/leaflet-src.esm.js'
1
+ import { DomEvent } from '../../../vendors/leaflet/leaflet-src.esm.js'
2
2
  import { translate } from '../i18n.js'
3
+ import * as DOMUtils from '../domutils.js'
3
4
 
4
5
  export class Panel {
5
6
  constructor(umap, leafletMap) {
6
7
  this.parent = leafletMap._controlContainer
7
8
  this._umap = umap
8
9
  this._leafletMap = leafletMap
9
- this.container = DomUtil.create('div', '', this.parent)
10
+ this.container = document.createElement('div')
11
+ this.parent.appendChild(this.container)
10
12
  // This will be set once according to the panel configured at load
11
13
  // or by using panels as popups
12
14
  this.mode = null
@@ -37,30 +39,33 @@ export class Panel {
37
39
  }
38
40
  document.body.classList.add(`panel-${this.className.split(' ')[0]}-on`)
39
41
  this.container.innerHTML = ''
40
- const actionsContainer = DomUtil.create('ul', 'buttons', this.container)
41
- const body = DomUtil.create('div', 'body', this.container)
42
+ const template = `
43
+ <div>
44
+ <ul class="buttons" data-ref="buttons">
45
+ <li><button class="icon icon-16 icon-close" data-ref="close" title="${translate('Close')}"></button></li>
46
+ <li><button class="icon icon-16 icon-resize" data-ref="resize" title="${translate('Toggle size')}"></button></li>
47
+ </ul>
48
+ <div class="body" data-ref="body">
49
+ </div>
50
+ </div>
51
+ `
52
+ const [root, { close, resize, body, buttons }] =
53
+ DOMUtils.loadTemplateWithRefs(template)
42
54
  body.appendChild(content)
43
- const closeButton = DomUtil.createButtonIcon(
44
- DomUtil.create('li', '', actionsContainer),
45
- 'icon-close',
46
- translate('Close')
47
- )
48
- const resizeButton = DomUtil.createButtonIcon(
49
- DomUtil.create('li', '', actionsContainer),
50
- 'icon-resize',
51
- translate('Toggle size')
52
- )
55
+ this.container.appendChild(root)
53
56
  for (const action of actions) {
54
- const element = DomUtil.element({ tagName: 'li', parent: actionsContainer })
55
- element.appendChild(action)
57
+ const li = document.createElement('li')
58
+ li.appendChild(action)
59
+ buttons.appendChild(li)
56
60
  }
57
- if (className) DomUtil.addClass(body, className)
61
+ if (className) body.classList.add(className)
58
62
  const promise = new Promise((resolve, reject) => {
59
63
  if (isOpen) {
60
64
  resolve(this)
61
65
  } else {
66
+ this.container.classList.add('on')
62
67
  Promise.all(
63
- this.container.getAnimations().map((animation) => animation.finished)
68
+ this.container.getAnimations?.().map((animation) => animation.finished)
64
69
  )
65
70
  .then(() => {
66
71
  resolve(this)
@@ -70,11 +75,10 @@ export class Panel {
70
75
  // were cancelled, we want the new panel callback to be called anyway.
71
76
  resolve(this)
72
77
  })
73
- this.container.classList.add('on')
74
78
  }
75
79
  })
76
- DomEvent.on(closeButton, 'click', this.close, this)
77
- DomEvent.on(resizeButton, 'click', this.resize, this)
80
+ close.addEventListener('click', () => this.close())
81
+ resize.addEventListener('click', () => this.resize())
78
82
  return promise
79
83
  }
80
84
 
@@ -102,6 +106,7 @@ export class Panel {
102
106
  this._leafletMap.invalidateSize({ pan: false })
103
107
  }
104
108
  }
109
+
105
110
  scrollTo(selector) {
106
111
  const fieldset = this.container.querySelector(selector)
107
112
  if (!fieldset) return
@@ -27,7 +27,7 @@ export default class Tooltip extends Positioned {
27
27
  this.parent.appendChild(this.container)
28
28
  this.openAt(opts)
29
29
  }
30
- this.TOOLTIP_ID = window.setTimeout(L.bind(showIt, this), opts.delay || 0)
30
+ this.TOOLTIP_ID = window.setTimeout(() => showIt(), opts.delay || 0)
31
31
  const id = this.TOOLTIP_ID
32
32
  const closeIt = () => {
33
33
  this.close(id)
@@ -1,8 +1,3 @@
1
- import {
2
- DomUtil,
3
- Util as LeafletUtil,
4
- latLngBounds,
5
- } from '../../vendors/leaflet/leaflet-src.esm.js'
6
1
  import {
7
2
  uMapAlert as Alert,
8
3
  uMapAlertCreation as AlertCreation,
@@ -261,15 +256,6 @@ export default class Umap {
261
256
  return window.self !== window.top
262
257
  }
263
258
 
264
- get fieldKeys() {
265
- return Array.from(
266
- new Set([
267
- ...this.fields.keys(),
268
- ...this.datalayers.active().reduce((acc, dl) => acc.concat(dl.fieldKeys), []),
269
- ])
270
- )
271
- }
272
-
273
259
  setPropertiesFromQueryString() {
274
260
  const asBoolean = (key) => {
275
261
  const value = this.searchParams.get(key)
@@ -681,7 +667,7 @@ export default class Umap {
681
667
  const parent = this._leafletMap.getPane('overlayPane')
682
668
  const datalayers = Object.values(this.datalayers)
683
669
  .filter((datalayer) => !datalayer._isDeleted)
684
- .sort((datalayer1, datalayer2) => datalayer1.rank > datalayer2.rank)
670
+ .sort((datalayer1, datalayer2) => datalayer1.rank - datalayer2.rank)
685
671
  for (const datalayer of datalayers) {
686
672
  const child = parent.querySelector(`[data-id="${datalayer.id}"]`)
687
673
  parent.appendChild(child)
@@ -773,14 +759,19 @@ export default class Umap {
773
759
  editCaption() {
774
760
  if (!this.editEnabled) return
775
761
  if (this.properties.editMode !== 'advanced') return
776
- const container = DomUtil.create('div')
762
+ const container = DOMUtils.loadTemplate(`
763
+ <div>
764
+ <h3>
765
+ <i class="icon icon-16 icon-info"></i>
766
+ ${translate('Edit map details')}
767
+ </h3>
768
+ </div>
769
+ `)
777
770
  const metadataFields = [
778
771
  'properties.name',
779
772
  'properties.description',
780
773
  'properties.is_template',
781
774
  ]
782
-
783
- DomUtil.createTitle(container, translate('Edit map details'), 'icon-info')
784
775
  const builder = new MutatingForm(this, metadataFields, {
785
776
  className: 'map-metadata',
786
777
  umap: this,
@@ -788,13 +779,13 @@ export default class Umap {
788
779
  const form = builder.build()
789
780
  container.appendChild(form)
790
781
 
791
- const tags = DomUtil.createFieldset(container, translate('Tags'))
782
+ const tags = DOMUtils.createFieldset(container, translate('Tags'))
792
783
  const tagsFields = ['properties.tags']
793
784
  const tagsBuilder = new MutatingForm(this, tagsFields, {
794
785
  umap: this,
795
786
  })
796
787
  tags.appendChild(tagsBuilder.build())
797
- const credits = DomUtil.createFieldset(container, translate('Credits'))
788
+ const credits = DOMUtils.createFieldset(container, translate('Credits'))
798
789
  const creditsFields = [
799
790
  'properties.licence',
800
791
  'properties.shortCredit',
@@ -810,7 +801,11 @@ export default class Umap {
810
801
  editCenter() {
811
802
  if (!this.editEnabled) return
812
803
  if (this.properties.editMode !== 'advanced') return
813
- const container = DomUtil.create('div')
804
+ const container = DOMUtils.loadTemplate(`
805
+ <div>
806
+ <h3><i class="icon icon-16 icon-zoom"></i>${translate('Edit map default view')}</h3>
807
+ </div>
808
+ `)
814
809
  const metadataFields = [
815
810
  ['properties.zoom', { handler: 'IntInput', label: translate('Default zoom') }],
816
811
  [
@@ -824,13 +819,12 @@ export default class Umap {
824
819
  'properties.defaultView',
825
820
  ]
826
821
 
827
- DomUtil.createTitle(container, translate('Edit map default view'), 'icon-zoom')
828
822
  const builder = new MutatingForm(this, metadataFields, {
829
823
  className: 'map-metadata',
830
824
  umap: this,
831
825
  })
832
826
  const form = builder.build()
833
- const button = Utils.loadTemplate(
827
+ const button = DOMUtils.loadTemplate(
834
828
  `<button type="button">${translate('Use current center and zoom')}</button>`
835
829
  )
836
830
  button.addEventListener('click', () => {
@@ -859,7 +853,7 @@ export default class Umap {
859
853
  'properties.layerSwitcher',
860
854
  ])
861
855
  const builder = new MutatingForm(this, UIFields, { umap: this })
862
- const controlsOptions = DomUtil.createFieldset(
856
+ const controlsOptions = DOMUtils.createFieldset(
863
857
  container,
864
858
  translate('User interface options')
865
859
  )
@@ -883,7 +877,7 @@ export default class Umap {
883
877
  ]
884
878
 
885
879
  const builder = new MutatingForm(this, shapeOptions, { umap: this })
886
- const defaultShapeProperties = DomUtil.createFieldset(
880
+ const defaultShapeProperties = DOMUtils.createFieldset(
887
881
  container,
888
882
  translate('Default shape properties')
889
883
  )
@@ -901,7 +895,7 @@ export default class Umap {
901
895
  ]
902
896
 
903
897
  const builder = new MutatingForm(this, shapeOptions, { umap: this })
904
- const defaultShapeProperties = DomUtil.createFieldset(
898
+ const defaultShapeProperties = DOMUtils.createFieldset(
905
899
  container,
906
900
  translate('Default properties')
907
901
  )
@@ -919,7 +913,7 @@ export default class Umap {
919
913
  'properties.outlinkTarget',
920
914
  ]
921
915
  const builder = new MutatingForm(this, popupFields, { umap: this })
922
- const popupFieldset = DomUtil.createFieldset(
916
+ const popupFieldset = DOMUtils.createFieldset(
923
917
  container,
924
918
  translate('Default interaction options')
925
919
  )
@@ -971,7 +965,7 @@ export default class Umap {
971
965
  { handler: 'Switch', label: translate('TMS format') },
972
966
  ],
973
967
  ]
974
- const customTilelayer = DomUtil.createFieldset(
968
+ const customTilelayer = DOMUtils.createFieldset(
975
969
  container,
976
970
  translate('Custom background')
977
971
  )
@@ -1022,7 +1016,7 @@ export default class Umap {
1022
1016
  ],
1023
1017
  ['properties.overlay.tms', { handler: 'Switch', label: translate('TMS format') }],
1024
1018
  ]
1025
- const overlay = DomUtil.createFieldset(container, translate('Custom overlay'))
1019
+ const overlay = DOMUtils.createFieldset(container, translate('Custom overlay'))
1026
1020
  const builder = new MutatingForm(this, overlayFields, { umap: this })
1027
1021
  overlay.appendChild(builder.build())
1028
1022
  }
@@ -1031,7 +1025,7 @@ export default class Umap {
1031
1025
  if (!Utils.isObject(this.properties.limitBounds)) {
1032
1026
  this.properties.limitBounds = {}
1033
1027
  }
1034
- const limitBounds = DomUtil.createFieldset(container, translate('Limit bounds'))
1028
+ const limitBounds = DOMUtils.createFieldset(container, translate('Limit bounds'))
1035
1029
  const boundsFields = [
1036
1030
  [
1037
1031
  'properties.limitBounds.south',
@@ -1052,28 +1046,29 @@ export default class Umap {
1052
1046
  ]
1053
1047
  const boundsBuilder = new MutatingForm(this, boundsFields, { umap: this })
1054
1048
  limitBounds.appendChild(boundsBuilder.build())
1055
- const boundsButtons = DomUtil.create('div', 'button-bar half', limitBounds)
1056
- DomUtil.createButton(
1057
- 'button',
1058
- boundsButtons,
1059
- translate('Use current bounds'),
1060
- () => {
1061
- const bounds = this._leafletMap.getBounds()
1062
- const oldLimitBounds = { ...this.properties.limitBounds }
1063
- this.properties.limitBounds.south = LeafletUtil.formatNum(bounds.getSouth())
1064
- this.properties.limitBounds.west = LeafletUtil.formatNum(bounds.getWest())
1065
- this.properties.limitBounds.north = LeafletUtil.formatNum(bounds.getNorth())
1066
- this.properties.limitBounds.east = LeafletUtil.formatNum(bounds.getEast())
1067
- boundsBuilder.fetchAll()
1068
- this.sync.update(
1069
- 'properties.limitBounds',
1070
- this.properties.limitBounds,
1071
- oldLimitBounds
1072
- )
1073
- this._leafletMap.handleLimitBounds()
1074
- }
1075
- )
1076
- DomUtil.createButton('button', boundsButtons, translate('Empty'), () => {
1049
+ const [boundsButtons, { current, empty }] = DOMUtils.loadTemplateWithRefs(`
1050
+ <div class="button-bar half">
1051
+ <button type="button" data-ref="current">${translate('Use current bounds')}</button>
1052
+ <button type="button" data-ref="empty">${translate('Empty')}</button>
1053
+ </div>
1054
+ `)
1055
+ limitBounds.appendChild(boundsButtons)
1056
+ current.addEventListener('click', () => {
1057
+ const bounds = this._leafletMap.getBounds()
1058
+ const oldLimitBounds = { ...this.properties.limitBounds }
1059
+ this.properties.limitBounds.south = bounds.getSouth().toFixed(6)
1060
+ this.properties.limitBounds.west = bounds.getWest().toFixed(6)
1061
+ this.properties.limitBounds.north = bounds.getNorth().toFixed(6)
1062
+ this.properties.limitBounds.east = bounds.getEast().toFixed(6)
1063
+ boundsBuilder.fetchAll()
1064
+ this.sync.update(
1065
+ 'properties.limitBounds',
1066
+ this.properties.limitBounds,
1067
+ oldLimitBounds
1068
+ )
1069
+ this._leafletMap.handleLimitBounds()
1070
+ })
1071
+ empty.addEventListener('click', () => {
1077
1072
  const oldLimitBounds = { ...this.properties.limitBounds }
1078
1073
  this.properties.limitBounds.south = null
1079
1074
  this.properties.limitBounds.west = null
@@ -1090,7 +1085,7 @@ export default class Umap {
1090
1085
  }
1091
1086
 
1092
1087
  _editSlideshow(container) {
1093
- const slideshow = DomUtil.createFieldset(container, translate('Slideshow'))
1088
+ const slideshow = DOMUtils.createFieldset(container, translate('Slideshow'))
1094
1089
  const slideshowFields = [
1095
1090
  [
1096
1091
  'properties.slideshow.active',
@@ -1123,7 +1118,10 @@ export default class Umap {
1123
1118
  }
1124
1119
 
1125
1120
  _editSync(container) {
1126
- const sync = DomUtil.createFieldset(container, translate('Real-time collaboration'))
1121
+ const sync = DOMUtils.createFieldset(
1122
+ container,
1123
+ translate('Real-time collaboration')
1124
+ )
1127
1125
  const builder = new MutatingForm(this, ['properties.syncEnabled'], {
1128
1126
  umap: this,
1129
1127
  })
@@ -1131,7 +1129,7 @@ export default class Umap {
1131
1129
  }
1132
1130
 
1133
1131
  _advancedActions(container) {
1134
- const advancedActions = DomUtil.createFieldset(
1132
+ const advancedActions = DOMUtils.createFieldset(
1135
1133
  container,
1136
1134
  translate('Advanced actions')
1137
1135
  )
@@ -1155,7 +1153,7 @@ export default class Umap {
1155
1153
  </div>
1156
1154
  `
1157
1155
  const [bar, { del, clear, empty, clone, download }] =
1158
- Utils.loadTemplateWithRefs(tpl)
1156
+ DOMUtils.loadTemplateWithRefs(tpl)
1159
1157
  advancedActions.appendChild(bar)
1160
1158
  if (this.permissions.isOwner()) {
1161
1159
  del.hidden = false
@@ -1172,12 +1170,11 @@ export default class Umap {
1172
1170
  edit() {
1173
1171
  if (!this.editEnabled) return
1174
1172
  if (this.properties.editMode !== 'advanced') return
1175
- const container = DomUtil.create('div')
1176
- DomUtil.createTitle(
1177
- container,
1178
- translate('Map advanced properties'),
1179
- 'icon-settings'
1180
- )
1173
+ const container = DOMUtils.loadTemplate(`
1174
+ <div>
1175
+ <h3><i class="icon icon-16 icon-settings"></i>${translate('Map advanced properties')}</h3>
1176
+ </div>
1177
+ `)
1181
1178
  this._editControls(container)
1182
1179
  this._editShapeProperties(container)
1183
1180
  this._editDefaultKeys(container)
@@ -1609,9 +1606,11 @@ export default class Umap {
1609
1606
  else if (finalIndex > initialIndex) movedLayer.insertBefore(targetLayer)
1610
1607
  else movedLayer.insertAfter(targetLayer)
1611
1608
  this.sync.startBatch()
1612
- this.datalayers.reverse().map((datalayer) => {
1609
+ this.datalayers.reverse().map(async (datalayer) => {
1613
1610
  const rank = datalayer.getDOMOrder()
1614
1611
  if (rank >= minIndex && rank <= maxIndex) {
1612
+ // TODO allow to save only metadata instead of force loading data
1613
+ if (!datalayer.isLoaded()) await datalayer.fetchData()
1615
1614
  const oldRank = datalayer.rank
1616
1615
  datalayer.rank = rank
1617
1616
  datalayer.sync.update('options.rank', rank, oldRank)
@@ -1623,14 +1622,13 @@ export default class Umap {
1623
1622
  }
1624
1623
  const orderable = new Orderable(ul, onReorder)
1625
1624
 
1626
- const bar = DomUtil.create('div', 'button-bar', container)
1627
- DomUtil.createButton(
1628
- 'show-on-edit block add-datalayer button',
1629
- bar,
1630
- translate('Add a layer'),
1631
- this.newDataLayer,
1632
- this
1633
- )
1625
+ const [bar, { button }] = DOMUtils.loadTemplateWithRefs(`
1626
+ <div class="button-bar">
1627
+ <button type="button" class="show-on-edit block add-datalayer" data-ref="button">${translate('Add a layer')}</button>
1628
+ </div>
1629
+ `)
1630
+ button.addEventListener('click', () => this.newDataLayer())
1631
+ container.appendChild(bar)
1634
1632
 
1635
1633
  this.editPanel.open({ content: container, highlight: 'layers' })
1636
1634
  }
@@ -1738,6 +1736,7 @@ export default class Umap {
1738
1736
  const fields = Object.keys(importedData.properties).map(
1739
1737
  (field) => `properties.${field}`
1740
1738
  )
1739
+ this.fields.pull()
1741
1740
  this.filters.load()
1742
1741
  this.render(fields)
1743
1742
  this._leafletMap._setDefaultCenter()
@@ -1790,16 +1789,12 @@ export default class Umap {
1790
1789
  await this.server.post(sendLink, {}, formData)
1791
1790
  }
1792
1791
 
1793
- getLayersBounds() {
1794
- const bounds = new latLngBounds()
1795
- this.datalayers.browsable().map((d) => {
1796
- if (d.isVisible()) bounds.extend(d.layer.getBounds())
1797
- })
1798
- return bounds
1799
- }
1800
-
1801
1792
  fitDataBounds() {
1802
- const bounds = this.getLayersBounds()
1793
+ const layers = this.datalayers
1794
+ .browsable()
1795
+ .filter((d) => d.isVisible())
1796
+ .map((d) => d.layer)
1797
+ const bounds = this._leafletMap.getLayersBounds(layers)
1803
1798
  if (!this.hasData() || !bounds.isValid()) return false
1804
1799
  this._leafletMap.fitBounds(bounds)
1805
1800
  }
@@ -177,15 +177,15 @@ export function toHTML(r, options) {
177
177
  // iframe
178
178
  r = r.replace(
179
179
  /{{{(https?[^|{]*)}}}/g,
180
- '<div><iframe frameborder="0" src="$1" width="100%" height="300px"></iframe></div>'
180
+ '<div><iframe allowfullscreen src="$1" style="width: 100%; height: 300px; border: 0;"></iframe></div>'
181
181
  )
182
182
  r = r.replace(
183
183
  /{{{(https?[^|{]*)\|(\d*)(px)?}}}/g,
184
- '<div><iframe frameborder="0" src="$1" width="100%" height="$2px"></iframe></div>'
184
+ '<div><iframe allowfullscreen src="$1" style="width: 100%; height: $2px; border: 0;"></iframe></div>'
185
185
  )
186
186
  r = r.replace(
187
187
  /{{{(https?[^|{]*)\|(\d*)(px)?\*(\d*)(px)?}}}/g,
188
- '<div><iframe frameborder="0" src="$1" width="$4px" height="$2px"></iframe></div>'
188
+ '<div><iframe allowfullscreen src="$1" style="width: $4px; height: $2px; border: 0;"></iframe></div>'
189
189
  )
190
190
 
191
191
  // images
@@ -681,3 +681,12 @@ export const COLORS = [
681
681
  'Ivory',
682
682
  'White',
683
683
  ]
684
+
685
+ export const LatLngIsValid = (latlng) => {
686
+ return (
687
+ Number.isFinite(latlng.lat) &&
688
+ Math.abs(latlng.lat) <= 90 &&
689
+ Number.isFinite(latlng.lng) &&
690
+ Math.abs(latlng.lng) <= 180
691
+ )
692
+ }
@@ -45,14 +45,12 @@ U.TileLayerControl = L.Control.IconLayers.extend({
45
45
  const lastRow = this._container.querySelector(
46
46
  '.leaflet-iconLayers-layersRow:last-child'
47
47
  )
48
- const button = L.DomUtil.element({
49
- tagName: 'button',
50
- className:
51
- 'leaflet-iconLayers-layerCell leaflet-iconLayers-layerCell-plus button',
52
- textContent: '+',
53
- parent: lastRow,
54
- })
55
- L.DomEvent.on(button, 'click', () =>
48
+ const button = document.createElement('button')
49
+ button.className =
50
+ 'leaflet-iconLayers-layerCell leaflet-iconLayers-layerCell-plus button'
51
+ button.textContent = '+'
52
+ lastRow.appendChild(button)
53
+ button.addEventListener('click', () =>
56
54
  this.map._controls.tilelayersChooser.openSwitcher()
57
55
  )
58
56
  },
@@ -130,7 +128,7 @@ U.Search = L.PhotonSearch.extend({
130
128
  this.hide()
131
129
  const { lat, lng } = pattern.exec(this.input.value).groups
132
130
  const latlng = L.latLng(lat, lng)
133
- if (latlng.isValid()) {
131
+ if (U.Utils.LatLngIsValid(latlng)) {
134
132
  this.reverse.doReverse(latlng)
135
133
  } else {
136
134
  U.Alert.error(L._('Invalid latitude or longitude'))
@@ -175,8 +173,8 @@ U.Search = L.PhotonSearch.extend({
175
173
  if (!osm_type || !osm_id) return
176
174
  const importer = this.map._umap.importer
177
175
  importer.build()
178
- importer.format = 'osm'
179
- importer.url = `https://www.openstreetmap.org/api/0.6/${osm_type}/${osm_id}/full`
176
+ importer.format = 'geojson'
177
+ importer.raw = await this.getOSMObject(osm_type, osm_id)
180
178
  importer.submit()
181
179
  })
182
180
  el.appendChild(tools)
@@ -197,6 +195,18 @@ U.Search = L.PhotonSearch.extend({
197
195
  })
198
196
  },
199
197
 
198
+ async getOSMObject(osm_type, osm_id) {
199
+ const url = `https://www.openstreetmap.org/api/0.6/${osm_type}/${osm_id}/full`
200
+ const response = await this.map._umap.request.get(url)
201
+ if (response?.ok) {
202
+ const data = await this.map._umap.formatter.fromOSM(await response.text())
203
+ data.features = data.features.filter(
204
+ (feature) => feature.properties.id === `${osm_type}/${osm_id}`
205
+ )
206
+ return JSON.stringify(data)
207
+ }
208
+ },
209
+
200
210
  setChoice: function (choice) {
201
211
  choice = choice || this.RESULTS[this.CURRENT]
202
212
  if (choice) {
@@ -230,7 +240,8 @@ L.Control.MiniMap.include({
230
240
 
231
241
  L.Control.Loading.include({
232
242
  onAdd: function (map) {
233
- this._container = L.DomUtil.create('div', 'umap-loader', map._controlContainer)
243
+ this._container = document.createElement('div')
244
+ this._container.classList.add('umap-loader')
234
245
  map.on('baselayerchange', this._layerAdd, this)
235
246
  this._addMapListeners(map)
236
247
  this._map = map
@@ -252,9 +263,10 @@ U.Editable = L.Editable.extend({
252
263
  this.on('editable:drawing:click editable:drawing:move', this.drawingTooltip)
253
264
  // Layer for items added by users
254
265
  this.on('editable:drawing:cancel', (event) => {
255
- if (event.layer instanceof U.LeafletMarker) event.layer.feature.del()
266
+ this.resetButtons()
256
267
  })
257
268
  this.on('editable:drawing:commit', function (event) {
269
+ this.resetButtons()
258
270
  if (this._umap.editedFeature !== event.layer) {
259
271
  const promise = event.layer.feature.edit(event)
260
272
  if (event.layer.feature.isRoute?.()) {
@@ -278,6 +290,13 @@ U.Editable = L.Editable.extend({
278
290
  this.on('editable:vertex:rawclick', this.onVertexRawClick)
279
291
  },
280
292
 
293
+ resetButtons: () => {
294
+ const buttons = document.querySelectorAll('.umap-edit-bar .drawing-tool')
295
+ for (const button of buttons) {
296
+ button.classList.remove('on')
297
+ }
298
+ },
299
+
281
300
  startRoute: function (latlng) {
282
301
  const feature = this.createLineString()
283
302
  feature.askForRouteSettings().then(async () => {
@@ -402,7 +421,7 @@ U.Editable = L.Editable.extend({
402
421
  // (eg. line has only one drawn point)
403
422
  // So let's check if the layer has no more shape
404
423
  event.layer.feature.pullGeometry(false)
405
- if (!event.layer.feature.hasGeom()) {
424
+ if (!event.layer.feature.hasGeom() || event.layer instanceof U.LeafletMarker) {
406
425
  event.layer.feature.del()
407
426
  } else {
408
427
  event.layer.feature.onCommit()
@@ -99,7 +99,6 @@ const locale = {
99
99
  "Delete this vertex (Alt+Click)": "Delete this vertex (Alt+Click)",
100
100
  "Delete": "ሰርዝ",
101
101
  "description": "መገለጫ",
102
- "Direct link": "Direct link",
103
102
  "Directions from here": "ከዚህ የሚነሱ አቅጣጫዎች",
104
103
  "Display label": "Display label",
105
104
  "Display measure": "Display measure",
@@ -135,7 +134,6 @@ const locale = {
135
134
  "Edit this feature": "ይህንን ፊቸር አርም",
136
135
  "Edit": "አርም",
137
136
  "Embed and link options": "Embed and link options",
138
- "Embed the map": "ካርታውን አካትት",
139
137
  "Emoji & Character": "Emoji & Character",
140
138
  "Empty": "ባዶ",
141
139
  "Equidistant": "Equidistant",
@@ -295,7 +293,6 @@ const locale = {
295
293
  "settings": "settings",
296
294
  "Shape properties": "Shape properties",
297
295
  "Share and download": "Share and download",
298
- "Share this link to open a customized map view": "Share this link to open a customized map view",
299
296
  "Short credits": "አጭር ክሬዲት",
300
297
  "Short link": "Short link",
301
298
  "Show this layer in the caption": "Show this layer in the caption",
@@ -650,7 +647,12 @@ const locale = {
650
647
  "List of values": "List of values",
651
648
  "Yes / No": "Yes / No",
652
649
  "Select field to compute intensity": "Select field to compute intensity",
653
- "Optional intensity field to compute heatmap": "Optional intensity field to compute heatmap"
650
+ "Optional intensity field to compute heatmap": "Optional intensity field to compute heatmap",
651
+ "All layers": "All layers",
652
+ "Comma separated list of values": "Comma separated list of values",
653
+ "Share": "Share",
654
+ "Customized link": "Customized link",
655
+ "Iframe": "Iframe"
654
656
  }
655
657
  L.registerLocale("am_ET", locale)
656
658
  L.setLocale("am_ET")
@@ -99,7 +99,6 @@
99
99
  "Delete this vertex (Alt+Click)": "Delete this vertex (Alt+Click)",
100
100
  "Delete": "ሰርዝ",
101
101
  "description": "መገለጫ",
102
- "Direct link": "Direct link",
103
102
  "Directions from here": "ከዚህ የሚነሱ አቅጣጫዎች",
104
103
  "Display label": "Display label",
105
104
  "Display measure": "Display measure",
@@ -135,7 +134,6 @@
135
134
  "Edit this feature": "ይህንን ፊቸር አርም",
136
135
  "Edit": "አርም",
137
136
  "Embed and link options": "Embed and link options",
138
- "Embed the map": "ካርታውን አካትት",
139
137
  "Emoji & Character": "Emoji & Character",
140
138
  "Empty": "ባዶ",
141
139
  "Equidistant": "Equidistant",
@@ -295,7 +293,6 @@
295
293
  "settings": "settings",
296
294
  "Shape properties": "Shape properties",
297
295
  "Share and download": "Share and download",
298
- "Share this link to open a customized map view": "Share this link to open a customized map view",
299
296
  "Short credits": "አጭር ክሬዲት",
300
297
  "Short link": "Short link",
301
298
  "Show this layer in the caption": "Show this layer in the caption",
@@ -650,5 +647,10 @@
650
647
  "List of values": "List of values",
651
648
  "Yes / No": "Yes / No",
652
649
  "Select field to compute intensity": "Select field to compute intensity",
653
- "Optional intensity field to compute heatmap": "Optional intensity field to compute heatmap"
650
+ "Optional intensity field to compute heatmap": "Optional intensity field to compute heatmap",
651
+ "All layers": "All layers",
652
+ "Comma separated list of values": "Comma separated list of values",
653
+ "Share": "Share",
654
+ "Customized link": "Customized link",
655
+ "Iframe": "Iframe"
654
656
  }