umap-project 3.0.4__py3-none-any.whl → 3.0.5__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 (158) hide show
  1. umap/__init__.py +1 -1
  2. umap/locale/el/LC_MESSAGES/django.mo +0 -0
  3. umap/locale/el/LC_MESSAGES/django.po +136 -56
  4. umap/locale/en/LC_MESSAGES/django.po +18 -18
  5. umap/locale/es/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/es/LC_MESSAGES/django.po +136 -56
  7. umap/locale/nl/LC_MESSAGES/django.mo +0 -0
  8. umap/locale/nl/LC_MESSAGES/django.po +1 -1
  9. umap/models.py +1 -0
  10. umap/settings/base.py +1 -0
  11. umap/static/umap/css/bar.css +1 -1
  12. umap/static/umap/css/tooltip.css +13 -0
  13. umap/static/umap/js/modules/autocomplete.js +7 -8
  14. umap/static/umap/js/modules/browser.js +89 -94
  15. umap/static/umap/js/modules/caption.js +6 -4
  16. umap/static/umap/js/modules/data/features.js +1 -19
  17. umap/static/umap/js/modules/data/layer.js +100 -61
  18. umap/static/umap/js/modules/facets.js +1 -1
  19. umap/static/umap/js/modules/form/fields.js +1 -1
  20. umap/static/umap/js/modules/importer.js +1 -1
  21. umap/static/umap/js/modules/managers.js +46 -0
  22. umap/static/umap/js/modules/permissions.js +1 -1
  23. umap/static/umap/js/modules/rendering/controls.js +251 -0
  24. umap/static/umap/js/modules/rendering/layers/heat.js +5 -0
  25. umap/static/umap/js/modules/rendering/map.js +21 -10
  26. umap/static/umap/js/modules/rendering/ui.js +0 -1
  27. umap/static/umap/js/modules/rules.js +56 -46
  28. umap/static/umap/js/modules/schema.js +5 -1
  29. umap/static/umap/js/modules/share.js +2 -2
  30. umap/static/umap/js/modules/slideshow.js +1 -1
  31. umap/static/umap/js/modules/sync/engine.js +23 -9
  32. umap/static/umap/js/modules/ui/bar.js +2 -2
  33. umap/static/umap/js/modules/ui/base.js +13 -0
  34. umap/static/umap/js/modules/umap.js +69 -111
  35. umap/static/umap/js/umap.controls.js +0 -310
  36. umap/static/umap/js/umap.core.js +0 -40
  37. umap/static/umap/locale/am_ET.js +8 -3
  38. umap/static/umap/locale/am_ET.json +8 -3
  39. umap/static/umap/locale/ar.js +8 -3
  40. umap/static/umap/locale/ar.json +8 -3
  41. umap/static/umap/locale/ast.js +8 -3
  42. umap/static/umap/locale/ast.json +8 -3
  43. umap/static/umap/locale/bg.js +8 -3
  44. umap/static/umap/locale/bg.json +8 -3
  45. umap/static/umap/locale/br.js +8 -3
  46. umap/static/umap/locale/br.json +8 -3
  47. umap/static/umap/locale/ca.js +20 -17
  48. umap/static/umap/locale/ca.json +20 -17
  49. umap/static/umap/locale/cs_CZ.js +5 -2
  50. umap/static/umap/locale/cs_CZ.json +5 -2
  51. umap/static/umap/locale/da.js +8 -3
  52. umap/static/umap/locale/da.json +8 -3
  53. umap/static/umap/locale/de.js +5 -2
  54. umap/static/umap/locale/de.json +5 -2
  55. umap/static/umap/locale/el.js +92 -87
  56. umap/static/umap/locale/el.json +92 -87
  57. umap/static/umap/locale/en.js +5 -2
  58. umap/static/umap/locale/en.json +5 -2
  59. umap/static/umap/locale/en_US.json +8 -3
  60. umap/static/umap/locale/es.js +18 -15
  61. umap/static/umap/locale/es.json +18 -15
  62. umap/static/umap/locale/et.js +8 -3
  63. umap/static/umap/locale/et.json +8 -3
  64. umap/static/umap/locale/eu.js +5 -2
  65. umap/static/umap/locale/eu.json +5 -2
  66. umap/static/umap/locale/fa_IR.js +5 -2
  67. umap/static/umap/locale/fa_IR.json +5 -2
  68. umap/static/umap/locale/fi.js +8 -3
  69. umap/static/umap/locale/fi.json +8 -3
  70. umap/static/umap/locale/fr.js +5 -2
  71. umap/static/umap/locale/fr.json +5 -2
  72. umap/static/umap/locale/gl.js +5 -2
  73. umap/static/umap/locale/gl.json +5 -2
  74. umap/static/umap/locale/he.js +8 -3
  75. umap/static/umap/locale/he.json +8 -3
  76. umap/static/umap/locale/hr.js +8 -3
  77. umap/static/umap/locale/hr.json +8 -3
  78. umap/static/umap/locale/hu.js +5 -2
  79. umap/static/umap/locale/hu.json +5 -2
  80. umap/static/umap/locale/id.js +8 -3
  81. umap/static/umap/locale/id.json +8 -3
  82. umap/static/umap/locale/is.js +8 -3
  83. umap/static/umap/locale/is.json +8 -3
  84. umap/static/umap/locale/it.js +5 -2
  85. umap/static/umap/locale/it.json +5 -2
  86. umap/static/umap/locale/ja.js +8 -3
  87. umap/static/umap/locale/ja.json +8 -3
  88. umap/static/umap/locale/ko.js +8 -3
  89. umap/static/umap/locale/ko.json +8 -3
  90. umap/static/umap/locale/lt.js +8 -3
  91. umap/static/umap/locale/lt.json +8 -3
  92. umap/static/umap/locale/ms.js +8 -3
  93. umap/static/umap/locale/ms.json +8 -3
  94. umap/static/umap/locale/nl.js +7 -4
  95. umap/static/umap/locale/nl.json +7 -4
  96. umap/static/umap/locale/no.js +8 -3
  97. umap/static/umap/locale/no.json +8 -3
  98. umap/static/umap/locale/pl.js +8 -3
  99. umap/static/umap/locale/pl.json +8 -3
  100. umap/static/umap/locale/pl_PL.json +8 -3
  101. umap/static/umap/locale/pt.js +5 -2
  102. umap/static/umap/locale/pt.json +5 -2
  103. umap/static/umap/locale/pt_BR.js +8 -3
  104. umap/static/umap/locale/pt_BR.json +8 -3
  105. umap/static/umap/locale/pt_PT.js +5 -2
  106. umap/static/umap/locale/pt_PT.json +5 -2
  107. umap/static/umap/locale/ro.js +8 -3
  108. umap/static/umap/locale/ro.json +8 -3
  109. umap/static/umap/locale/ru.js +8 -3
  110. umap/static/umap/locale/ru.json +8 -3
  111. umap/static/umap/locale/sk_SK.js +8 -3
  112. umap/static/umap/locale/sk_SK.json +8 -3
  113. umap/static/umap/locale/sl.js +8 -3
  114. umap/static/umap/locale/sl.json +8 -3
  115. umap/static/umap/locale/sr.js +8 -3
  116. umap/static/umap/locale/sr.json +8 -3
  117. umap/static/umap/locale/sv.js +8 -3
  118. umap/static/umap/locale/sv.json +8 -3
  119. umap/static/umap/locale/th_TH.js +8 -3
  120. umap/static/umap/locale/th_TH.json +8 -3
  121. umap/static/umap/locale/tr.js +8 -3
  122. umap/static/umap/locale/tr.json +8 -3
  123. umap/static/umap/locale/uk_UA.js +8 -3
  124. umap/static/umap/locale/uk_UA.json +8 -3
  125. umap/static/umap/locale/vi.js +8 -3
  126. umap/static/umap/locale/vi.json +8 -3
  127. umap/static/umap/locale/vi_VN.json +8 -3
  128. umap/static/umap/locale/zh.js +8 -3
  129. umap/static/umap/locale/zh.json +8 -3
  130. umap/static/umap/locale/zh_CN.json +8 -3
  131. umap/static/umap/locale/zh_TW.Big5.json +8 -3
  132. umap/static/umap/locale/zh_TW.js +5 -2
  133. umap/static/umap/locale/zh_TW.json +5 -2
  134. umap/static/umap/map.css +9 -31
  135. umap/static/umap/vendors/togeojson/togeojson.es.js +350 -177
  136. umap/static/umap/vendors/togeojson/togeojson.es.mjs.map +1 -1
  137. umap/templates/umap/design_system.html +355 -0
  138. umap/tests/base.py +2 -2
  139. umap/tests/fixtures/heatmap_data.json +1044 -0
  140. umap/tests/integration/test_browser.py +3 -3
  141. umap/tests/integration/test_conditional_rules.py +2 -2
  142. umap/tests/integration/test_datalayer.py +0 -1
  143. umap/tests/integration/test_edit_map.py +7 -7
  144. umap/tests/integration/test_facets_browser.py +2 -2
  145. umap/tests/integration/test_heatmap.py +41 -0
  146. umap/tests/integration/test_import.py +58 -1
  147. umap/tests/integration/test_map.py +7 -8
  148. umap/tests/integration/test_optimistic_merge.py +12 -4
  149. umap/tests/integration/test_querystring.py +1 -1
  150. umap/tests/integration/test_remote_data.py +79 -0
  151. umap/tests/integration/test_websocket_sync.py +2 -2
  152. umap/urls.py +1 -0
  153. umap/views.py +7 -0
  154. {umap_project-3.0.4.dist-info → umap_project-3.0.5.dist-info}/METADATA +8 -8
  155. {umap_project-3.0.4.dist-info → umap_project-3.0.5.dist-info}/RECORD +158 -152
  156. {umap_project-3.0.4.dist-info → umap_project-3.0.5.dist-info}/WHEEL +0 -0
  157. {umap_project-3.0.4.dist-info → umap_project-3.0.5.dist-info}/entry_points.txt +0 -0
  158. {umap_project-3.0.4.dist-info → umap_project-3.0.5.dist-info}/licenses/LICENSE +0 -0
@@ -33,6 +33,7 @@ import { EditPanel, FullPanel, Panel } from './ui/panel.js'
33
33
  import Tooltip from './ui/tooltip.js'
34
34
  import URLs from './urls.js'
35
35
  import * as Utils from './utils.js'
36
+ import { DataLayerManager } from './managers.js'
36
37
 
37
38
  export default class Umap {
38
39
  constructor(element, geojson) {
@@ -107,7 +108,7 @@ export default class Umap {
107
108
  if (geojson.properties.schema) this.overrideSchema(geojson.properties.schema)
108
109
 
109
110
  // Do not display in an iframe.
110
- if (window.self !== window.top) {
111
+ if (this.isEmbed) {
111
112
  this.properties.homeControl = false
112
113
  }
113
114
 
@@ -166,8 +167,7 @@ export default class Umap {
166
167
  }
167
168
 
168
169
  // Global storage for retrieving datalayers and features.
169
- this.datalayers = {} // All datalayers, including deleted.
170
- this.datalayersIndex = [] // Datalayers actually on the map and ordered.
170
+ this.datalayers = new DataLayerManager()
171
171
  this.featuresIndex = {}
172
172
 
173
173
  this.formatter = new Formatter(this)
@@ -217,7 +217,6 @@ export default class Umap {
217
217
  }
218
218
 
219
219
  window.onbeforeunload = () => (this.editEnabled && this.isDirty) || null
220
- this.backup()
221
220
  }
222
221
 
223
222
  get isDirty() {
@@ -258,6 +257,10 @@ export default class Umap {
258
257
  }
259
258
  }
260
259
 
260
+ get isEmbed() {
261
+ return window.self !== window.top
262
+ }
263
+
261
264
  setPropertiesFromQueryString() {
262
265
  const asBoolean = (key) => {
263
266
  const value = this.searchParams.get(key)
@@ -612,7 +615,7 @@ export default class Umap {
612
615
  this.datalayersLoaded = true
613
616
  this.fire('datalayersloaded')
614
617
  const toLoad = []
615
- for (const datalayer of this.datalayersIndex) {
618
+ for (const datalayer of this.datalayers.active()) {
616
619
  if (datalayer.showAtLoad()) toLoad.push(() => datalayer.show())
617
620
  }
618
621
  while (toLoad.length) {
@@ -626,7 +629,7 @@ export default class Umap {
626
629
 
627
630
  createDataLayer(options = {}, sync = true) {
628
631
  options.name =
629
- options.name || `${translate('Layer')} ${this.datalayersIndex.length + 1}`
632
+ options.name || `${translate('Layer')} ${this.datalayers.count() + 1}`
630
633
  const datalayer = new DataLayer(this, this._leafletMap, options)
631
634
 
632
635
  if (sync !== false) {
@@ -637,7 +640,6 @@ export default class Umap {
637
640
 
638
641
  createDirtyDataLayer(options) {
639
642
  const datalayer = this.createDataLayer(options, true)
640
- datalayer.isDirty = true
641
643
  return datalayer
642
644
  }
643
645
 
@@ -647,19 +649,19 @@ export default class Umap {
647
649
  }
648
650
 
649
651
  reindexDataLayers() {
650
- this.eachDataLayer((datalayer) => datalayer.reindex())
652
+ this.datalayers.active().map((datalayer) => datalayer.reindex())
651
653
  this.onDataLayersChanged()
652
654
  }
653
655
 
654
- indexDatalayers() {
655
- const panes = this._leafletMap.getPane('overlayPane')
656
-
657
- this.datalayersIndex = []
658
- for (const pane of panes.children) {
659
- if (!pane.dataset || !pane.dataset.id) continue
660
- this.datalayersIndex.push(this.datalayers[pane.dataset.id])
656
+ reorderDataLayers() {
657
+ const parent = this._leafletMap.getPane('overlayPane')
658
+ const datalayers = Object.values(this.datalayers)
659
+ .filter((datalayer) => !datalayer._isDeleted)
660
+ .sort((datalayer1, datalayer2) => datalayer1.rank > datalayer2.rank)
661
+ for (const datalayer of datalayers) {
662
+ const child = parent.querySelector(`[data-id="${datalayer.id}"]`)
663
+ parent.appendChild(child)
661
664
  }
662
- this.onDataLayersChanged()
663
665
  }
664
666
 
665
667
  onceDatalayersLoaded(callback, context) {
@@ -690,8 +692,8 @@ export default class Umap {
690
692
  async saveAll() {
691
693
  if (!this.isDirty) return
692
694
  if (this._defaultExtent) this._setCenterAndZoom()
693
- this.backup()
694
- await this.sync.save()
695
+ const status = await this.sync.save()
696
+ if (!status) return
695
697
  // Do a blind render for now, as we are not sure what could
696
698
  // have changed, we'll be more subtil when we'll remove the
697
699
  // save action
@@ -709,24 +711,6 @@ export default class Umap {
709
711
  return this.properties.name || translate('Untitled map')
710
712
  }
711
713
 
712
- backup() {
713
- this.backupProperties()
714
- this._datalayersIndex_bk = [].concat(this.datalayersIndex)
715
- }
716
-
717
- backupProperties() {
718
- this._backupProperties = Object.assign({}, this.properties)
719
- this._backupProperties.tilelayer = Object.assign({}, this.properties.tilelayer)
720
- this._backupProperties.limitBounds = Object.assign({}, this.properties.limitBounds)
721
- this._backupProperties.permissions = Object.assign({}, this.permissions.properties)
722
- }
723
-
724
- resetProperties() {
725
- this.properties = Object.assign({}, this._backupProperties)
726
- this.properties.tilelayer = Object.assign({}, this._backupProperties.tilelayer)
727
- this.permissions.properties = Object.assign({}, this._backupProperties.permissions)
728
- }
729
-
730
714
  setProperties(newProperties) {
731
715
  for (const key of Object.keys(SCHEMA)) {
732
716
  if (newProperties[key] !== undefined) {
@@ -739,24 +723,24 @@ export default class Umap {
739
723
  }
740
724
 
741
725
  hasData() {
742
- for (const datalayer of this.datalayersIndex) {
726
+ for (const datalayer of this.datalayers.active()) {
743
727
  if (datalayer.hasData()) return true
744
728
  }
745
729
  }
746
730
 
747
731
  hasLayers() {
748
- return Boolean(this.datalayersIndex.length)
732
+ return Boolean(this.datalayers.count())
749
733
  }
750
734
 
751
735
  allProperties() {
752
- return [].concat(...this.datalayersIndex.map((dl) => dl.allProperties()))
736
+ return [].concat(...this.datalayers.active().map((dl) => dl.allProperties()))
753
737
  }
754
738
 
755
739
  sortedValues(property) {
756
740
  return []
757
- .concat(...this.datalayersIndex.map((dl) => dl.sortedValues(property)))
741
+ .concat(...this.datalayers.active().map((dl) => dl.sortedValues(property)))
758
742
  .filter((val, idx, arr) => arr.indexOf(val) === idx)
759
- .sort(U.Utils.naturalSort)
743
+ .sort(Utils.naturalSort)
760
744
  }
761
745
 
762
746
  editCaption() {
@@ -819,7 +803,7 @@ export default class Umap {
819
803
  `<button type="button">${translate('Use current center and zoom')}</button>`
820
804
  )
821
805
  button.addEventListener('click', () => {
822
- this._setCenterAndZoom()
806
+ this.setCenterAndZoom()
823
807
  builder.fetchAll()
824
808
  })
825
809
  container.appendChild(form)
@@ -1177,7 +1161,7 @@ export default class Umap {
1177
1161
  }
1178
1162
  this._advancedActions(container)
1179
1163
 
1180
- this.editPanel.open({
1164
+ return this.editPanel.open({
1181
1165
  content: container,
1182
1166
  className: 'dark',
1183
1167
  highlight: 'settings',
@@ -1231,12 +1215,8 @@ export default class Umap {
1231
1215
  })
1232
1216
  }
1233
1217
  } else {
1234
- if (!this.permissions.isDirty) {
1235
- // Do not override local changes to permissions,
1236
- // but update in case some other editors changed them in the meantime.
1237
- this.permissions.setProperties(data.permissions)
1238
- this.permissions.commit()
1239
- }
1218
+ this.permissions.setProperties(data.permissions)
1219
+ this.permissions.commit()
1240
1220
  this._leafletMap.once('saved', () => {
1241
1221
  Alert.success(data.info || translate('Map has been saved!'))
1242
1222
  })
@@ -1273,7 +1253,7 @@ export default class Umap {
1273
1253
 
1274
1254
  toGeoJSON() {
1275
1255
  let features = []
1276
- this.eachDataLayer((datalayer) => {
1256
+ this.datalayers.active().map((datalayer) => {
1277
1257
  if (datalayer.isVisible()) {
1278
1258
  features = features.concat(datalayer.featuresToGeoJSON())
1279
1259
  }
@@ -1349,13 +1329,20 @@ export default class Umap {
1349
1329
  if (fields.includes('properties.rules')) {
1350
1330
  this.rules.load()
1351
1331
  }
1352
- this.eachVisibleDataLayer((datalayer) => {
1332
+ this.datalayers.visible().map((datalayer) => {
1353
1333
  datalayer.redraw()
1354
1334
  })
1355
1335
  break
1356
1336
  case 'datalayer-index':
1357
1337
  this.reindexDataLayers()
1358
1338
  break
1339
+ case 'datalayer-rank':
1340
+ // When drag'n'dropping datalayers,
1341
+ // this get called once per datalayers.
1342
+ // (and same for undo/redo of the action)
1343
+ // TODO: call only once
1344
+ this.reorderDataLayers()
1345
+ break
1359
1346
  case 'background':
1360
1347
  this._leafletMap.initTileLayers()
1361
1348
  break
@@ -1444,7 +1431,7 @@ export default class Umap {
1444
1431
  ) {
1445
1432
  return datalayer
1446
1433
  }
1447
- datalayer = this.findDataLayer((datalayer) => {
1434
+ datalayer = this.datalayers.find((datalayer) => {
1448
1435
  if (!datalayer.isDataReadOnly() && datalayer.isBrowsable()) {
1449
1436
  fallback = datalayer
1450
1437
  if (datalayer.isVisible()) return true
@@ -1459,61 +1446,37 @@ export default class Umap {
1459
1446
  return this.createDirtyDataLayer()
1460
1447
  }
1461
1448
 
1462
- findDataLayer(method, context) {
1463
- for (let i = this.datalayersIndex.length - 1; i >= 0; i--) {
1464
- if (method.call(context, this.datalayersIndex[i])) {
1465
- return this.datalayersIndex[i]
1466
- }
1467
- }
1468
- }
1469
-
1470
- eachDataLayer(method, context) {
1471
- for (let i = 0; i < this.datalayersIndex.length; i++) {
1472
- method.call(context, this.datalayersIndex[i])
1473
- }
1474
- }
1475
-
1476
- eachDataLayerReverse(method, context, filter) {
1477
- for (let i = this.datalayersIndex.length - 1; i >= 0; i--) {
1478
- if (filter && !filter.call(context, this.datalayersIndex[i])) continue
1479
- method.call(context, this.datalayersIndex[i])
1480
- }
1481
- }
1482
-
1483
- eachBrowsableDataLayer(method, context) {
1484
- this.eachDataLayerReverse(method, context, (d) => d.allowBrowse())
1485
- }
1486
-
1487
- eachVisibleDataLayer(method, context) {
1488
- this.eachDataLayerReverse(method, context, (d) => d.isVisible())
1489
- }
1490
-
1491
- eachFeature(callback, context) {
1492
- this.eachBrowsableDataLayer((datalayer) => {
1493
- if (datalayer.isVisible()) datalayer.eachFeature(callback, context)
1449
+ eachFeature(callback) {
1450
+ this.datalayers.browsable().map((datalayer) => {
1451
+ if (datalayer.isVisible()) datalayer.eachFeature(callback)
1494
1452
  })
1495
1453
  }
1496
1454
 
1497
1455
  removeDataLayers() {
1498
- this.eachDataLayerReverse((datalayer) => {
1456
+ this.datalayers.active().map((datalayer) => {
1499
1457
  datalayer.del()
1500
1458
  })
1501
1459
  }
1502
1460
 
1503
1461
  emptyDataLayers() {
1504
- this.eachDataLayerReverse((datalayer) => {
1462
+ this.datalayers.active().map((datalayer) => {
1505
1463
  datalayer.empty()
1506
1464
  })
1507
1465
  }
1508
1466
 
1509
1467
  editDatalayers() {
1510
1468
  if (!this.editEnabled) return
1511
- const container = DomUtil.create('div')
1512
- DomUtil.createTitle(container, translate('Manage layers'), 'icon-layers')
1513
- const ul = DomUtil.create('ul', '', container)
1514
- this.eachDataLayerReverse((datalayer) => {
1515
- const row = DomUtil.create('li', 'orderable', ul)
1516
- DomUtil.createIcon(row, 'icon-drag', translate('Drag to reorder'))
1469
+ const template = `
1470
+ <div>
1471
+ <h3><i class="icon icon-16 icon-layers"></i>${translate('Manage layers')}</h3>
1472
+ <ul data-ref=ul></ul>
1473
+ </div>
1474
+ `
1475
+ const [container, { ul }] = Utils.loadTemplateWithRefs(template)
1476
+ this.datalayers.reverse().map((datalayer) => {
1477
+ const row = Utils.loadTemplate(
1478
+ `<li class="orderable"><i class="icon icon-16 icon-drag" title="${translate('Drag to reorder')}"></i></li>`
1479
+ )
1517
1480
  datalayer.renderToolbox(row)
1518
1481
  const builder = new MutatingForm(
1519
1482
  datalayer,
@@ -1524,20 +1487,27 @@ export default class Umap {
1524
1487
  row.appendChild(form)
1525
1488
  row.classList.toggle('off', !datalayer.isVisible())
1526
1489
  row.dataset.id = datalayer.id
1490
+ ul.appendChild(row)
1527
1491
  })
1528
1492
  const onReorder = (src, dst, initialIndex, finalIndex) => {
1529
1493
  const movedLayer = this.datalayers[src.dataset.id]
1530
1494
  const targetLayer = this.datalayers[dst.dataset.id]
1531
- const minIndex = Math.min(movedLayer.getRank(), targetLayer.getRank())
1532
- const maxIndex = Math.max(movedLayer.getRank(), targetLayer.getRank())
1495
+ const minIndex = Math.min(movedLayer.getDOMOrder(), targetLayer.getDOMOrder())
1496
+ const maxIndex = Math.max(movedLayer.getDOMOrder(), targetLayer.getDOMOrder())
1533
1497
  if (finalIndex === 0) movedLayer.bringToTop()
1534
1498
  else if (finalIndex > initialIndex) movedLayer.insertBefore(targetLayer)
1535
1499
  else movedLayer.insertAfter(targetLayer)
1536
- this.eachDataLayerReverse((datalayer) => {
1537
- if (datalayer.getRank() >= minIndex && datalayer.getRank() <= maxIndex)
1538
- datalayer.isDirty = true
1500
+ this.sync.startBatch()
1501
+ this.datalayers.reverse().map((datalayer) => {
1502
+ const rank = datalayer.getDOMOrder()
1503
+ if (rank >= minIndex && rank <= maxIndex) {
1504
+ const oldRank = datalayer.rank
1505
+ datalayer.rank = rank
1506
+ datalayer.sync.update('options.rank', rank, oldRank)
1507
+ }
1539
1508
  })
1540
- this.indexDatalayers()
1509
+ this.sync.commitBatch()
1510
+ this.onDataLayersChanged()
1541
1511
  }
1542
1512
  const orderable = new Orderable(ul, onReorder)
1543
1513
 
@@ -1559,18 +1529,6 @@ export default class Umap {
1559
1529
  return datalayer
1560
1530
  }
1561
1531
 
1562
- firstVisibleDatalayer() {
1563
- return this.findDataLayer((datalayer) => {
1564
- if (datalayer.isVisible()) return true
1565
- })
1566
- }
1567
-
1568
- ensurePanesOrder() {
1569
- this.eachDataLayer((datalayer) => {
1570
- datalayer.bringToTop()
1571
- })
1572
- }
1573
-
1574
1532
  openBrowser(mode) {
1575
1533
  this.onceDatalayersLoaded(() => this.browser.open(mode))
1576
1534
  }
@@ -1721,7 +1679,7 @@ export default class Umap {
1721
1679
 
1722
1680
  getLayersBounds() {
1723
1681
  const bounds = new latLngBounds()
1724
- this.eachBrowsableDataLayer((d) => {
1682
+ this.datalayers.browsable().map((d) => {
1725
1683
  if (d.isVisible()) bounds.extend(d.layer.getBounds())
1726
1684
  })
1727
1685
  return bounds