umap-project 1.4.4__py3-none-any.whl → 1.5.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 (132) hide show
  1. umap/__init__.py +1 -1
  2. umap/locale/br/LC_MESSAGES/django.mo +0 -0
  3. umap/locale/br/LC_MESSAGES/django.po +8 -7
  4. umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
  5. umap/locale/cs_CZ/LC_MESSAGES/django.po +35 -35
  6. umap/locale/en/LC_MESSAGES/django.po +28 -28
  7. umap/migrations/0011_alter_map_edit_status_alter_map_share_status.py +24 -0
  8. umap/models.py +10 -2
  9. umap/settings/base.py +2 -0
  10. umap/static/umap/base.css +4 -4
  11. umap/static/umap/img/16-white.svg +18 -3
  12. umap/static/umap/img/logo_small.svg +14 -0
  13. umap/static/umap/img/source/16-white.svg +19 -5
  14. umap/static/umap/js/umap.controls.js +122 -132
  15. umap/static/umap/js/umap.core.js +12 -5
  16. umap/static/umap/js/umap.features.js +40 -14
  17. umap/static/umap/js/umap.forms.js +55 -5
  18. umap/static/umap/js/umap.js +59 -100
  19. umap/static/umap/js/umap.layer.js +69 -26
  20. umap/static/umap/js/umap.permissions.js +5 -0
  21. umap/static/umap/js/umap.popup.js +3 -6
  22. umap/static/umap/js/umap.xhr.js +2 -1
  23. umap/static/umap/locale/am_ET.js +14 -7
  24. umap/static/umap/locale/am_ET.json +14 -7
  25. umap/static/umap/locale/ar.js +14 -7
  26. umap/static/umap/locale/ar.json +14 -7
  27. umap/static/umap/locale/ast.js +14 -7
  28. umap/static/umap/locale/ast.json +14 -7
  29. umap/static/umap/locale/bg.js +14 -7
  30. umap/static/umap/locale/bg.json +14 -7
  31. umap/static/umap/locale/br.js +29 -22
  32. umap/static/umap/locale/br.json +29 -22
  33. umap/static/umap/locale/ca.js +14 -7
  34. umap/static/umap/locale/ca.json +14 -7
  35. umap/static/umap/locale/cs_CZ.js +42 -35
  36. umap/static/umap/locale/cs_CZ.json +42 -35
  37. umap/static/umap/locale/da.js +14 -7
  38. umap/static/umap/locale/da.json +14 -7
  39. umap/static/umap/locale/de.js +14 -7
  40. umap/static/umap/locale/de.json +14 -7
  41. umap/static/umap/locale/el.js +14 -7
  42. umap/static/umap/locale/el.json +14 -7
  43. umap/static/umap/locale/en.js +14 -7
  44. umap/static/umap/locale/en.json +14 -7
  45. umap/static/umap/locale/en_US.json +14 -7
  46. umap/static/umap/locale/es.js +14 -7
  47. umap/static/umap/locale/es.json +14 -7
  48. umap/static/umap/locale/et.js +14 -7
  49. umap/static/umap/locale/et.json +14 -7
  50. umap/static/umap/locale/eu.js +7 -7
  51. umap/static/umap/locale/eu.json +7 -7
  52. umap/static/umap/locale/fa_IR.js +14 -7
  53. umap/static/umap/locale/fa_IR.json +14 -7
  54. umap/static/umap/locale/fi.js +14 -7
  55. umap/static/umap/locale/fi.json +14 -7
  56. umap/static/umap/locale/fr.js +14 -7
  57. umap/static/umap/locale/fr.json +14 -7
  58. umap/static/umap/locale/gl.js +14 -7
  59. umap/static/umap/locale/gl.json +14 -7
  60. umap/static/umap/locale/he.js +14 -7
  61. umap/static/umap/locale/he.json +14 -7
  62. umap/static/umap/locale/hr.js +14 -7
  63. umap/static/umap/locale/hr.json +14 -7
  64. umap/static/umap/locale/hu.js +14 -7
  65. umap/static/umap/locale/hu.json +14 -7
  66. umap/static/umap/locale/id.js +14 -7
  67. umap/static/umap/locale/id.json +14 -7
  68. umap/static/umap/locale/is.js +14 -7
  69. umap/static/umap/locale/is.json +14 -7
  70. umap/static/umap/locale/it.js +14 -7
  71. umap/static/umap/locale/it.json +14 -7
  72. umap/static/umap/locale/ja.js +14 -7
  73. umap/static/umap/locale/ja.json +14 -7
  74. umap/static/umap/locale/ko.js +14 -7
  75. umap/static/umap/locale/ko.json +14 -7
  76. umap/static/umap/locale/lt.js +14 -7
  77. umap/static/umap/locale/lt.json +14 -7
  78. umap/static/umap/locale/ms.js +14 -7
  79. umap/static/umap/locale/ms.json +14 -7
  80. umap/static/umap/locale/nl.js +14 -7
  81. umap/static/umap/locale/nl.json +14 -7
  82. umap/static/umap/locale/no.js +14 -7
  83. umap/static/umap/locale/no.json +14 -7
  84. umap/static/umap/locale/pl.js +14 -7
  85. umap/static/umap/locale/pl.json +14 -7
  86. umap/static/umap/locale/pl_PL.json +14 -7
  87. umap/static/umap/locale/pt.js +14 -7
  88. umap/static/umap/locale/pt.json +14 -7
  89. umap/static/umap/locale/pt_BR.js +14 -7
  90. umap/static/umap/locale/pt_BR.json +14 -7
  91. umap/static/umap/locale/pt_PT.js +14 -7
  92. umap/static/umap/locale/pt_PT.json +14 -7
  93. umap/static/umap/locale/ro.js +14 -7
  94. umap/static/umap/locale/ro.json +14 -7
  95. umap/static/umap/locale/ru.js +14 -7
  96. umap/static/umap/locale/ru.json +14 -7
  97. umap/static/umap/locale/sk_SK.js +14 -7
  98. umap/static/umap/locale/sk_SK.json +14 -7
  99. umap/static/umap/locale/sl.js +14 -7
  100. umap/static/umap/locale/sl.json +14 -7
  101. umap/static/umap/locale/sr.js +14 -7
  102. umap/static/umap/locale/sr.json +14 -7
  103. umap/static/umap/locale/sv.js +38 -31
  104. umap/static/umap/locale/sv.json +38 -31
  105. umap/static/umap/locale/th_TH.js +14 -7
  106. umap/static/umap/locale/th_TH.json +14 -7
  107. umap/static/umap/locale/tr.js +14 -7
  108. umap/static/umap/locale/tr.json +14 -7
  109. umap/static/umap/locale/uk_UA.js +14 -7
  110. umap/static/umap/locale/uk_UA.json +14 -7
  111. umap/static/umap/locale/vi.js +14 -7
  112. umap/static/umap/locale/vi.json +14 -7
  113. umap/static/umap/locale/vi_VN.json +14 -7
  114. umap/static/umap/locale/zh.js +14 -7
  115. umap/static/umap/locale/zh.json +14 -7
  116. umap/static/umap/locale/zh_CN.json +14 -7
  117. umap/static/umap/locale/zh_TW.Big5.json +14 -7
  118. umap/static/umap/locale/zh_TW.js +14 -7
  119. umap/static/umap/locale/zh_TW.json +14 -7
  120. umap/static/umap/map.css +119 -47
  121. umap/static/umap/test/DataLayer.js +32 -6
  122. umap/static/umap/test/Util.js +7 -7
  123. umap/static/umap/vendors/leaflet/leaflet-src.js +7156 -7156
  124. umap/static/umap/vendors/togeojson/togeojson.js +2 -406
  125. umap/tests/test_map.py +16 -0
  126. umap/tests/test_views.py +18 -0
  127. umap/views.py +3 -1
  128. {umap_project-1.4.4.dist-info → umap_project-1.5.0.dist-info}/METADATA +3 -3
  129. {umap_project-1.4.4.dist-info → umap_project-1.5.0.dist-info}/RECORD +132 -130
  130. {umap_project-1.4.4.dist-info → umap_project-1.5.0.dist-info}/WHEEL +0 -0
  131. {umap_project-1.4.4.dist-info → umap_project-1.5.0.dist-info}/entry_points.txt +0 -0
  132. {umap_project-1.4.4.dist-info → umap_project-1.5.0.dist-info}/licenses/LICENSE +0 -0
@@ -417,12 +417,21 @@ L.FormBuilder.DataLayerSwitcher = L.FormBuilder.Select.extend({
417
417
  },
418
418
  })
419
419
 
420
- L.FormBuilder.onLoadPanel = L.FormBuilder.Select.extend({
420
+ L.FormBuilder.DefaultView = L.FormBuilder.Select.extend({
421
+ selectOptions: [
422
+ ['center', L._('Saved center and zoom')],
423
+ ['bounds', L._('Layers bounds')],
424
+ ['latest', L._('Latest feature')],
425
+ ['locate', L._('User location')],
426
+ ],
427
+ })
428
+
429
+ L.FormBuilder.OnLoadPanel = L.FormBuilder.Select.extend({
421
430
  selectOptions: [
422
431
  ['none', L._('None')],
423
432
  ['caption', L._('Caption')],
424
433
  ['databrowser', L._('Data browser')],
425
- ['datafilters', L._('Data filters')],
434
+ ['facet', L._('Facet search')],
426
435
  ],
427
436
  })
428
437
 
@@ -533,7 +542,7 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
533
542
  },
534
543
 
535
544
  udpatePreview: function () {
536
- if (this.value() && this.value().indexOf('{') === -1) {
545
+ if (L.Util.hasVar(this.value())) {
537
546
  // Do not try to render URL with variables
538
547
  if (this.isUrl()) {
539
548
  const img = L.DomUtil.create(
@@ -675,6 +684,37 @@ L.FormBuilder.Switch = L.FormBuilder.CheckBox.extend({
675
684
  },
676
685
  })
677
686
 
687
+ L.FormBuilder.FacetSearch = L.FormBuilder.Element.extend({
688
+ build: function () {
689
+ this.container = L.DomUtil.create('div', 'umap-facet', this.parentNode)
690
+ this.ul = L.DomUtil.create('ul', '', this.container)
691
+ const choices = this.options.choices
692
+ choices.sort()
693
+ choices.forEach((value) => this.buildLi(value))
694
+ },
695
+
696
+ buildLabel: function () {
697
+ this.label = L.DomUtil.add('h5', '', this.parentNode, this.options.label);
698
+ },
699
+
700
+ buildLi: function (value) {
701
+ const property_li = L.DomUtil.create('li', '', this.ul),
702
+ input = L.DomUtil.create('input', '', property_li),
703
+ label = L.DomUtil.create('label', '', property_li)
704
+ input.type = 'checkbox'
705
+ input.id = `checkbox_${this.name}_${value}`
706
+ input.checked = this.get().includes(value)
707
+ input.dataset.value = value
708
+ label.htmlFor = `checkbox_${this.name}_${value}`
709
+ label.innerHTML = value
710
+ L.DomEvent.on(input, 'change', (e) => this.sync())
711
+ },
712
+
713
+ toJS: function () {
714
+ return [...this.ul.querySelectorAll('input:checked')].map(i => i.dataset.value)
715
+ },
716
+ })
717
+
678
718
  L.FormBuilder.MultiChoice = L.FormBuilder.Element.extend({
679
719
  default: 'null',
680
720
  className: 'umap-multiplechoice',
@@ -1008,9 +1048,13 @@ L.U.FormBuilder = L.FormBuilder.extend({
1008
1048
  label: L._('Do you want to display the scale control?'),
1009
1049
  },
1010
1050
  onLoadPanel: {
1011
- handler: 'onLoadPanel',
1051
+ handler: 'OnLoadPanel',
1012
1052
  label: L._('Do you want to display a panel on load?'),
1013
1053
  },
1054
+ defaultView: {
1055
+ handler: 'DefaultView',
1056
+ label: L._('Default view'),
1057
+ },
1014
1058
  displayPopupFooter: {
1015
1059
  handler: 'Switch',
1016
1060
  label: L._('Do you want to display popup footer?'),
@@ -1096,6 +1140,12 @@ L.U.FormBuilder = L.FormBuilder.extend({
1096
1140
  handler: 'ControlChoice',
1097
1141
  label: L._('Display the star map button'),
1098
1142
  },
1143
+ fromZoom: {
1144
+ handler: 'IntInput',
1145
+ label: L._('From zoom'),
1146
+ helpText: L._('Optional.'),
1147
+ },
1148
+ toZoom: { handler: 'IntInput', label: L._('To zoom'), helpText: L._('Optional.') },
1099
1149
  },
1100
1150
 
1101
1151
  initialize: function (obj, fields, options) {
@@ -1106,7 +1156,7 @@ L.U.FormBuilder = L.FormBuilder.extend({
1106
1156
 
1107
1157
  setter: function (field, value) {
1108
1158
  L.FormBuilder.prototype.setter.call(this, field, value)
1109
- this.obj.isDirty = true
1159
+ if (this.options.makeDirty !== false) this.obj.isDirty = true
1110
1160
  },
1111
1161
 
1112
1162
  finish: function () {
@@ -67,13 +67,11 @@ L.U.Map.include({
67
67
  initialize: function (el, geojson) {
68
68
  // Locale name (pt_PT, en_US…)
69
69
  // To be used for Django localization
70
- if (geojson.properties.locale)
71
- L.setLocale(geojson.properties.locale)
70
+ if (geojson.properties.locale) L.setLocale(geojson.properties.locale)
72
71
 
73
72
  // Language code (pt-pt, en-us…)
74
73
  // To be used in javascript APIs
75
- if (geojson.properties.lang)
76
- L.lang = geojson.properties.lang
74
+ if (geojson.properties.lang) L.lang = geojson.properties.lang
77
75
 
78
76
  // Don't let default autocreation of controls
79
77
  const zoomControl =
@@ -91,7 +89,7 @@ L.U.Map.include({
91
89
 
92
90
  this.ui = new L.U.UI(this._container)
93
91
  this.xhr = new L.U.Xhr(this.ui)
94
- this.xhr.on('dataloading', (e) => this.fire('dataloading', e))
92
+ this.xhr.on('dataloading', (e) => this.fire('dataloading', e))
95
93
  this.xhr.on('dataload', (e) => this.fire('dataload', e))
96
94
 
97
95
  this.initLoader()
@@ -144,18 +142,6 @@ L.U.Map.include({
144
142
  // Certainly IE8, which has a limited version of defineProperty
145
143
  }
146
144
 
147
- if (this.options.hash) this.addHash()
148
- this.initCenter()
149
- this.handleLimitBounds()
150
-
151
- this.initTileLayers(this.options.tilelayers)
152
-
153
- // Global storage for retrieving datalayers and features
154
- this.datalayers = {}
155
- this.datalayers_index = []
156
- this.dirty_datalayers = []
157
- this.features_index = {}
158
-
159
145
  // Retrocompat
160
146
  if (
161
147
  this.options.slideshow &&
@@ -163,10 +149,20 @@ L.U.Map.include({
163
149
  this.options.slideshow.active === undefined
164
150
  )
165
151
  this.options.slideshow.active = true
152
+ if (this.options.advancedFilterKey) this.options.facetKey = this.options.advancedFilterKey
166
153
 
167
- this.initControls()
154
+ // Global storage for retrieving datalayers and features
155
+ this.datalayers = {}
156
+ this.datalayers_index = []
157
+ this.dirty_datalayers = []
158
+ this.features_index = {}
159
+ this.facets = {}
168
160
 
169
- // create datalayers
161
+ if (this.options.hash) this.addHash()
162
+ this.initControls()
163
+ this.initCenter()
164
+ this.handleLimitBounds()
165
+ this.initTileLayers(this.options.tilelayers)
170
166
  this.initDatalayers()
171
167
 
172
168
  if (this.options.displayCaptionOnLoad) {
@@ -247,14 +243,14 @@ L.U.Map.include({
247
243
  },
248
244
  this
249
245
  )
250
- this.initEditBar()
246
+ this.renderEditToolbar()
251
247
  }
252
248
  this.initShortcuts()
253
249
  this.onceDatalayersLoaded(function () {
254
250
  if (L.Util.queryString('share')) this.renderShareBox()
255
251
  else if (this.options.onLoadPanel === 'databrowser') this.openBrowser()
256
252
  else if (this.options.onLoadPanel === 'caption') this.displayCaption()
257
- else if (this.options.onLoadPanel === 'datafilters') this.openFilter()
253
+ else if (this.options.onLoadPanel === 'facet' || this.options.onLoadPanel === 'datafilters') this.openFacet()
258
254
  })
259
255
  this.onceDataLoaded(function () {
260
256
  const slug = L.Util.queryString('feature')
@@ -636,10 +632,16 @@ L.U.Map.include({
636
632
  if (this.options.hash && this._hash.parseHash(location.hash)) {
637
633
  // FIXME An invalid hash will cause the load to fail
638
634
  this._hash.update()
639
- } else if (this.options.locate && this.options.locate.setView) {
640
- // Prevent from making two setViews at init
641
- // which is not very fluid...
642
- this.locate(this.options.locate)
635
+ } else if (this.options.defaultView === 'locate' && !this.options.noControl) {
636
+ this._controls.locate.start()
637
+ } else if (this.options.defaultView === 'bounds') {
638
+ this.onceDataLoaded(() => this.fitBounds(this.getLayersBounds()))
639
+ } else if (this.options.defaultView === 'latest') {
640
+ this.onceDataLoaded(() => {
641
+ const datalayer = this.defaultDataLayer(),
642
+ feature = datalayer.getFeatureByIndex(-1)
643
+ if (feature) feature.zoomTo()
644
+ })
643
645
  } else {
644
646
  this.options.center = this.latLng(this.options.center)
645
647
  this.setView(this.options.center, this.options.zoom)
@@ -951,9 +953,9 @@ L.U.Map.include({
951
953
  })
952
954
  },
953
955
 
954
- openFilter: function () {
956
+ openFacet: function () {
955
957
  this.onceDatalayersLoaded(function () {
956
- this._openFilter()
958
+ this._openFacet()
957
959
  })
958
960
  },
959
961
 
@@ -1036,6 +1038,7 @@ L.U.Map.include({
1036
1038
  'miniMap',
1037
1039
  'displayPopupFooter',
1038
1040
  'onLoadPanel',
1041
+ 'defaultView',
1039
1042
  'tilelayersControl',
1040
1043
  'name',
1041
1044
  'description',
@@ -1064,7 +1067,7 @@ L.U.Map.include({
1064
1067
  'sortKey',
1065
1068
  'labelKey',
1066
1069
  'filterKey',
1067
- 'advancedFilterKey',
1070
+ 'facetKey',
1068
1071
  'slugKey',
1069
1072
  'showLabel',
1070
1073
  'labelDirection',
@@ -1273,6 +1276,9 @@ L.U.Map.include({
1273
1276
  }
1274
1277
  },
1275
1278
 
1279
+ // TODO: allow to control the default datalayer
1280
+ // (edit and viewing)
1281
+ // cf https://github.com/umap-project/umap/issues/585
1276
1282
  defaultDataLayer: function () {
1277
1283
  let datalayer, fallback
1278
1284
  datalayer = this.lastUsedDataLayer
@@ -1314,6 +1320,7 @@ L.U.Map.include({
1314
1320
  'options.miniMap',
1315
1321
  'options.scaleControl',
1316
1322
  'options.onLoadPanel',
1323
+ 'options.defaultView',
1317
1324
  'options.displayPopupFooter',
1318
1325
  'options.captionBar',
1319
1326
  'options.captionMenus',
@@ -1387,13 +1394,12 @@ L.U.Map.include({
1387
1394
  },
1388
1395
  ],
1389
1396
  [
1390
- 'options.advancedFilterKey',
1397
+ 'options.facetKey',
1391
1398
  {
1392
1399
  handler: 'Input',
1393
- helpEntries: 'advancedFilterKey',
1400
+ helpEntries: 'facetKey',
1394
1401
  placeholder: L._('Example: key1,key2,key3'),
1395
- label: L._('Advanced filter keys'),
1396
- inheritable: true,
1402
+ label: L._('Facet keys')
1397
1403
  },
1398
1404
  ],
1399
1405
  [
@@ -1710,7 +1716,7 @@ L.U.Map.include({
1710
1716
  if (!this.editEnabled) return
1711
1717
  const container = L.DomUtil.create('div', 'umap-edit-container'),
1712
1718
  metadataFields = ['options.name', 'options.description'],
1713
- title = L.DomUtil.create('h4', '', container)
1719
+ title = L.DomUtil.create('h3', '', container)
1714
1720
  title.textContent = L._('Edit map properties')
1715
1721
  const builder = new L.U.FormBuilder(this, metadataFields)
1716
1722
  const form = builder.build()
@@ -1778,7 +1784,7 @@ L.U.Map.include({
1778
1784
  this.openBrowser,
1779
1785
  this
1780
1786
  )
1781
- if (this.options.advancedFilterKey) {
1787
+ if (this.options.facetKey) {
1782
1788
  const filter = L.DomUtil.add(
1783
1789
  'a',
1784
1790
  'umap-open-filter-link',
@@ -1789,7 +1795,7 @@ L.U.Map.include({
1789
1795
  L.DomEvent.on(filter, 'click', L.DomEvent.stop).on(
1790
1796
  filter,
1791
1797
  'click',
1792
- this.openFilter,
1798
+ this.openFacet,
1793
1799
  this
1794
1800
  )
1795
1801
  }
@@ -1804,66 +1810,6 @@ L.U.Map.include({
1804
1810
  })
1805
1811
  },
1806
1812
 
1807
- initEditBar: function () {
1808
- const container = L.DomUtil.create(
1809
- 'div',
1810
- 'umap-main-edit-toolbox with-transition dark',
1811
- this._controlContainer
1812
- ),
1813
- title = L.DomUtil.add('h3', '', container, `${L._('Editing')} `),
1814
- name = L.DomUtil.create('a', 'umap-click-to-edit', title),
1815
- setName = function () {
1816
- name.textContent = this.getDisplayName()
1817
- }
1818
- if (this.options.user) {
1819
- const userLabel = L.DomUtil.add('a', 'umap-user', title, this.options.user.name)
1820
- userLabel.href = this.options.user.url
1821
- }
1822
- L.bind(setName, this)()
1823
- L.DomEvent.on(name, 'click', this.edit, this)
1824
- this.on('postsync', L.bind(setName, this))
1825
- this.help.button(name, 'edit')
1826
- const save = L.DomUtil.create('a', 'leaflet-control-edit-save button', container)
1827
- save.href = '#'
1828
- save.title = `${L._('Save current edits')} (Ctrl+S)`
1829
- save.textContent = L._('Save')
1830
- const cancel = L.DomUtil.create(
1831
- 'a',
1832
- 'leaflet-control-edit-cancel button',
1833
- container
1834
- )
1835
- cancel.href = '#'
1836
- cancel.title = L._('Cancel edits')
1837
- cancel.textContent = L._('Cancel')
1838
- const disable = L.DomUtil.create('a', 'leaflet-control-edit-disable', container)
1839
- disable.href = '#'
1840
- disable.title = disable.textContent = L._('Disable editing')
1841
-
1842
- L.DomEvent.addListener(disable, 'click', L.DomEvent.stop).addListener(
1843
- disable,
1844
- 'click',
1845
- function (e) {
1846
- this.disableEdit(e)
1847
- this.ui.closePanel()
1848
- },
1849
- this
1850
- )
1851
-
1852
- L.DomEvent.addListener(save, 'click', L.DomEvent.stop).addListener(
1853
- save,
1854
- 'click',
1855
- this.save,
1856
- this
1857
- )
1858
-
1859
- L.DomEvent.addListener(cancel, 'click', L.DomEvent.stop).addListener(
1860
- cancel,
1861
- 'click',
1862
- this.askForReset,
1863
- this
1864
- )
1865
- },
1866
-
1867
1813
  askForReset: function (e) {
1868
1814
  if (!confirm(L._('Are you sure you want to cancel your changes?'))) return
1869
1815
  this.reset()
@@ -2007,10 +1953,10 @@ L.U.Map.include({
2007
1953
  text: L._('Browse data'),
2008
1954
  callback: this.openBrowser,
2009
1955
  })
2010
- if (this.options.advancedFilterKey) {
1956
+ if (this.options.facetKey) {
2011
1957
  items.push({
2012
- text: L._('Select data'),
2013
- callback: this.openFilter,
1958
+ text: L._('Facet search'),
1959
+ callback: this.openFacet,
2014
1960
  })
2015
1961
  }
2016
1962
  items.push(
@@ -2095,7 +2041,20 @@ L.U.Map.include({
2095
2041
  return (this.options.filterKey || this.options.sortKey || 'name').split(',')
2096
2042
  },
2097
2043
 
2098
- getAdvancedFilterKeys: function () {
2099
- return (this.options.advancedFilterKey || '').split(',')
2044
+ getFacetKeys: function () {
2045
+ return (this.options.facetKey || '').split(',').reduce((acc, curr) => {
2046
+ const els = curr.split("|")
2047
+ acc[els[0]] = els[1] || els[0]
2048
+ return acc
2049
+ }, {})
2050
+ },
2051
+
2052
+ getLayersBounds: function () {
2053
+ const bounds = new L.latLngBounds()
2054
+ this.eachBrowsableDataLayer((d) => {
2055
+ if (d.isVisible()) bounds.extend(d.layer.getBounds())
2056
+ })
2057
+ return bounds
2100
2058
  },
2059
+
2101
2060
  })
@@ -10,6 +10,10 @@ L.U.Layer = {
10
10
  },
11
11
 
12
12
  postUpdate: function () {},
13
+
14
+ hasDataVisible: function () {
15
+ return !!Object.keys(this._layers).length
16
+ },
13
17
  }
14
18
 
15
19
  L.U.Layer.Default = L.FeatureGroup.extend({
@@ -53,6 +57,17 @@ L.U.Layer.Cluster = L.MarkerClusterGroup.extend({
53
57
  }
54
58
  L.MarkerClusterGroup.prototype.initialize.call(this, options)
55
59
  this._markerCluster = L.U.MarkerCluster
60
+ this._layers = []
61
+ },
62
+
63
+ addLayer: function (layer) {
64
+ this._layers.push(layer)
65
+ return L.MarkerClusterGroup.prototype.addLayer.call(this, layer)
66
+ },
67
+
68
+ removeLayer: function (layer) {
69
+ this._layers.splice(this._layers.indexOf(layer), 1)
70
+ return L.MarkerClusterGroup.prototype.removeLayer.call(this, layer)
56
71
  },
57
72
 
58
73
  getEditableOptions: function () {
@@ -237,11 +252,31 @@ L.U.DataLayer = L.Evented.extend({
237
252
  this.connectToMap()
238
253
  if (this.displayedOnLoad()) this.show()
239
254
  if (!this.umap_id) this.isDirty = true
255
+
256
+ // Retrocompat
257
+ if (this.options.remoteData && this.options.remoteData.from) {
258
+ this.options.fromZoom = this.options.remoteData.from
259
+ }
260
+ if (this.options.remoteData && this.options.remoteData.to) {
261
+ this.options.toZoom = this.options.remoteData.to
262
+ }
263
+
240
264
  this.onceLoaded(function () {
241
- this.map.on('moveend', this.fetchRemoteData, this)
265
+ this.map.on('moveend', this.onMoveEnd, this)
266
+ this.map.on('zoomend', this.onZoomEnd, this)
242
267
  })
243
268
  },
244
269
 
270
+ onMoveEnd: function (e) {
271
+ if (this.isRemoteLayer()) this.fetchRemoteData()
272
+ },
273
+
274
+ onZoomEnd: function (e) {
275
+ if (this._forcedVisibility) return
276
+ if (!this.showAtZoom() && this.isVisible()) this.hide()
277
+ if (this.showAtZoom() && !this.isVisible()) this.show()
278
+ },
279
+
245
280
  displayedOnLoad: function () {
246
281
  return (
247
282
  (this.map.datalayersOnLoad &&
@@ -265,6 +300,10 @@ L.U.DataLayer = L.Evented.extend({
265
300
  this.parentPane.appendChild(this.pane)
266
301
  },
267
302
 
303
+ hasDataVisible: function () {
304
+ return this.layer.hasDataVisible()
305
+ },
306
+
268
307
  resetLayer: function (force) {
269
308
  if (this.layer && this.options.type === this.layer._type && !force) return
270
309
  const visible = this.isVisible()
@@ -273,12 +312,7 @@ L.U.DataLayer = L.Evented.extend({
273
312
  if (visible) this.map.removeLayer(this.layer)
274
313
  const Class = L.U.Layer[this.options.type] || L.U.Layer.Default
275
314
  this.layer = new Class(this)
276
- const filterKeys = this.map.getFilterKeys(),
277
- filter = this.map.options.filter
278
- this.eachLayer(function (layer) {
279
- if (filter && !layer.matchFilter(filter, filterKeys)) return
280
- this.layer.addLayer(layer)
281
- })
315
+ this.eachLayer((feature) => this.showFeature(feature))
282
316
  if (visible) this.map.addLayer(this.layer)
283
317
  this.propagateRemote()
284
318
  },
@@ -335,6 +369,7 @@ L.U.DataLayer = L.Evented.extend({
335
369
  this.backupData()
336
370
  this._geojson = null
337
371
  }
372
+ this.fire('datachanged')
338
373
  },
339
374
 
340
375
  backupData: function () {
@@ -351,17 +386,17 @@ L.U.DataLayer = L.Evented.extend({
351
386
  }
352
387
  },
353
388
 
389
+ showAtZoom: function () {
390
+ const from = parseInt(this.options.fromZoom, 10),
391
+ to = parseInt(this.options.toZoom, 10),
392
+ zoom = this.map.getZoom()
393
+ if (isNaN(from) || isNaN(to)) return false
394
+ return (zoom >= from && zoom <= to)
395
+ },
396
+
354
397
  fetchRemoteData: function () {
355
398
  if (!this.isRemoteLayer()) return
356
- const from = parseInt(this.options.remoteData.from, 10),
357
- to = parseInt(this.options.remoteData.to, 10)
358
- if (
359
- (!isNaN(from) && this.map.getZoom() < from) ||
360
- (!isNaN(to) && this.map.getZoom() > to)
361
- ) {
362
- this.clear()
363
- return
364
- }
399
+ if (!this.showAtZoom()) return
365
400
  if (!this.options.remoteData.dynamic && this.hasDataLoaded()) return
366
401
  if (!this.isVisible()) return
367
402
  let url = this.map.localizeUrl(this.options.remoteData.url)
@@ -457,15 +492,23 @@ L.U.DataLayer = L.Evented.extend({
457
492
  return this.options.type === 'Cluster'
458
493
  },
459
494
 
495
+ showFeature: function (feature) {
496
+ const filterKeys = this.map.getFilterKeys(),
497
+ filter = this.map.options.filter
498
+ if (filter && !feature.matchFilter(filter, filterKeys)) return
499
+ if (!feature.matchFacets()) return
500
+ this.layer.addLayer(feature)
501
+ },
502
+
460
503
  addLayer: function (feature) {
461
504
  const id = L.stamp(feature)
462
505
  feature.connectToDataLayer(this)
463
506
  this._index.push(id)
464
507
  this._layers[id] = feature
465
- this.layer.addLayer(feature)
466
508
  this.indexProperties(feature)
467
- if (this.hasDataLoaded()) this.fire('datachanged')
468
509
  this.map.features_index[feature.getSlug()] = feature
510
+ this.showFeature(feature)
511
+ if (this.hasDataLoaded()) this.fire('datachanged')
469
512
  },
470
513
 
471
514
  removeLayer: function (feature) {
@@ -840,6 +883,8 @@ L.U.DataLayer = L.Evented.extend({
840
883
  'options.smoothFactor',
841
884
  'options.dashArray',
842
885
  'options.zoomTo',
886
+ 'options.fromZoom',
887
+ 'options.toZoom',
843
888
  'options.labelKey',
844
889
  ]
845
890
 
@@ -880,11 +925,8 @@ L.U.DataLayer = L.Evented.extend({
880
925
  { handler: 'Url', label: L._('Url'), helpEntries: 'formatURL' },
881
926
  ],
882
927
  ['options.remoteData.format', { handler: 'DataFormat', label: L._('Format') }],
883
- [
884
- 'options.remoteData.from',
885
- { label: L._('From zoom'), helpText: L._('Optional.') },
886
- ],
887
- ['options.remoteData.to', { label: L._('To zoom'), helpText: L._('Optional.') }],
928
+ 'options.fromZoom',
929
+ 'options.toZoom',
888
930
  [
889
931
  'options.remoteData.dynamic',
890
932
  { handler: 'Switch', label: L._('Dynamic'), helpEntries: 'dynamicRemoteData' },
@@ -976,9 +1018,7 @@ L.U.DataLayer = L.Evented.extend({
976
1018
  buildVersionsFieldset: function (container) {
977
1019
  const appendVersion = function (data) {
978
1020
  const date = new Date(parseInt(data.at, 10))
979
- const content = `${date.toLocaleString(L.lang)} (${
980
- parseInt(data.size) / 1000
981
- }Kb)`
1021
+ const content = `${date.toLocaleString(L.lang)} (${parseInt(data.size) / 1000}Kb)`
982
1022
  const el = L.DomUtil.create('div', 'umap-datalayer-version', versionsContainer)
983
1023
  const a = L.DomUtil.create('a', '', el)
984
1024
  L.DomUtil.add('span', '', el, content)
@@ -1041,6 +1081,9 @@ L.U.DataLayer = L.Evented.extend({
1041
1081
  },
1042
1082
 
1043
1083
  toggle: function () {
1084
+ // From now on, do not try to how/hide
1085
+ // automatically this layer.
1086
+ this._forcedVisibility = true
1044
1087
  if (!this.isVisible()) this.show()
1045
1088
  else this.hide()
1046
1089
  },
@@ -160,6 +160,7 @@ L.U.MapPermissions = L.Class.extend({
160
160
  this.commit()
161
161
  this.isDirty = false
162
162
  this.map.continueSaving()
163
+ this.map.fire('postsync')
163
164
  },
164
165
  })
165
166
  },
@@ -194,4 +195,8 @@ L.U.MapPermissions = L.Class.extend({
194
195
  commit: function () {
195
196
  L.Util.extend(this.map.options.permissions, this.options)
196
197
  },
198
+
199
+ getShareStatusDisplay: function () {
200
+ return Object.fromEntries(this.map.options.share_statuses)[this.options.share_status]
201
+ }
197
202
  })
@@ -63,8 +63,8 @@ L.U.Popup.Panel = L.U.Popup.extend({
63
63
  return button
64
64
  },
65
65
 
66
- update: function () {
67
- this.feature.map.ui.openPanel({
66
+ onAdd: function (map) {
67
+ map.ui.openPanel({
68
68
  data: { html: this._content },
69
69
  actions: [this.allButton()],
70
70
  })
@@ -72,12 +72,9 @@ L.U.Popup.Panel = L.U.Popup.extend({
72
72
 
73
73
  onRemove: function (map) {
74
74
  map.ui.closePanel()
75
- L.U.Popup.prototype.onRemove.call(this, map)
76
75
  },
77
76
 
78
- _initLayout: function () {
79
- this._container = L.DomUtil.create('span')
80
- },
77
+ update: function () {},
81
78
  _updateLayout: function () {},
82
79
  _updatePosition: function () {},
83
80
  _adjustPan: function () {},
@@ -95,7 +95,8 @@ L.U.Xhr = L.Evented.extend({
95
95
  // 0 === request cut by user or CORS
96
96
  self.ui.alert({
97
97
  content: L._(
98
- 'Issue reaching that URL (network problem or CORS protection)'
98
+ 'Issue reaching that URL (network problem or CORS protection): {url}',
99
+ { url: settings.uri }
99
100
  ),
100
101
  level: 'error',
101
102
  })