umap-project 3.0.1__py3-none-any.whl → 3.0.3__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 (74) hide show
  1. umap/__init__.py +1 -1
  2. umap/autocomplete.py +9 -0
  3. umap/locale/en/LC_MESSAGES/django.po +11 -7
  4. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  5. umap/locale/fr/LC_MESSAGES/django.po +11 -7
  6. umap/locale/nl/LC_MESSAGES/django.mo +0 -0
  7. umap/locale/nl/LC_MESSAGES/django.po +136 -56
  8. umap/settings/base.py +2 -2
  9. umap/static/umap/base.css +4 -0
  10. umap/static/umap/css/bar.css +2 -1
  11. umap/static/umap/css/form.css +5 -8
  12. umap/static/umap/css/icon.css +1 -1
  13. umap/static/umap/img/16-white.svg +1 -1
  14. umap/static/umap/img/16.svg +1 -1
  15. umap/static/umap/img/24-white.svg +1 -0
  16. umap/static/umap/img/24.svg +2 -1
  17. umap/static/umap/img/source/16-white.svg +3 -3
  18. umap/static/umap/img/source/16.svg +1 -1
  19. umap/static/umap/img/source/24-white.svg +3 -2
  20. umap/static/umap/img/source/24.svg +5 -4
  21. umap/static/umap/js/modules/browser.js +1 -0
  22. umap/static/umap/js/modules/caption.js +2 -2
  23. umap/static/umap/js/modules/data/features.js +7 -10
  24. umap/static/umap/js/modules/data/layer.js +9 -1
  25. umap/static/umap/js/modules/form/fields.js +4 -2
  26. umap/static/umap/js/modules/importers/cadastrefr.js +14 -12
  27. umap/static/umap/js/modules/importers/geodatamine.js +11 -9
  28. umap/static/umap/js/modules/rendering/map.js +2 -4
  29. umap/static/umap/js/modules/rendering/ui.js +0 -1
  30. umap/static/umap/js/modules/schema.js +12 -0
  31. umap/static/umap/js/modules/ui/bar.js +2 -2
  32. umap/static/umap/js/modules/umap.js +23 -1
  33. umap/static/umap/js/modules/utils.js +2 -0
  34. umap/static/umap/js/umap.controls.js +3 -3
  35. umap/static/umap/js/umap.core.js +6 -2
  36. umap/static/umap/locale/cs_CZ.js +4 -2
  37. umap/static/umap/locale/cs_CZ.json +4 -2
  38. umap/static/umap/locale/de.js +4 -2
  39. umap/static/umap/locale/de.json +4 -2
  40. umap/static/umap/locale/en.js +4 -2
  41. umap/static/umap/locale/en.json +4 -2
  42. umap/static/umap/locale/es.js +4 -2
  43. umap/static/umap/locale/es.json +4 -2
  44. umap/static/umap/locale/eu.js +4 -2
  45. umap/static/umap/locale/eu.json +4 -2
  46. umap/static/umap/locale/fa_IR.js +4 -2
  47. umap/static/umap/locale/fa_IR.json +4 -2
  48. umap/static/umap/locale/fr.js +4 -2
  49. umap/static/umap/locale/fr.json +4 -2
  50. umap/static/umap/locale/gl.js +4 -2
  51. umap/static/umap/locale/gl.json +4 -2
  52. umap/static/umap/locale/hu.js +4 -2
  53. umap/static/umap/locale/hu.json +4 -2
  54. umap/static/umap/locale/it.js +4 -2
  55. umap/static/umap/locale/it.json +4 -2
  56. umap/static/umap/locale/nl.js +12 -10
  57. umap/static/umap/locale/nl.json +12 -10
  58. umap/static/umap/locale/pt.js +4 -2
  59. umap/static/umap/locale/pt.json +4 -2
  60. umap/static/umap/locale/pt_PT.js +4 -2
  61. umap/static/umap/locale/pt_PT.json +4 -2
  62. umap/static/umap/locale/zh_TW.js +4 -2
  63. umap/static/umap/locale/zh_TW.json +4 -2
  64. umap/static/umap/map.css +3 -1
  65. umap/templates/umap/search.html +10 -1
  66. umap/tests/integration/test_edit_map.py +1 -7
  67. umap/tests/integration/test_picto.py +10 -2
  68. umap/tests/test_views.py +18 -0
  69. umap/views.py +6 -3
  70. {umap_project-3.0.1.dist-info → umap_project-3.0.3.dist-info}/METADATA +6 -6
  71. {umap_project-3.0.1.dist-info → umap_project-3.0.3.dist-info}/RECORD +74 -74
  72. {umap_project-3.0.1.dist-info → umap_project-3.0.3.dist-info}/WHEEL +0 -0
  73. {umap_project-3.0.1.dist-info → umap_project-3.0.3.dist-info}/entry_points.txt +0 -0
  74. {umap_project-3.0.1.dist-info → umap_project-3.0.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,8 +1,8 @@
1
1
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
2
  <!-- Created with Inkscape (http://www.inkscape.org/) -->
3
3
 
4
- <svg width="288" height="288" viewBox="0 0 76.199999 76.199999" version="1.1" id="svg6237" inkscape:version="1.4 (e7c3feb100, 2024-10-09)" sodipodi:docname="24.svg" inkscape:export-filename="../24.svg" inkscape:export-xdpi="7.52" inkscape:export-ydpi="7.52" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
5
- <sodipodi:namedview id="namedview6239" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:document-units="px" showgrid="true" showguides="true" inkscape:zoom="5.1755289" inkscape:cx="321.22321" inkscape:cy="85.788333" inkscape:window-width="1920" inkscape:window-height="1011" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" inkscape:current-layer="layer1">
4
+ <svg width="288" height="288" viewBox="0 0 76.199999 76.199999" version="1.1" id="svg6237" inkscape:version="1.4.1 (93de688d07, 2025-03-30)" sodipodi:docname="24.svg" inkscape:export-filename="../24.svg" inkscape:export-xdpi="7.52" inkscape:export-ydpi="7.52" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
5
+ <sodipodi:namedview id="namedview6239" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:document-units="px" showgrid="true" showguides="true" inkscape:zoom="8.9060631" inkscape:cx="172.74748" inkscape:cy="256.79135" inkscape:window-width="1920" inkscape:window-height="1011" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" inkscape:current-layer="layer1">
6
6
  <inkscape:grid type="xygrid" id="grid6358" empspacing="6" originx="0" originy="0" spacingy="0.26458333" spacingx="0.26458333" units="px" visible="true" />
7
7
  <inkscape:grid id="grid1" units="px" originx="0" originy="0" spacingx="9.5249999" spacingy="9.5249999" empcolor="#3f3fff" empopacity="0.25098039" color="#ff0000" opacity="0.83529412" empspacing="0" dotted="false" gridanglex="30" gridanglez="30" visible="true" />
8
8
  </sodipodi:namedview>
@@ -44,7 +44,7 @@
44
44
  <path d="m 60.085221,50.800004 c -0.890121,-0.0021 -1.610321,0.711677 -1.612305,1.5875 0.002,0.877761 0.722184,1.586074 1.612305,1.5875 0.593513,-8.73e-4 1.110529,-0.321123 1.389062,-0.79375 h 0.65319 l 0.520899,-0.504362 0.396875,0.380339 0.380338,-0.37207 0.388607,0.380338 0.396875,-0.380338 0.388607,0.380338 0.677994,-0.65319 c 0.09761,-0.09927 0.100016,-0.174188 0,-0.272852 l -0.553971,-0.545703 h -3.241146 c -0.277124,-0.47713 -0.799763,-0.794983 -1.39733,-0.79375 z m -0.7028,1.157552 c 0.233962,-0.0011 0.419905,0.187463 0.42168,0.42168 -0.0017,0.230958 -0.187613,0.419542 -0.42168,0.42168 -0.237929,-0.0024 -0.43214,-0.190722 -0.429948,-0.42168 -0.0022,-0.234217 0.192019,-0.422799 0.429948,-0.42168 z" id="permissions" style="fill:#4d4d4d;fill-opacity:1;stroke-width:0.264583" class="sprite" />
45
45
  <polygon points="12.5,50 12.5,87.5 43.75,87.5 43.75,62.5 56.25,62.5 56.25,87.5 87.5,87.5 87.5,50 100,50 50,0 0,50 " id="home" transform="matrix(0.0635,0,0,0.0635,30.162499,20.902083)" style="fill:#4d4d4d;fill-opacity:1" class="sprite" />
46
46
  <path inkscape:connector-curvature="0" d="m 7.937502,33.337505 c 0,-0.119238 -0.0078,-0.236713 -0.02082,-0.352777 h -0.356658 c -0.159103,-1.275998 -1.168753,-2.285648 -2.44475,-2.445102 v -0.356307 c -0.116064,-0.01304 -0.233539,-0.02082 -0.352778,-0.02082 -0.119239,0 -0.236714,0.0078 -0.352778,0.02082 v 0.356659 c -1.275997,0.159102 -2.285647,1.168752 -2.445103,2.44475 h -0.356305 c -0.01305,0.116064 -0.02081,0.233539 -0.02081,0.352777 0,0.119239 0.0078,0.236714 0.02081,0.352779 h 0.356658 c 0.159103,1.275996 1.168753,2.285659 2.44475,2.445123 v 0.356658 c 0.116064,0.0127 0.233539,0.02037 0.352778,0.02037 0.119239,0 0.236714,-0.0077 0.352778,-0.0209 v -0.356658 c 1.275644,-0.159438 2.285647,-1.168757 2.445102,-2.444753 h 0.356659 c 0.0127,-0.115712 0.02046,-0.233187 0.02046,-0.352779 z m -2.822223,2.084929 v -0.32104 c 0,-0.195085 -0.158044,-0.352777 -0.352777,-0.352777 -0.194734,0 -0.352778,0.157692 -0.352778,0.352777 v 0.32104 c -0.885472,-0.148883 -1.582914,-0.845973 -1.731786,-1.731798 l 0.320675,-2.65e-4 c 0.195086,0 0.352778,-0.158046 0.352778,-0.352779 0,-0.194733 -0.157692,-0.352777 -0.352778,-0.352777 h -0.321028 c 0.149225,-0.885473 0.846667,-1.582915 1.732139,-1.73214 v 0.32103 c 0,0.194733 0.158044,0.352777 0.352778,0.352777 0.194733,0 0.352777,-0.158044 0.352777,-0.352777 v -0.32103 c 0.885825,0.148873 1.583267,0.846315 1.732139,1.73214 h -0.321028 c -0.195086,0 -0.352777,0.158044 -0.352777,0.352777 0,0.194733 0.157691,0.352779 0.352777,0.352779 l 0.321028,2.65e-4 c -0.149225,0.885825 -0.846314,1.582915 -1.732139,1.731798 z" id="geolocation" style="fill:#4d4d4d;fill-opacity:1;stroke-width:0.264583" class="sprite" />
47
- <g id="share" class="sprite" transform="matrix(0.26458333,0,0,0.26458333,-2.6458336,-229.22505)">
47
+ <g id="share" class="sprite" transform="matrix(0.26458333,0,0,0.26458333,-21.695832,-210.17502)">
48
48
  <circle id="path4309" style="fill:none;stroke:#464646;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" cx="100" cy="992.3623" r="11" />
49
49
  <circle transform="rotate(-111.82202)" id="path4819" style="fill:#464646;fill-opacity:1;stroke:none;stroke-width:4.28879" cx="-963.88702" cy="-276.03735" r="2.5" />
50
50
  <circle transform="rotate(-111.82202)" id="path4819-2" style="fill:#464646;fill-opacity:1;stroke:none;stroke-width:4.28879" cx="-956.38037" cy="-281.15619" r="2.5" />
@@ -77,7 +77,7 @@
77
77
  </g>
78
78
  <path style="fill:#464646;fill-opacity:1;stroke:none;stroke-width:1.84551;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" inkscape:transform-center-x="-0.0017170804" inkscape:transform-center-y="-1.1593678" d="m 31.537126,45.771563 0.577355,-2.184903 -1.687401,-1.349931 h 2.154994 l 0.756436,-2.28465 0.754501,2.284227 h 2.154902 l -1.688682,1.351121 0.575368,2.185485 -1.798166,-1.252432 z" id="star" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccccccccc" class="sprite" />
79
79
  <path style="fill:none;fill-opacity:1;stroke:#464646;stroke-width:0.264583;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" inkscape:transform-center-x="-0.0017170804" inkscape:transform-center-y="-1.1593678" d="m 40.742193,45.771563 0.577355,-2.184903 -1.687401,-1.349931 h 2.154994 l 0.756436,-2.28465 0.754502,2.284227 h 2.154901 l -1.688682,1.351121 0.575368,2.185485 -1.798169,-1.252432 z" id="starred" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccccccccc" class="sprite" />
80
- <path d="m 45.33157,52.032511 0.367177,0.21791 c 0.07232,0.04294 0.09577,0.135732 0.0524,0.207275 -0.01292,0.02122 -0.03092,0.03903 -0.0524,0.0518 l -2.836254,1.6832 -2.836235,-1.6832 c -0.07233,-0.04294 -0.09579,-0.135704 -0.05238,-0.207274 0.0129,-0.02125 0.03089,-0.03905 0.05238,-0.05181 l 0.367179,-0.21791 2.469056,1.465315 z m 0,1.419992 0.367177,0.217911 c 0.07232,0.04294 0.09577,0.135731 0.0524,0.207274 -0.01292,0.02125 -0.03092,0.03903 -0.0524,0.05181 l -2.679097,1.58996 c -0.09674,0.05739 -0.217576,0.05739 -0.314315,0 l -2.679077,-1.58996 c -0.07233,-0.04292 -0.09579,-0.135705 -0.05238,-0.207249 0.0129,-0.02127 0.03089,-0.03908 0.05238,-0.05183 l 0.367179,-0.217911 2.469056,1.465315 z m -2.31192,-4.196946 2.679097,1.589967 c 0.07232,0.04292 0.09577,0.135715 0.0524,0.207256 -0.01292,0.02126 -0.03092,0.03906 -0.0524,0.05182 l -2.836254,1.683221 -2.836235,-1.683221 c -0.07233,-0.04292 -0.09579,-0.135716 -0.05238,-0.207256 0.0129,-0.02126 0.03089,-0.03906 0.05238,-0.05182 l 2.679077,-1.589967 c 0.09674,-0.05741 0.217576,-0.05741 0.314315,0 z" fill="#4d4d4d" id="datalayers" style="stroke-width:0.264583" />
80
+ <path d="m 45.33157,52.032514 0.367177,0.21791 c 0.07232,0.04294 0.09577,0.135732 0.0524,0.207275 -0.01292,0.02122 -0.03092,0.03903 -0.0524,0.0518 l -2.836254,1.6832 -2.836235,-1.6832 c -0.07233,-0.04294 -0.09579,-0.135704 -0.05238,-0.207274 0.0129,-0.02125 0.03089,-0.03905 0.05238,-0.05181 l 0.367179,-0.21791 2.469056,1.465315 z m 0,1.419992 0.367177,0.217911 c 0.07232,0.04294 0.09577,0.135731 0.0524,0.207274 -0.01292,0.02125 -0.03092,0.03903 -0.0524,0.05181 l -2.679097,1.58996 c -0.09674,0.05739 -0.217576,0.05739 -0.314315,0 l -2.679077,-1.58996 c -0.07233,-0.04292 -0.09579,-0.135705 -0.05238,-0.207249 0.0129,-0.02127 0.03089,-0.03908 0.05238,-0.05183 l 0.367179,-0.217911 2.469056,1.465315 z m -2.31192,-4.196946 2.679097,1.589967 c 0.07232,0.04292 0.09577,0.135715 0.0524,0.207256 -0.01292,0.02126 -0.03092,0.03906 -0.0524,0.05182 l -2.836254,1.683221 -2.836235,-1.683221 c -0.07233,-0.04292 -0.09579,-0.135716 -0.05238,-0.207256 0.0129,-0.02126 0.03089,-0.03906 0.05238,-0.05182 l 2.679077,-1.589967 c 0.09674,-0.05741 0.217576,-0.05741 0.314315,0 z" fill="#4d4d4d" id="datalayers" style="stroke-width:0.264583" />
81
81
  <g id="tilelayers" transform="translate(19.049999,56.885416)">
82
82
  <path d="m 26.772659,3.4276506 h -4.243945 c -0.07035,0 -0.137814,0.027945 -0.187558,0.077687 -0.04974,0.049744 -0.07769,0.1172104 -0.07769,0.1875578 v 4.2439431 c 0,0.070353 0.02794,0.1378215 0.07769,0.1875631 0.04974,0.049742 0.11721,0.077682 0.187558,0.077682 h 4.243945 c 0.07035,0 0.137822,-0.02794 0.187563,-0.077682 0.04974,-0.049742 0.07768,-0.1172104 0.07768,-0.1875631 v -4.2439431 c 0,-0.070347 -0.02794,-0.1378135 -0.07768,-0.1875578 -0.04974,-0.049742 -0.11721,-0.077687 -0.187563,-0.077687 z m -0.265245,4.1590648 h -3.713453 v -3.546348 h 3.713453 z" fill="#464646" id="path2349" style="stroke-width:0.264583" />
83
83
  <g mask="url(#mask0_181_11898)" id="g2376" transform="matrix(0.26458333,0,0,0.26458333,20.637501,1.8520833)">
@@ -110,5 +110,6 @@
110
110
  <path inkscape:connector-curvature="0" id="path3789" style="font-weight:bold;font-size:12px;-inkscape-font-specification:'Sans Bold';fill:#4d4d4d;stroke-width:0.75" d="m 9,1046.0464 h -2.3698034 v -0.3223 c 0,-0.3596 0.072207,-0.6775 0.2166302,-0.9539 0.1444174,-0.2807 0.4485749,-0.636 0.9124728,-1.0658 l 0.4201314,-0.3816 c 0.249449,-0.228 0.4310681,-0.4429 0.5448577,-0.6446 0.1181576,-0.2019 0.1772384,-0.4036 0.177243,-0.6053 -4.6e-6,-0.3071 -0.1050376,-0.5462 -0.3150985,-0.7171 -0.2100697,-0.1756 -0.5032861,-0.2632 -0.87965,-0.2632 -0.3544889,0 -0.7374207,0.075 -1.1487968,0.2237 -0.4113804,0.1446 -0.840264,0.3618 -1.2866522,0.6513 v -2.0659 c 0.5295391,-0.184 1.0131273,-0.32 1.4507661,-0.4077 0.437634,-0.088 0.8599531,-0.1317 1.2669587,-0.1317 1.0678292,0 1.8818328,0.2194 2.442012,0.6579 0.560169,0.4341 0.840256,1.0702 0.840263,1.9078 -7e-6,0.4298 -0.08535,0.8159 -0.256017,1.158 -0.170685,0.3377 -0.461713,0.7017 -0.873085,1.092 l -0.4201313,0.375 c -0.297598,0.272 -0.4923463,0.4913 -0.5842451,0.658 -0.091909,0.1622 -0.1378603,0.342 -0.1378556,0.5394 v 0.296 m -2.3698034,0.9739 h 2.3698034 v 2.342 h -2.3698034 v -2.342" sodipodi:nodetypes="ccsccccccsccccsccccccccccccc" />
111
111
  </g>
112
112
  </g>
113
+ <path id="copy" style="fill:#4d4d4d;stroke-width:0.264582;paint-order:fill markers stroke" d="m 42.218298,69.320832 v 1.288405 h 1.472463 v 1.472465 h 1.288405 v -2.76087 z m -1.472465,1.472463 v 2.760871 h 2.760869 v -2.760871 z" />
113
114
  </g>
114
115
  </svg>
@@ -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
  }
@@ -218,6 +217,7 @@ class Feature {
218
217
 
219
218
  edit(event) {
220
219
  if (!this._umap.editEnabled || this.isReadOnly()) return
220
+ if (this._umap.editedFeature === this) return
221
221
  const container = DomUtil.create('div', 'umap-feature-container')
222
222
  DomUtil.createTitle(
223
223
  container,
@@ -326,7 +326,9 @@ class Feature {
326
326
  ]
327
327
  }
328
328
 
329
- endEdit() {}
329
+ endEdit() {
330
+ this.ui.disableEdit()
331
+ }
330
332
 
331
333
  getDisplayName() {
332
334
  const keys = U.LABEL_KEYS.slice() // Copy.
@@ -828,11 +830,6 @@ class Path extends Feature {
828
830
  )
829
831
  }
830
832
 
831
- endEdit() {
832
- this.ui.disableEdit()
833
- super.endEdit()
834
- }
835
-
836
833
  transferShape(at, to) {
837
834
  const shape = this.ui.enableEdit().deleteShapeAt(at)
838
835
  // FIXME: make Leaflet.Editable send an event instead
@@ -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 () {
@@ -111,7 +111,6 @@ const PointMixin = {
111
111
  this.on('dragend', (event) => {
112
112
  this.isDirty = true
113
113
  this.feature.edit(event)
114
- // this.feature.pullGeometry(false)
115
114
  })
116
115
  if (!this.feature.isReadOnly()) this.on('mouseover', this._enableDragging)
117
116
  this.on('mouseout', this._onMouseOut)
@@ -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
+ geojson.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)
@@ -525,7 +546,6 @@ export default class Umap {
525
546
  'Ctrl+e': {
526
547
  if: () => this.hasEditMode(),
527
548
  do: () => {
528
- console.log('doing')
529
549
  if (!this.editEnabled) this.enableEdit()
530
550
  else if (!this.isDirty) this.disableEdit()
531
551
  },
@@ -813,6 +833,7 @@ export default class Umap {
813
833
  UIFields.push(`properties.${name}Control`)
814
834
  }
815
835
  UIFields = UIFields.concat([
836
+ 'properties.homeControl',
816
837
  'properties.moreControl',
817
838
  'properties.scrollWheelZoom',
818
839
  'properties.miniMap',
@@ -821,6 +842,7 @@ export default class Umap {
821
842
  'properties.displayPopupFooter',
822
843
  'properties.captionBar',
823
844
  'properties.captionMenus',
845
+ 'properties.layerSwitcher',
824
846
  ])
825
847
  const builder = new MutatingForm(this, UIFields, { umap: this })
826
848
  const controlsOptions = DomUtil.createFieldset(
@@ -283,6 +283,8 @@ export function greedyTemplate(str, data, ignore) {
283
283
  }
284
284
 
285
285
  export function naturalSort(a, b, lang) {
286
+ a ??= ''
287
+ b ??= ''
286
288
  return a
287
289
  .toString()
288
290
  .toLowerCase()
@@ -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
 
@@ -113,8 +113,12 @@ L.DomUtil.createCopiableInput = (parent, label, value) => {
113
113
  input.type = 'text'
114
114
  input.readOnly = true
115
115
  input.value = value
116
- const button = L.DomUtil.createButtonIcon(wrapper, 'icon-copy', L._('copy'), () =>
117
- L.Util.copyToClipboard(input.value)
116
+ const button = L.DomUtil.createButtonIcon(
117
+ wrapper,
118
+ 'icon-copy',
119
+ L._('copy'),
120
+ () => L.Util.copyToClipboard(input.value),
121
+ 24
118
122
  )
119
123
  button.type = 'button'
120
124
  return input
@@ -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")
@@ -457,7 +457,6 @@
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,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": "Diesen Datensatz auswählen",
458
458
  "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematische Daten von OpenStreetMap",
459
459
  "Choose a theme": "Thema auswählen",
460
- "Symplify all geometries to points": "Alle Geometrien zu Punkten vereinfachen",
461
460
  "Choose this data": "Diese Daten auswählen",
462
461
  "Search admin boundary": "Administrative Grenze suchen",
463
462
  "Please choose a theme and a boundary first.": "Bitte wähle zuerst ein Thema und eine administrative Grenze.",
@@ -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("de", locale)
544
546
  L.setLocale("de")
@@ -457,7 +457,6 @@
457
457
  "Choose this dataset": "Diesen Datensatz auswählen",
458
458
  "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematische Daten von OpenStreetMap",
459
459
  "Choose a theme": "Thema auswählen",
460
- "Symplify all geometries to points": "Alle Geometrien zu Punkten vereinfachen",
461
460
  "Choose this data": "Diese Daten auswählen",
462
461
  "Search admin boundary": "Administrative Grenze suchen",
463
462
  "Please choose a theme and a boundary first.": "Bitte wähle zuerst ein Thema und eine administrative Grenze.",
@@ -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": "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.",
@@ -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("en", locale)
544
546
  L.setLocale("en")
@@ -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.",
@@ -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": "Elegir este conjunto de datos",
458
458
  "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: datos temáticos de OpenStreetMap",
459
459
  "Choose a theme": "Elegir un tema",
460
- "Symplify all geometries to points": "Simplificar todas las geometrías a puntos",
461
460
  "Choose this data": "Elegir estos datos",
462
461
  "Search admin boundary": "Buscar límite administrativo",
463
462
  "Please choose a theme and a boundary first.": "Primero elige un tema y un límite.",
@@ -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("es", locale)
544
546
  L.setLocale("es")
@@ -457,7 +457,6 @@
457
457
  "Choose this dataset": "Elegir este conjunto de datos",
458
458
  "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: datos temáticos de OpenStreetMap",
459
459
  "Choose a theme": "Elegir un tema",
460
- "Symplify all geometries to points": "Simplificar todas las geometrías a puntos",
461
460
  "Choose this data": "Elegir estos datos",
462
461
  "Search admin boundary": "Buscar límite administrativo",
463
462
  "Please choose a theme and a boundary first.": "Primero elige un tema y un límite.",
@@ -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": "Aukeratu datu-multzo hau",
458
458
  "GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: OpenStreetMap-eko datu tematikoak",
459
459
  "Choose a theme": "Aukeratu gai bat",
460
- "Symplify all geometries to points": "Sinplifikatu geometria guztiak puntutan",
461
460
  "Choose this data": "Aukeratu datu hauek",
462
461
  "Search admin boundary": "Bilatu muga administratiboa",
463
462
  "Please choose a theme and a boundary first.": "Aukeratu gai bat eta muga bat.",
@@ -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("eu", locale)
544
546
  L.setLocale("eu")