umap-project 3.0.2__py3-none-any.whl → 3.0.4__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 (64) hide show
  1. umap/__init__.py +1 -1
  2. umap/locale/en/LC_MESSAGES/django.po +11 -7
  3. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  4. umap/locale/fr/LC_MESSAGES/django.po +11 -7
  5. umap/locale/nl/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/nl/LC_MESSAGES/django.po +136 -56
  7. umap/settings/base.py +2 -2
  8. umap/static/umap/base.css +4 -0
  9. umap/static/umap/css/bar.css +1 -1
  10. umap/static/umap/css/form.css +44 -44
  11. umap/static/umap/js/modules/browser.js +1 -0
  12. umap/static/umap/js/modules/caption.js +2 -2
  13. umap/static/umap/js/modules/data/features.js +3 -4
  14. umap/static/umap/js/modules/data/layer.js +9 -1
  15. umap/static/umap/js/modules/form/fields.js +4 -2
  16. umap/static/umap/js/modules/importers/cadastrefr.js +14 -12
  17. umap/static/umap/js/modules/importers/geodatamine.js +11 -9
  18. umap/static/umap/js/modules/rendering/map.js +2 -4
  19. umap/static/umap/js/modules/schema.js +12 -0
  20. umap/static/umap/js/modules/ui/bar.js +2 -2
  21. umap/static/umap/js/modules/umap.js +22 -0
  22. umap/static/umap/js/umap.controls.js +3 -3
  23. umap/static/umap/locale/ca.js +8 -6
  24. umap/static/umap/locale/ca.json +8 -6
  25. umap/static/umap/locale/cs_CZ.js +4 -2
  26. umap/static/umap/locale/cs_CZ.json +4 -2
  27. umap/static/umap/locale/de.js +4 -2
  28. umap/static/umap/locale/de.json +4 -2
  29. umap/static/umap/locale/en.js +4 -2
  30. umap/static/umap/locale/en.json +4 -2
  31. umap/static/umap/locale/es.js +4 -2
  32. umap/static/umap/locale/es.json +4 -2
  33. umap/static/umap/locale/eu.js +4 -2
  34. umap/static/umap/locale/eu.json +4 -2
  35. umap/static/umap/locale/fa_IR.js +4 -2
  36. umap/static/umap/locale/fa_IR.json +4 -2
  37. umap/static/umap/locale/fr.js +4 -2
  38. umap/static/umap/locale/fr.json +4 -2
  39. umap/static/umap/locale/gl.js +4 -2
  40. umap/static/umap/locale/gl.json +4 -2
  41. umap/static/umap/locale/hu.js +4 -2
  42. umap/static/umap/locale/hu.json +4 -2
  43. umap/static/umap/locale/it.js +4 -2
  44. umap/static/umap/locale/it.json +4 -2
  45. umap/static/umap/locale/nl.js +12 -10
  46. umap/static/umap/locale/nl.json +12 -10
  47. umap/static/umap/locale/pt.js +4 -2
  48. umap/static/umap/locale/pt.json +4 -2
  49. umap/static/umap/locale/pt_PT.js +4 -2
  50. umap/static/umap/locale/pt_PT.json +4 -2
  51. umap/static/umap/locale/zh_TW.js +4 -2
  52. umap/static/umap/locale/zh_TW.json +4 -2
  53. umap/static/umap/map.css +3 -2
  54. umap/static/umap/vars.css +4 -0
  55. umap/templates/umap/search.html +10 -1
  56. umap/tests/integration/test_edit_map.py +1 -7
  57. umap/tests/integration/test_iframe.py +25 -0
  58. umap/tests/integration/test_picto.py +10 -2
  59. umap/views.py +6 -3
  60. {umap_project-3.0.2.dist-info → umap_project-3.0.4.dist-info}/METADATA +1 -1
  61. {umap_project-3.0.2.dist-info → umap_project-3.0.4.dist-info}/RECORD +64 -63
  62. {umap_project-3.0.2.dist-info → umap_project-3.0.4.dist-info}/WHEEL +0 -0
  63. {umap_project-3.0.2.dist-info → umap_project-3.0.4.dist-info}/entry_points.txt +0 -0
  64. {umap_project-3.0.2.dist-info → umap_project-3.0.4.dist-info}/licenses/LICENSE +0 -0
@@ -6,7 +6,7 @@ input[type="text"], input[type="password"], input[type="date"],
6
6
  input[type="datetime-local"], input[type="email"], input[type="number"],
7
7
  input[type="search"], input[type="tel"], input[type="time"], input[type="file"],
8
8
  input[type="url"], textarea {
9
- background-color: white;
9
+ background-color: var(--color-light);
10
10
  border: 2px solid var(--color-darkBlue);
11
11
  color: var(--text-color);
12
12
  display: block;
@@ -47,7 +47,7 @@ input[type=checkbox]:checked:after {
47
47
  }
48
48
  input[data-modified=true] {
49
49
  background-color: var(--color-lightCyan);
50
- border: 1px solid var(--color-darkGray);
50
+ border: 1px solid var(--color-veryDarkGray);
51
51
  }
52
52
  input + select,
53
53
  select + input,
@@ -71,7 +71,7 @@ select {
71
71
  .dark select {
72
72
  color: var(--text-color);
73
73
  background-color: var(--color-darkGray);
74
- border-color: var(--color-dark);
74
+ border-color: var(--color-veryDarkGray);
75
75
  border-width: 1px;
76
76
  }
77
77
  select[multiple="multiple"] {
@@ -89,7 +89,7 @@ input[type="submit"] {
89
89
  text-decoration: none;
90
90
  justify-content: center;
91
91
  background-color: var(--color-darkBlue);
92
- color: white;
92
+ color: var(--color-light);
93
93
  font-weight: normal;
94
94
  min-height: 40px;
95
95
  }
@@ -97,21 +97,21 @@ input[type="submit"] {
97
97
  .dark [type="button"] {
98
98
  background-color: var(--color-darkerGray);
99
99
  color: var(--text-color);
100
- border: 1px solid #1b1f20;
100
+ border: 1px solid var(--color-veryDarkGray);
101
101
  }
102
102
  .button.primary {
103
103
  font-weight: bold;
104
104
  }
105
105
  .dark .button.primary:not([disabled]),
106
106
  .dark [type="button"].primary:not([disabled]) {
107
- background-color: var(--color-brightCyan);
107
+ background-color: var(--color-verySoftCyan);
108
108
  color: var(--color-dark);
109
- border: 1px solid #1b1f20;
109
+ border: 1px solid var(--color-veryDarkGray);
110
110
  }
111
111
  .dark .button:hover,
112
112
  .dark [type="button"]:hover,
113
113
  .dark input[type="submit"]:hover {
114
- background-color: #2e3436;
114
+ background-color: var(--color-darkerGray);
115
115
  }
116
116
  .dark a {
117
117
  color: var(--text-color);
@@ -151,14 +151,14 @@ button.round.small {
151
151
  display: block;
152
152
  padding: 7px 7px;
153
153
  margin-bottom: 14px;
154
- background: #393F3F;
154
+ background: var(--color-mediumGray);
155
155
  color: var(--color-lightGray);
156
156
  font-size: 10px;
157
157
  border-radius: 0 2px;
158
158
  }
159
159
  .content .helptext {
160
- background-color: #eee;
161
- color: #000;
160
+ background-color: var(--color-lightGray);
161
+ color: var(--color-dark);
162
162
  }
163
163
  input + .help-text {
164
164
  margin-top: -14px;
@@ -205,8 +205,8 @@ input + .error {
205
205
  margin-top: -14px;
206
206
  margin-bottom: 14px;
207
207
  background: var(--color-lightGray);
208
- color: #fff;
209
- background-color: #cc0000;
208
+ color: var(--color-light);
209
+ background-color: var(--color-red);
210
210
  font-size: 11px;
211
211
  border-radius: 0 2px;
212
212
  }
@@ -214,14 +214,14 @@ input[type="file"] + .error {
214
214
  margin-top: 0;
215
215
  }
216
216
  input[value]:invalid {
217
- border-color: red;
218
- background-color: darkred;
217
+ border-color: var(--color-red);
218
+ background-color: var(--color-darkRed);
219
219
  }
220
220
  .dark input, .dark textarea {
221
221
  background-color: var(--color-darkerGray);
222
- border-color: var(--color-dark);
222
+ border-color: var(--color-veryDarkGray);
223
223
  border-width: 1px;
224
- color: #efefef;
224
+ color: var(--color-lightGray);
225
225
  }
226
226
  details {
227
227
  margin-bottom: 5px;
@@ -229,7 +229,7 @@ details {
229
229
  border-start-end-radius: 4px;
230
230
  }
231
231
  .dark details {
232
- border: 1px solid #222;
232
+ border: 1px solid var(--color-veryDarkGray);
233
233
  }
234
234
  details fieldset {
235
235
  overflow: hidden;
@@ -245,8 +245,8 @@ details summary {
245
245
  padding: 0 5px;
246
246
  }
247
247
  .dark details summary {
248
- background-color: #232729;
249
- color: #fff;
248
+ background-color: var(--color-darkerGray);
249
+ color: var(--color-light);
250
250
  }
251
251
  .dark details fieldset {
252
252
  border: 1px solid var(--color-darkGray);
@@ -311,33 +311,34 @@ input.switch:empty ~ label:after {
311
311
  width: 6em;
312
312
  -webkit-transition: all 100ms ease-in;
313
313
  transition: all 100ms ease-in;
314
- color: #c9c9c7;
314
+ color: var(--color-mediumGray);
315
315
  font-weight: bold;
316
- background-color: #ededed;
316
+ background-color: var(--color-lighterGray);
317
317
  }
318
318
  .dark input.switch:empty ~ label:before,
319
319
  .dark input.switch:empty ~ label:after {
320
- background-color: #272c2e;
320
+ background-color: var(--color-darkerGray);
321
321
  }
322
322
  input.switch:empty ~ label:after {
323
323
  width: 3em;
324
324
  margin-inline-start: 0.1em;
325
- background-color: #ededed;
325
+ background-color: var(--color-lightGray);
326
326
  content: "OFF";
327
327
  text-indent: 3.5em;
328
- border: 1px solid #374E75;
328
+ border: 1px solid var(--color-darkerGray);
329
329
  font-weight: bold;
330
330
  }
331
331
  .dark input.switch:empty ~ label:after {
332
- border: 1px solid #202425;
333
- background-color: #2c3233;
332
+ border: 1px solid var(--color-veryDarkGray);
333
+ background-color: var(--color-darkerGray);
334
+ color: var(--color-lightGray);
334
335
  }
335
336
  input.switch:checked:empty ~ label:after {
336
337
  content: ' ';
337
338
  }
338
339
  .dark input.switch:checked ~ label:before,
339
340
  input.switch:checked ~ label:before {
340
- background-color: var(--color-lightCyan);
341
+ background-color: var(--color-verySoftCyan);
341
342
  border: 1px solid var(--color-lightGray);
342
343
  color: var(--color-darkGray);
343
344
  content: "ON";
@@ -347,7 +348,7 @@ input.switch:checked ~ label:before {
347
348
  }
348
349
  .dark input.switch:checked ~ label:before {
349
350
  border: none;
350
- background-color: var(--color-accent);
351
+ background-color: var(--color-verySoftCyan);
351
352
  }
352
353
  input.switch:checked ~ label:after {
353
354
  margin-inline-start: 3em;
@@ -387,9 +388,9 @@ input.switch:checked ~ label:after {
387
388
  display: none;
388
389
  }
389
390
  .umap-multiplechoice label {
390
- border: 1px solid #374E75;
391
+ border: 1px solid var(--color-veryDarkGray);
391
392
  cursor: pointer;
392
- background-color: #c9c9c7;
393
+ background-color: var(--color-lightGray);
393
394
  min-height: 30px;
394
395
  line-height: 30px;
395
396
  text-align: center;
@@ -397,12 +398,11 @@ input.switch:checked ~ label:after {
397
398
  display: inline-block;
398
399
  }
399
400
  .dark .umap-multiplechoice label {
400
- border: 1px solid black;
401
- background-color: #2c3233;
401
+ border: 1px solid var(--color-veryDarkGray);
402
+ background-color: var(--color-darkGray);
402
403
  }
403
404
  .umap-multiplechoice input[type='radio']:checked + label {
404
- background-color: var(--color-accent);
405
- box-shadow: inset 0 0 6px 0px #2c3233;
405
+ background-color: var(--color-verySoftCyan);
406
406
  color: var(--color-darkGray);
407
407
  }
408
408
  .inheritable .header .buttons {
@@ -420,7 +420,7 @@ input.switch:checked ~ label:after {
420
420
  width: initial;
421
421
  }
422
422
  .inheritable + .inheritable {
423
- border-top: 1px solid #222;
423
+ border-top: 1px solid var(--color-darkerGray);
424
424
  padding-top: 5px;
425
425
  margin-top: 5px;
426
426
  }
@@ -504,7 +504,7 @@ i.info {
504
504
  justify-content: space-around;
505
505
  font-size: 1.2em;
506
506
  margin-bottom: 20px;
507
- border-bottom: 1px solid #bebebe;
507
+ border-bottom: 1px solid var(--color-lighterGray);
508
508
  }
509
509
  .flat-tabs button {
510
510
  padding: 10px;
@@ -515,14 +515,14 @@ i.info {
515
515
  .flat-tabs button:hover,
516
516
  .flat-tabs .on {
517
517
  font-weight: bold;
518
- border-bottom: 1px solid #444;
518
+ border-bottom: 1px solid var(--color-mediumGray);
519
519
  }
520
520
  .dark .flat-tabs button {
521
- color: #fff;
521
+ color: var(--color-light);
522
522
  }
523
523
  .dark .flat-tabs button:hover,
524
524
  .dark .flat-tabs .on {
525
- border-bottom: 1px solid #fff;
525
+ border-bottom: 1px solid var(--color-light);
526
526
  }
527
527
  .umap-pictogram-category h6 {
528
528
  font-size: 1.3em;
@@ -538,11 +538,11 @@ i.info {
538
538
  height: 30px;
539
539
  line-height: 30px;
540
540
  cursor: pointer;
541
- background-color: #999;
541
+ background-color: var(--color-lightGray);
542
542
  text-align: center;
543
543
  margin-bottom: 5px;
544
544
  display: inline-block;
545
- color: black;
545
+ color: var(--color-dark);
546
546
  font-weight: bold;
547
547
  overflow: hidden;
548
548
  }
@@ -552,10 +552,10 @@ i.info {
552
552
  }
553
553
  .umap-pictogram-choice:hover,
554
554
  .umap-color-picker span:hover {
555
- background-color: #bebebe;
555
+ background-color: var(--color-lighterGray);
556
556
  }
557
557
  .umap-pictogram-choice.selected {
558
- box-shadow: inset 0 0 0 1px #e9e9e9;
558
+ box-shadow: inset 0 0 0 1px var(--color-lighterGray);
559
559
  }
560
560
 
561
561
  .umap-pictogram-choice .leaflet-marker-icon {
@@ -232,6 +232,7 @@ export default class Browser {
232
232
  toggle.addEventListener('click', () => this.toggleLayers())
233
233
  fitBounds.addEventListener('click', () => this._umap.fitDataBounds())
234
234
  download.addEventListener('click', () => this.downloadVisible(download))
235
+ download.hidden = this._umap.getProperty('embedControl') === false
235
236
  }
236
237
 
237
238
  downloadVisible(element) {
@@ -74,10 +74,10 @@ export default class Caption extends Utils.WithTemplate {
74
74
  this.addCredits()
75
75
  if (this._umap.properties.created_at) {
76
76
  const created_at = translate('created at {date}', {
77
- date: new Date(this._umap.properties.created_at).toLocaleDateString(),
77
+ date: this._umap.createdAt.toLocaleDateString(),
78
78
  })
79
79
  const modified_at = translate('modified at {date}', {
80
- date: new Date(this._umap.properties.modified_at).toLocaleDateString(),
80
+ date: this._umap.modifiedAt.toLocaleDateString(),
81
81
  })
82
82
  this.elements.dates.innerHTML = `${created_at} - ${modified_at}`
83
83
  } else {
@@ -146,14 +146,13 @@ class Feature {
146
146
  }
147
147
 
148
148
  onCommit() {
149
+ this.pullGeometry(false)
149
150
  // When the layer is a remote layer, we don't want to sync the creation of the
150
151
  // points via the websocket, as the other peers will get them themselves.
151
- const oldGeoJSON = this._just_married ? null : Utils.CopyJSON(this.toGeoJSON())
152
- this.pullGeometry(false)
153
152
  if (this.datalayer?.isRemoteLayer()) return
154
- if (this._just_married) {
153
+ if (this._needs_upsert) {
155
154
  this.sync.upsert(this.toGeoJSON(), null)
156
- this._just_married = false
155
+ this._needs_upsert = false
157
156
  } else {
158
157
  this.sync.update('geometry', this.geometry, this._geometry_bk)
159
158
  }
@@ -220,6 +220,7 @@ export class DataLayer {
220
220
  this._loading = true
221
221
  const [geojson, response, error] = await this._umap.server.get(this._dataUrl())
222
222
  if (!error) {
223
+ this._umap.modifiedAt = response.headers.get('last-modified')
223
224
  this.setReferenceVersion({ response, sync: false })
224
225
  // FIXME: for now the _umap_options property is set dynamically from backend
225
226
  // And thus it's not in the geojson file in the server
@@ -303,7 +304,10 @@ export class DataLayer {
303
304
  async getUrl(url, initialUrl) {
304
305
  const response = await this._umap.request.get(url)
305
306
  return new Promise((resolve) => {
306
- if (response?.ok) return resolve(response.text())
307
+ if (response?.ok) {
308
+ this._umap.modifiedAt = response.headers.get('last-modified')
309
+ return resolve(response.text())
310
+ }
307
311
  Alert.error(
308
312
  translate('Cannot load remote data for layer "{layer}" with url "{url}"', {
309
313
  layer: this.getName(),
@@ -414,6 +418,10 @@ export class DataLayer {
414
418
 
415
419
  removeFeature(feature, sync) {
416
420
  const id = stamp(feature)
421
+ // This feature was not yet added, may be after
422
+ // hitting Escape while drawing a new line or
423
+ // polygon, not yet valid (not enough points)
424
+ if (!this._index.includes(id)) return
417
425
  if (sync !== false) {
418
426
  const oldValue = feature.toGeoJSON()
419
427
  feature.sync.delete(oldValue)
@@ -808,9 +808,10 @@ Fields.IconUrl = class extends Fields.BlurInput {
808
808
  }
809
809
 
810
810
  addCategory(items, name) {
811
+ const hidden = name ? '' : ' hidden'
811
812
  const [parent, { grid }] = Utils.loadTemplateWithRefs(`
812
813
  <div class="umap-pictogram-category">
813
- <h6 hidden=${!name}>${name}</h6>
814
+ <h6${hidden}>${name}</h6>
814
815
  <div class="umap-pictogram-grid" data-ref=grid></div>
815
816
  </div>
816
817
  `)
@@ -924,7 +925,8 @@ Fields.Url = class extends Fields.Input {
924
925
  Fields.Switch = class extends Fields.CheckBox {
925
926
  getTemplate() {
926
927
  const label = this.properties.label
927
- return `${super.getTemplate()}<label title="${label}" for="${this.id}" data-ref=customLabel>${label}</label>`
928
+ const help = this.properties.helpEntries?.join() || ''
929
+ return `${super.getTemplate()}<label title="${label}" for="${this.id}" data-ref=customLabel data-help="${help}">${label}</label>`
928
930
  }
929
931
 
930
932
  build() {
@@ -8,18 +8,20 @@ import { AutocompleteCommunes } from './communesfr.js'
8
8
  const TEMPLATE = `
9
9
  <h3>Cadastre</h3>
10
10
  <p>Importer les données cadastrales d’une commune française.</p>
11
- <select name="theme">
12
- <option value="batiments">Bâtiments</option>
13
- <option value="communes">Communes</option>
14
- <option value="feuilles">Feuilles</option>
15
- <option value="lieux_dits">Lieux dits</option>
16
- <option value="parcelles" selected>Parcelles</option>
17
- <option value="prefixes_sections">Préfixes sections</option>
18
- <option value="sections">Sections</option>
19
- <option value="subdivisions_fiscales">Subdivisions fiscales</option>
20
- </select>
21
- <label id="boundary">
22
- </label>
11
+ <div class="formbox">
12
+ <select name="theme">
13
+ <option value="batiments">Bâtiments</option>
14
+ <option value="communes">Communes</option>
15
+ <option value="feuilles">Feuilles</option>
16
+ <option value="lieux_dits">Lieux dits</option>
17
+ <option value="parcelles" selected>Parcelles</option>
18
+ <option value="prefixes_sections">Préfixes sections</option>
19
+ <option value="sections">Sections</option>
20
+ <option value="subdivisions_fiscales">Subdivisions fiscales</option>
21
+ </select>
22
+ <label id="boundary">
23
+ </label>
24
+ </div>
23
25
  `
24
26
 
25
27
  export class Importer {
@@ -16,15 +16,17 @@ const BOUNDARY_TYPES = {
16
16
  const TEMPLATE = `
17
17
  <h3>GeoDataMine</h3>
18
18
  <p>${translate('GeoDataMine: thematic data from OpenStreetMap')}.</p>
19
- <select name="theme">
20
- <option value="">${translate('Choose a theme')}</option>
21
- </select>
22
- <label>
23
- <input type="checkbox" name="aspoint" />
24
- ${translate('Symplify all geometries to points')}
25
- </label>
26
- <label id="boundary">
27
- </label>
19
+ <div class="formbox">
20
+ <select name="theme">
21
+ <option value="">${translate('Choose a theme')}</option>
22
+ </select>
23
+ <label>
24
+ <input type="checkbox" name="aspoint" />
25
+ ${translate('Simplify all geometries to points')}
26
+ </label>
27
+ <label id="boundary">
28
+ </label>
29
+ </div>
28
30
  `
29
31
 
30
32
  class Autocomplete extends SingleMixin(BaseAjax) {
@@ -23,6 +23,7 @@ BaseMap.mergeOptions({
23
23
 
24
24
  const ControlsMixin = {
25
25
  HIDDABLE_CONTROLS: [
26
+ 'home',
26
27
  'zoom',
27
28
  'search',
28
29
  'fullscreen',
@@ -41,6 +42,7 @@ const ControlsMixin = {
41
42
  if (this._umap.hasEditMode() && !this.options.noControl) {
42
43
  new U.EditControl(this).addTo(this)
43
44
  }
45
+ this._controls.home = new U.HomeControl(this._umap)
44
46
  this._controls.zoom = new Control.Zoom({
45
47
  zoomInTitle: translate('Zoom in'),
46
48
  zoomOutTitle: translate('Zoom out'),
@@ -91,10 +93,6 @@ const ControlsMixin = {
91
93
  }
92
94
  if (this.options.noControl) return
93
95
 
94
- // Do not display in an iframe.
95
- if (window.self === window.top) {
96
- this._controls.home = new U.HomeControl().addTo(this)
97
- }
98
96
  this._controls.attribution = new U.AttributionControl().addTo(this)
99
97
  if (this.options.miniMap) {
100
98
  this.whenReady(function () {
@@ -204,6 +204,12 @@ export const SCHEMA = {
204
204
  type: Object,
205
205
  impacts: ['data'],
206
206
  },
207
+ homeControl: {
208
+ type: Boolean,
209
+ impacts: ['ui'],
210
+ label: translate('Display the back to home icon'),
211
+ default: true,
212
+ },
207
213
  iconClass: {
208
214
  type: String,
209
215
  impacts: ['data'],
@@ -275,6 +281,12 @@ export const SCHEMA = {
275
281
  label: translate('Label key'),
276
282
  inheritable: true,
277
283
  },
284
+ layerSwitcher: {
285
+ type: Boolean,
286
+ impacts: ['ui'],
287
+ label: translate('Do you want to display layer switcher in caption bar?'),
288
+ default: true,
289
+ },
278
290
  licence: {
279
291
  type: String,
280
292
  impacts: ['ui'],
@@ -180,7 +180,7 @@ const BOTTOM_BAR_TEMPLATE = `
180
180
  <button class="umap-about-link flat" type="button" title="${translate('Open caption')}" data-ref="caption">${translate('Open caption')}</button>
181
181
  <button class="umap-open-browser-link flat" type="button" title="${translate('Browse data')}" data-ref="browse">${translate('Browse data')}</button>
182
182
  <button class="umap-open-browser-link flat" type="button" title="${translate('Filter data')}" data-ref="filter">${translate('Filter data')}</button>
183
- <select data-ref=layers></select>
183
+ <select data-ref="layers"></select>
184
184
  </div>
185
185
  `
186
186
 
@@ -233,7 +233,7 @@ export class BottomBar extends WithTemplate {
233
233
  this.elements.layers.hidden = true
234
234
  } else {
235
235
  this.elements.layers.appendChild(Utils.loadTemplate(`<option value=""></option>`))
236
- this.elements.layers.hidden = false
236
+ this.elements.layers.hidden = !this._umap.getProperty('layerSwitcher')
237
237
  const visible = datalayers.filter((datalayer) => datalayer.isVisible())
238
238
  for (const datalayer of datalayers) {
239
239
  const selected = visible.length === 1 && datalayer.isVisible() ? 'selected' : ''
@@ -57,6 +57,8 @@ export default class Umap {
57
57
  },
58
58
  geojson.properties
59
59
  )
60
+ this.createdAt = new Date(this.properties.created_at)
61
+ this.modifiedAt = this.properties.modified_at
60
62
  this.searchParams = new URLSearchParams(window.location.search)
61
63
 
62
64
  // Locale name (pt_PT, en_US…)
@@ -104,6 +106,11 @@ export default class Umap {
104
106
 
105
107
  if (geojson.properties.schema) this.overrideSchema(geojson.properties.schema)
106
108
 
109
+ // Do not display in an iframe.
110
+ if (window.self !== window.top) {
111
+ this.properties.homeControl = false
112
+ }
113
+
107
114
  this._leafletMap.setup()
108
115
 
109
116
  this.panel = new Panel(this, this._leafletMap)
@@ -237,6 +244,20 @@ export default class Umap {
237
244
  this._activeFeature = feature
238
245
  }
239
246
 
247
+ get modifiedAt() {
248
+ return this._modifiedAt
249
+ }
250
+
251
+ set modifiedAt(at) {
252
+ if (!at) return
253
+ if (typeof at === 'string') {
254
+ at = new Date(at)
255
+ }
256
+ if (!this._modifiedAt || at > this._modifiedAt) {
257
+ this._modifiedAt = at
258
+ }
259
+ }
260
+
240
261
  setPropertiesFromQueryString() {
241
262
  const asBoolean = (key) => {
242
263
  const value = this.searchParams.get(key)
@@ -820,6 +841,7 @@ export default class Umap {
820
841
  'properties.displayPopupFooter',
821
842
  'properties.captionBar',
822
843
  'properties.captionMenus',
844
+ 'properties.layerSwitcher',
823
845
  ])
824
846
  const builder = new MutatingForm(this, UIFields, { umap: this })
825
847
  const controlsOptions = DomUtil.createFieldset(
@@ -629,7 +629,7 @@ U.Editable = L.Editable.extend({
629
629
  const line = new U.LineString(this._umap, datalayer, {
630
630
  geometry: { type: 'LineString', coordinates: [] },
631
631
  })
632
- line._just_married = true
632
+ line._needs_upsert = true
633
633
  return line.ui
634
634
  },
635
635
 
@@ -638,7 +638,7 @@ U.Editable = L.Editable.extend({
638
638
  const poly = new U.Polygon(this._umap, datalayer, {
639
639
  geometry: { type: 'Polygon', coordinates: [] },
640
640
  })
641
- poly._just_married = true
641
+ poly._needs_upsert = true
642
642
  return poly.ui
643
643
  },
644
644
 
@@ -647,7 +647,7 @@ U.Editable = L.Editable.extend({
647
647
  const point = new U.Point(this._umap, datalayer, {
648
648
  geometry: { type: 'Point', coordinates: [latlng.lng, latlng.lat] },
649
649
  })
650
- point._just_married = true
650
+ point._needs_upsert = true
651
651
  return point.ui
652
652
  },
653
653
 
@@ -457,7 +457,6 @@ const locale = {
457
457
  "Choose this dataset": "Choose this dataset",
458
458
  "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
459
459
  "Choose a theme": "Choose a theme",
460
- "Symplify all geometries to points": "Symplify all geometries to points",
461
460
  "Choose this data": "Choose this data",
462
461
  "Search admin boundary": "Search admin boundary",
463
462
  "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@@ -522,10 +521,10 @@ const locale = {
522
521
  "Anonymous": "Anonymous",
523
522
  "created at {date}": "created at {date}",
524
523
  "modified at {date}": "modified at {date}",
525
- "Default zoom": "Default zoom",
526
- "Default latitude": "Default latitude",
527
- "Default longitude": "Default longitude",
528
- "Edit map default view": "Edit map default view",
524
+ "Default zoom": "Zoom predeterminat",
525
+ "Default latitude": "Latitud predeterminada",
526
+ "Default longitude": "Longitud predeterminada",
527
+ "Edit map default view": "Edita la visualització predeterminada del mapa",
529
528
  "Use current center and zoom": "Use current center and zoom",
530
529
  "Layer permalink": "Layer permalink",
531
530
  "Back to home": "Back to home",
@@ -538,7 +537,10 @@ const locale = {
538
537
  "Images": "Images",
539
538
  "Iframes": "Iframes",
540
539
  "Tags": "Tags",
541
- "Geocode": "Geocode"
540
+ "Geocode": "Geocode",
541
+ "Display the back to home icon": "Display the back to home icon",
542
+ "Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
543
+ "Simplify all geometries to points": "Simplify all geometries to points"
542
544
  }
543
545
  L.registerLocale("ca", locale)
544
546
  L.setLocale("ca")
@@ -457,7 +457,6 @@
457
457
  "Choose this dataset": "Choose this dataset",
458
458
  "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
459
459
  "Choose a theme": "Choose a theme",
460
- "Symplify all geometries to points": "Symplify all geometries to points",
461
460
  "Choose this data": "Choose this data",
462
461
  "Search admin boundary": "Search admin boundary",
463
462
  "Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
@@ -522,10 +521,10 @@
522
521
  "Anonymous": "Anonymous",
523
522
  "created at {date}": "created at {date}",
524
523
  "modified at {date}": "modified at {date}",
525
- "Default zoom": "Default zoom",
526
- "Default latitude": "Default latitude",
527
- "Default longitude": "Default longitude",
528
- "Edit map default view": "Edit map default view",
524
+ "Default zoom": "Zoom predeterminat",
525
+ "Default latitude": "Latitud predeterminada",
526
+ "Default longitude": "Longitud predeterminada",
527
+ "Edit map default view": "Edita la visualització predeterminada del mapa",
529
528
  "Use current center and zoom": "Use current center and zoom",
530
529
  "Layer permalink": "Layer permalink",
531
530
  "Back to home": "Back to home",
@@ -538,5 +537,8 @@
538
537
  "Images": "Images",
539
538
  "Iframes": "Iframes",
540
539
  "Tags": "Tags",
541
- "Geocode": "Geocode"
540
+ "Geocode": "Geocode",
541
+ "Display the back to home icon": "Display the back to home icon",
542
+ "Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
543
+ "Simplify all geometries to points": "Simplify all geometries to points"
542
544
  }
@@ -457,7 +457,6 @@ const locale = {
457
457
  "Choose this dataset": "Vyberte tuto datovou sadu",
458
458
  "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: tematická data z OpenStreetMap",
459
459
  "Choose a theme": "Vyberte si téma",
460
- "Symplify all geometries to points": "Zjednodušte všechny geometrie na body",
461
460
  "Choose this data": "Zvolte tato data",
462
461
  "Search admin boundary": "Hledat hranici správce",
463
462
  "Please choose a theme and a boundary first.": "Nejprve si vyberte téma a hranice.",
@@ -538,7 +537,10 @@ const locale = {
538
537
  "Images": "Images",
539
538
  "Iframes": "Iframes",
540
539
  "Tags": "Tags",
541
- "Geocode": "Geocode"
540
+ "Geocode": "Geocode",
541
+ "Display the back to home icon": "Display the back to home icon",
542
+ "Do you want to display layer switcher in caption bar?": "Do you want to display layer switcher in caption bar?",
543
+ "Simplify all geometries to points": "Simplify all geometries to points"
542
544
  }
543
545
  L.registerLocale("cs_CZ", locale)
544
546
  L.setLocale("cs_CZ")