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
@@ -2,8 +2,12 @@
2
2
  <!-- Created with Inkscape (http://www.inkscape.org/) -->
3
3
 
4
4
  <svg width="144" height="144" id="svg2" version="1.1" inkscape:version="1.2.2 (b0a8486541, 2022-12-01)" sodipodi:docname="16-white.svg" inkscape:export-filename="16-white.png" inkscape:export-xdpi="96" inkscape:export-ydpi="96" 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" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
5
- <defs id="defs4" />
6
- <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="3.9131365" inkscape:cx="47.659978" inkscape:cy="71.17053" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" inkscape:window-width="1920" inkscape:window-height="1019" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" showguides="true" inkscape:guide-bbox="true" inkscape:snap-grids="true" inkscape:snap-to-guides="true" inkscape:showpageshadow="2" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1">
5
+ <defs id="defs4">
6
+ <clipPath id="clip0_241_10857">
7
+ <rect width="18.049999" height="19.01" fill="#ffffff" id="rect586" x="0" y="0" />
8
+ </clipPath>
9
+ </defs>
10
+ <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="9.2657163" inkscape:cx="68.963907" inkscape:cy="48.29632" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" inkscape:window-width="1920" inkscape:window-height="1019" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" showguides="true" inkscape:guide-bbox="true" inkscape:snap-grids="true" inkscape:snap-to-guides="true" inkscape:showpageshadow="2" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1">
7
11
  <inkscape:grid type="xygrid" id="grid3004" empspacing="4" visible="true" enabled="true" snapvisiblegridlinesonly="true" originx="0" originy="0" />
8
12
  <sodipodi:guide orientation="-1,0" position="24,144" id="guide3084" inkscape:locked="false" inkscape:label="" inkscape:color="rgb(0,134,229)" />
9
13
  <sodipodi:guide orientation="0,1" position="0,72" id="guide3086" inkscape:locked="false" inkscape:label="" inkscape:color="rgb(0,134,229)" />
@@ -49,14 +53,12 @@
49
53
  <g id="text4356" style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#4d4d4d;fill-opacity:1;stroke:none" transform="translate(-4,-172.00004)">
50
54
  <path inkscape:connector-curvature="0" id="path4384" style="font-variant:normal;font-stretch:normal;font-size:20px;font-family:Arial;-inkscape-font-specification:Arial;fill:#f2f2f2;fill-opacity:1;stroke:#999999;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="m 35.742187,999.43835 3.076172,-3.07617 -3.066406,-3.0664 1.191406,-1.19141 3.066407,3.06641 3.05664,-3.05664 1.171875,1.18164 -3.046875,3.05664 3.066406,3.0664 -1.191406,1.19138 -3.066406,-3.06638 -3.076172,3.07618 -1.181641,-1.18165" />
51
55
  </g>
52
- <path inkscape:connector-curvature="0" d="m 11.192256,853.3618 2e-6,-4.19993 -4.192255,10e-6 -3e-6,-1.62667 h 4.192263 v -4.17331 l 1.608812,0.007 0.0067,4.16664 h 4.192255 l -3.9e-5,1.62662 -4.19222,4e-5 -1.5e-5,4.19994 h -1.615475" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:20px;line-height:125%;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;fill:#4d4d4d;fill-opacity:1;stroke:none" id="path4384-3" />
53
56
  <path style="fill:#f2f2f2;fill-opacity:1;stroke:#999999;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="m 63.71429,866.36213 -1.14285,1.14286 2.28571,2.28572 1.14285,-1.14286 z m -1.71429,1.71428 -6.285714,6.28574 2.285715,2.2857 6.285719,-6.28572 z m -6.285714,6.28574 -1.714286,3.99999 4.000001,-1.71429 z" id="path3684" inkscape:connector-curvature="0" sodipodi:nodetypes="cccccccccccccc" />
54
57
  <text xml:space="preserve" style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" x="41.647079" y="916.79706" id="text4457-6"><tspan y="916.79706" x="41.647079" sodipodi:role="line" id="tspan4459-6" style="font-size:30.4762px;line-height:1.25;font-family:sans-serif"> </tspan></text>
55
58
  <g id="text4356-2" style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none" transform="translate(44,-124.00004)">
56
59
  <path inkscape:connector-curvature="0" id="path4384-2" style="font-variant:normal;font-stretch:normal;font-size:20px;font-family:Arial;-inkscape-font-specification:Arial;fill:#f2f2f2;fill-opacity:1" d="m 35.742187,999.43835 3.076172,-3.07617 -3.066406,-3.0664 1.191406,-1.19141 3.066407,3.06641 3.05664,-3.05664 1.171875,1.18164 -3.046875,3.05664 3.066406,3.0664 -1.191406,1.19138 -3.066406,-3.06638 -3.076172,3.07618 -1.181641,-1.18165" />
57
60
  </g>
58
61
  <path style="fill:#b3b3b3;fill-opacity:1;stroke:none" d="m 63.71429,890.36216 -1.14285,1.1428 2.28571,2.2858 1.14285,-1.1429 z m -1.71429,1.7143 -6.285714,6.28572 2.285714,2.2857 6.28572,-6.2857 z m -6.285714,6.28572 -1.714286,4 4,-1.7143 z" id="path3684-2" inkscape:connector-curvature="0" sodipodi:nodetypes="cccccccccccccc" />
59
- <path id="table-5-8-8-6" style="fill:#464646;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 30,914.3622 v 1 h 1 v -1 z m 2,0 v 1 h 10 v -1 z m -2,2 v 1 h 1 v -1 z m 2,0 v 1 h 10 v -1 z m -2,2 v 1 h 1 v -1 z m 2,0 v 1 h 10 v -1 z m -2,2 v 1 h 1 v -1 z m 2,0 v 1 h 10 v -1 z m -2,2 v 1 h 1 v -1 z m 2,0 v 1 h 10 v -1 z m -2,2 v 1 h 1 v -1 z m 2,0 v 1 h 10 v -1 z" inkscape:connector-curvature="0" />
60
62
  <path inkscape:connector-curvature="0" id="table-5-8-8-6-1" style="fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 54,914.3622 v 1 h 1 v -1 z m 2,0 v 1 h 10 v -1 z m -2,2 v 1 h 1 v -1 z m 2,0 v 1 h 10 v -1 z m -2,2 v 1 h 1 v -1 z m 2,0 v 1 h 10 v -1 z m -2,2 v 1 h 1 v -1 z m 2,0 v 1 h 10 v -1 z m -2,2 v 1 h 1 v -1 z m 2,0 v 1 h 10 v -1 z m -2,2 v 1 h 1 v -1 z m 2,0 v 1 h 10 v -1 z" />
61
63
  <circle style="fill:#f2f2f2;fill-opacity:1;stroke:#999999;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="path3764" cx="108" cy="844.36218" r="1.5" />
62
64
  <path style="fill:#f2f2f2;fill-opacity:1;stroke:#999999;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="m 107,847.36218 h 2 v 6 h -2 z" id="rect4274" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccc" />
@@ -152,6 +154,18 @@
152
154
  <rect style="fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect4241-8-2" width="2" height="2" x="85" y="901.36218" />
153
155
  <rect style="fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" id="rect4243-2-5" width="2" height="2" x="89" y="901.36218" />
154
156
  <path style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:#999999;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="m 131,937.3621 v 1 c -1.42857,0 -3.28571,0.5999 -4,2 v 1 h 10 v -1 c -0.71429,-1.4001 -2.57143,-2 -4,-2 v -1 z m -4,5 2,9 h 6 l 2,-9 z" id="delete-30-7" inkscape:connector-curvature="0" sodipodi:nodetypes="cccccccccccccc" inkscape:label="delete-30" />
155
- <path d="m 60.05856,945.6588 c 1.5887,0 3.11185,0.6337 4.23522,1.7571 1.12337,1.1232 1.7553,2.6464 1.75709,4.2352 0,0.238 -0.12691,0.4577 -0.3329,0.5766 -0.20598,0.1189 -0.45982,0.1189 -0.66579,0 -0.20598,-0.1189 -0.33291,-0.3386 -0.33291,-0.5766 0,-1.6651 -0.88828,-3.2037 -2.33028,-4.0363 -1.44199,-0.8324 -3.218566,-0.8324 -4.660564,0 -1.441999,0.8326 -2.330283,2.3712 -2.330283,4.0363 0,0.238 -0.126916,0.4577 -0.332898,0.5766 -0.205982,0.1189 -0.459818,0.1189 -0.665795,0 -0.205978,-0.1189 -0.332898,-0.3386 -0.332898,-0.5766 0.0018,-1.5887 0.633685,-3.1118 1.757091,-4.2352 1.123215,-1.1234 2.646403,-1.7553 4.235217,-1.7571 z m 0,-0.6658 c -0.882924,0 -1.729586,-0.3507 -2.353913,-0.9751 -0.624325,-0.6243 -0.975066,-1.471 -0.975066,-2.3539 0,-0.8829 0.350734,-1.7296 0.975066,-2.3539 0.624334,-0.6244 1.470989,-0.9751 2.353913,-0.9751 0.88292,0 1.72959,0.3507 2.35391,0.9751 0.62432,0.6243 0.97506,1.471 0.97506,2.3539 -8.2e-4,0.8826 -0.35206,1.7288 -0.97624,2.3528 -0.62402,0.6241 -1.47012,0.9752 -2.35273,0.9762 z m 0,-1.3316 c 0.52982,0 1.03776,-0.2105 1.41244,-0.5849 0.37451,-0.3747 0.58494,-0.8827 0.58494,-1.4125 0,-0.5298 -0.21043,-1.0377 -0.58494,-1.4124 -0.37466,-0.3745 -0.88262,-0.585 -1.41244,-0.585 -0.529824,0 -1.037768,0.2105 -1.41244,0.585 -0.374512,0.3747 -0.584948,0.8826 -0.584948,1.4124 0,0.5298 0.210436,1.0378 0.584948,1.4125 0.37466,0.3744 0.882616,0.5849 1.41244,0.5849 z" id="path349" style="fill:#f2f2f2;fill-opacity:1;stroke:#999999;stroke-width:0.178;stroke-dasharray:none;stroke-opacity:1" />
157
+ <path d="m 113.2903,943.46769 0.9072,0.5491 c 0.1786,0.10817 0.2366,0.34196 0.1294,0.52223 -0.0319,0.0535 -0.0764,0.0983 -0.1294,0.13055 l -7.00717,4.24121 -7.00708,-4.24121 c -0.17869,-0.10817 -0.236639,-0.34196 -0.12942,-0.52222 0.0319,-0.0536 0.0763,-0.0984 0.12942,-0.13056 l 0.90714,-0.5491 6.09994,3.69219 z m 0,3.57799 0.9072,0.5491 c 0.1786,0.1081 0.2366,0.3419 0.1294,0.5222 -0.0319,0.0535 -0.0764,0.0983 -0.1294,0.1306 l -6.61891,4.0061 c -0.239,0.1447 -0.53753,0.1447 -0.77652,0 l -6.61882,-4.0061 c -0.17869,-0.1082 -0.236639,-0.342 -0.12942,-0.5223 0.0319,-0.0536 0.0763,-0.0984 0.12942,-0.1305 l 0.90714,-0.5491 6.09994,3.6921 z m -5.71171,-10.57501 6.61891,4.00621 c 0.1786,0.10815 0.2366,0.34196 0.1294,0.52222 -0.0319,0.0536 -0.0764,0.0984 -0.1294,0.13056 l -7.00717,4.24119 -7.00708,-4.24119 c -0.17869,-0.10815 -0.236639,-0.34196 -0.12942,-0.52222 0.0319,-0.0536 0.0763,-0.0984 0.12942,-0.13056 l 6.61882,-4.00621 c 0.23899,-0.14465 0.53752,-0.14465 0.77652,0 z" fill="#4d4d4d" id="path437" style="fill:#f2f2f2;fill-opacity:1;stroke:#999999;stroke-opacity:1;stroke-width:0.178;stroke-dasharray:none" />
158
+ <path id="linestring" style="color:#000000;fill:#f2f2f2;fill-opacity:1;fill-rule:evenodd;stroke:#999999;stroke-width:0.2;stroke-dasharray:none;stroke-opacity:1" d="m 7,937.36218 v 2 h 1.8828125 l 6.1171875,3.05859 v 0.23438 l -6.7070312,6.70703 h -1.2929688 v 2 h 2 v -1.29297 l 6.707031,-6.70703 h 1.292969 v -2 h -1.882812 l -6.117188,-3.05859 v -0.94141 z" />
159
+ <path id="polygon" style="fill:#f2f2f2;fill-rule:evenodd;stroke:#999999;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-dasharray:none;fill-opacity:1" d="M 29 936.36218 L 29 938.36218 L 29.927734 938.36218 L 29.072266 950.36218 L 28 950.36218 L 28 952.36218 L 30 952.36218 L 30 951.16296 L 38 949.5614 L 38 950.36218 L 40 950.36218 L 40 948.36218 L 39.222656 948.36218 L 40.777344 941.36218 L 42 941.36218 L 42 939.36218 L 40 939.36218 L 40 940.08874 L 31 937.63562 L 31 936.36218 L 29 936.36218 z " />
160
+ <path id="marker" d="m 84,936.36218 c -2.625,0 -5.25,1.70216 -6,5.1064 0,2.04256 1.5,6.12768 6,10.8936 4.5,-4.76592 6,-8.85104 6,-10.8936 -0.75,-3.40424 -3.375,-5.1064 -6,-5.1064 z m 0,2.38304 c 1.656857,0 3,1.21928 3,2.72336 0,1.50408 -1.343143,2.72344 -3,2.72344 -1.656848,0 -3,-1.21936 -3,-2.72344 0,-1.50408 1.343152,-2.72336 3,-2.72336 z" style="fill:#f2f2f2;fill-opacity:1;stroke:#999999;stroke-width:0.25;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" inkscape:connector-curvature="0" />
161
+ <g transform="matrix(0.16294606,0,0,0.16295934,27.835262,912.23132)" id="settings" style="fill:#f2f2f2;fill-opacity:1;stroke:#999999;stroke-width:1.49736;stroke-miterlimit:4;stroke-dasharray:none" class="sprite">
162
+ <path inkscape:connector-curvature="0" d="m 98.762,43.652 c -0.186,-1.386 -1.481,-2.582 -2.876,-2.659 l -6.172,-0.337 c -1.395,-0.076 -2.899,-1.224 -3.341,-2.55 l -2.28,-5.518 c -0.629,-1.249 -0.379,-3.121 0.553,-4.161 l 4.122,-4.6 c 0.933,-1.042 0.962,-2.77 0.066,-3.842 l -8.813,-8.813 c -1.073,-0.897 -2.803,-0.867 -3.845,0.065 l -4.598,4.122 c -1.039,0.934 -2.915,1.182 -4.161,0.551 l -5.521,-2.279 c -1.324,-0.442 -2.472,-1.945 -2.549,-3.34 l -0.337,-6.17 c -0.077,-1.396 -1.272,-2.691 -2.659,-2.878 0,0 -3.252,-0.44 -6.248,-0.44 -2.991,0 -6.243,0.44 -6.243,0.44 -1.386,0.188 -2.582,1.483 -2.658,2.878 l -0.338,6.17 c -0.076,1.396 -1.224,2.898 -2.551,3.34 l -5.517,2.279 c -1.249,0.631 -3.122,0.382 -4.161,-0.551 l -4.601,-4.122 c -1.042,-0.932 -2.769,-0.962 -3.842,-0.065 l -8.813,8.813 c -0.897,1.073 -0.867,2.801 0.066,3.842 l 4.122,4.6 c 0.933,1.041 1.182,2.913 0.551,4.161 l -2.279,5.518 c -0.442,1.326 -1.946,2.474 -3.34,2.55 l -6.17,0.337 c -1.396,0.077 -2.691,1.272 -2.879,2.659 0,0 -0.439,3.253 -0.439,6.243 0,2.99 0.44,6.24 0.44,6.24 0.188,1.389 1.483,2.582 2.879,2.659 l 6.169,0.339 c 1.396,0.075 2.898,1.225 3.341,2.549 l 2.278,5.517 c 0.631,1.248 0.381,3.122 -0.551,4.163 l -4.122,4.598 c -0.933,1.042 -0.963,2.771 -0.066,3.845 l 8.814,8.813 c 1.073,0.896 2.801,0.866 3.842,-0.066 l 4.6,-4.122 c 1.041,-0.932 2.913,-1.182 4.161,-0.553 l 5.517,2.28 c 1.327,0.441 2.475,1.946 2.55,3.343 l 0.338,6.168 c 0.076,1.395 1.272,2.692 2.658,2.88 0,0 3.252,0.439 6.244,0.439 2.996,0 6.25,-0.439 6.25,-0.439 1.385,-0.188 2.58,-1.485 2.657,-2.88 l 0.337,-6.168 c 0.077,-1.396 1.225,-2.901 2.551,-3.343 l 5.517,-2.28 c 1.248,-0.629 3.122,-0.379 4.163,0.553 l 4.598,4.122 c 1.042,0.933 2.771,0.964 3.843,0.067 l 8.815,-8.814 c 0.896,-1.073 0.866,-2.803 -0.066,-3.845 l -4.122,-4.598 c -0.932,-1.041 -1.182,-2.915 -0.553,-4.163 l 2.28,-5.517 c 0.441,-1.324 1.946,-2.474 3.341,-2.549 l 6.172,-0.339 c 1.395,-0.077 2.692,-1.271 2.876,-2.659 0,0 0.441,-3.25 0.441,-6.24 0,-2.99 -0.441,-6.243 -0.441,-6.243 z m -48.658,18.709 c -6.886,0 -12.468,-5.585 -12.468,-12.467 0,-6.885 5.582,-12.467 12.468,-12.467 6.89,0 12.475,5.582 12.475,12.467 -10e-4,6.882 -5.586,12.467 -12.475,12.467 z" id="path27812" style="fill:#f2f2f2;fill-opacity:1;stroke:#999999;stroke-width:1.49736;stroke-miterlimit:4;stroke-dasharray:none" />
163
+ </g>
164
+ <g clip-path="url(#clip0_241_10857)" id="undo" transform="matrix(0.71300568,0,0,0.66260978,53.493751,938.13028)" style="fill:none;stroke:#f2f2f2;stroke-width:1.45488;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1">
165
+ <path d="m 1.07001,4.41003 h 9.41999 c 0.9234,-0.0066 1.8391,0.16957 2.6941,0.5184 0.8551,0.34883 1.6327,0.8634 2.288,1.51407 0.6553,0.65067 1.1754,1.42458 1.5303,2.27713 0.3549,0.85256 0.5376,1.76697 0.5376,2.69037 0.0067,0.9277 -0.1712,1.8474 -0.5231,2.7058 -0.3519,0.8583 -0.871,1.6382 -1.527,2.2941 -0.656,0.656 -1.4358,1.1751 -2.2941,1.527 -0.8584,0.352 -1.7781,0.5298 -2.7058,0.5231 h -9.41999" stroke="#f2f2f2" stroke-miterlimit="10" id="path580" style="fill:none;stroke:#f2f2f2;stroke-width:1.45486;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1" />
166
+ <path d="m 4.75002,8.44998 -4.039998,-4.05 4.039998,-4.050004" stroke="#f2f2f2" stroke-miterlimit="10" id="path582" style="fill:none;stroke:#f2f2f2;stroke-width:1.45486;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1" />
167
+ </g>
168
+ <path d="m 9,849.93721 v 4.04997 c 0,0.20708 0.167895,0.375 0.375,0.375 h 5.25 c 0.207075,0 0.375,-0.16792 0.375,-0.375 v -4.04997 c 0,-0.20708 -0.167925,-0.375 -0.375,-0.375 h -5.25 c -0.207105,0 -0.375,0.16792 -0.375,0.375 z" stroke="#f2f2f2" id="path438" style="fill:none;stroke-width:0.999997" />
169
+ <path d="m 15.21255,842.36218 h -8.83755 c -0.207105,0 -0.375,0.1679 -0.375,0.37499 v 11.24993 c 0,0.20708 0.167895,0.375 0.375,0.375 h 11.25 c 0.207075,0 0.375,-0.16792 0.375,-0.375 v -8.67664 c 0,-0.0953 -0.0363,-0.18697 -0.1014,-0.25648 l -2.41245,-2.57327 c -0.07095,-0.0756 -0.16995,-0.11853 -0.2736,-0.11853 z" stroke="#f2f2f2" id="save" style="fill:none;stroke-width:0.999997" />
156
170
  </g>
157
171
  </svg>
@@ -314,13 +314,11 @@ L.U.EditControl = L.Control.extend({
314
314
  },
315
315
 
316
316
  onAdd: function (map) {
317
- const container = L.DomUtil.create(
318
- 'div',
319
- 'leaflet-control-edit-enable umap-control'
320
- ),
317
+ const container = L.DomUtil.create('div', 'leaflet-control-edit-enable'),
321
318
  edit = L.DomUtil.create('a', '', container)
322
319
  edit.href = '#'
323
320
  edit.title = `${L._('Enable editing')} (Ctrl+E)`
321
+ edit.textContent = L._('Edit')
324
322
 
325
323
  L.DomEvent.addListener(edit, 'click', L.DomEvent.stop).addListener(
326
324
  edit,
@@ -671,6 +669,9 @@ L.U.DataLayer.addInitHook(function () {
671
669
  L.U.Map.include({
672
670
  _openBrowser: function () {
673
671
  const browserContainer = L.DomUtil.create('div', 'umap-browse-data')
672
+ // HOTFIX. Remove when this is merged and released:
673
+ // https://github.com/Leaflet/Leaflet/pull/9052
674
+ L.DomEvent.disableClickPropagation(browserContainer)
674
675
 
675
676
  const title = L.DomUtil.add(
676
677
  'h3',
@@ -750,11 +751,7 @@ L.U.Map.include({
750
751
  const build = () => {
751
752
  ul.innerHTML = ''
752
753
  datalayer.eachFeature((feature) => {
753
- if (
754
- (filterValue && !feature.matchFilter(filterValue, filterKeys)) ||
755
- feature.properties.isVisible === false
756
- )
757
- return
754
+ if (filterValue && !feature.matchFilter(filterValue, filterKeys)) return
758
755
  ul.appendChild(addFeature(feature))
759
756
  })
760
757
  }
@@ -785,148 +782,72 @@ L.U.Map.include({
785
782
  L.bind(appendAll, this)()
786
783
  L.DomEvent.on(filter, 'input', appendAll, this)
787
784
  L.DomEvent.on(filter, 'input', resetLayers, this)
788
- const link = L.DomUtil.create('li', '')
789
- L.DomUtil.create('i', 'umap-icon-16 umap-caption', link)
790
- const label = L.DomUtil.create('span', '', link)
791
- label.textContent = label.title = L._('About')
792
- L.DomEvent.on(link, 'click', this.displayCaption, this)
793
- this.ui.openPanel({ data: { html: browserContainer }, actions: [link] })
785
+
786
+ this.ui.openPanel({
787
+ data: { html: browserContainer },
788
+ actions: [this._aboutLink()],
789
+ })
794
790
  },
795
791
 
796
- _openFilter: function () {
797
- const filterContainer = L.DomUtil.create('div', 'umap-filter-data'),
798
- title = L.DomUtil.add(
799
- 'h3',
800
- 'umap-filter-title',
801
- filterContainer,
802
- this.options.name
803
- ),
804
- propertiesContainer = L.DomUtil.create(
805
- 'div',
806
- 'umap-filter-properties',
807
- filterContainer
808
- ),
809
- advancedFilterKeys = this.getAdvancedFilterKeys()
792
+ _openFacet: function () {
793
+ const container = L.DomUtil.create('div', 'umap-facet-search'),
794
+ title = L.DomUtil.add('h3', 'umap-filter-title', container, L._('Facet search')),
795
+ keys = Object.keys(this.getFacetKeys())
810
796
 
811
- const advancedFiltersFull = {}
812
- let filtersAlreadyLoaded = true
813
- if (!this.getMap().options.advancedFilters) {
814
- this.getMap().options.advancedFilters = {}
815
- filtersAlreadyLoaded = false
816
- }
817
- advancedFilterKeys.forEach((property) => {
818
- advancedFiltersFull[property] = []
819
- if (!filtersAlreadyLoaded || !this.getMap().options.advancedFilters[property]) {
820
- this.getMap().options.advancedFilters[property] = []
821
- }
797
+ const knownValues = {}
798
+
799
+ keys.forEach((key) => {
800
+ knownValues[key] = []
801
+ if (!this.facets[key]) this.facets[key] = []
822
802
  })
803
+
823
804
  this.eachBrowsableDataLayer((datalayer) => {
824
805
  datalayer.eachFeature((feature) => {
825
- advancedFilterKeys.forEach((property) => {
826
- if (feature.properties[property]) {
827
- if (!advancedFiltersFull[property].includes(feature.properties[property])) {
828
- advancedFiltersFull[property].push(feature.properties[property])
829
- }
806
+ keys.forEach((key) => {
807
+ let value = feature.properties[key]
808
+ if (typeof value !== 'undefined' && !knownValues[key].includes(value)) {
809
+ knownValues[key].push(value)
830
810
  }
831
811
  })
832
812
  })
833
813
  })
834
814
 
835
- const addPropertyValue = function (property, value) {
836
- const property_li = L.DomUtil.create('li', ''),
837
- filter_check = L.DomUtil.create('input', '', property_li),
838
- filter_label = L.DomUtil.create('label', '', property_li)
839
- filter_check.type = 'checkbox'
840
- filter_check.id = `checkbox_${property}_${value}`
841
- filter_check.checked =
842
- this.getMap().options.advancedFilters[property] &&
843
- this.getMap().options.advancedFilters[property].includes(value)
844
- filter_check.setAttribute('data-property', property)
845
- filter_check.setAttribute('data-value', value)
846
- filter_label.htmlFor = `checkbox_${property}_${value}`
847
- filter_label.innerHTML = value
848
- L.DomEvent.on(
849
- filter_check,
850
- 'change',
851
- function (e) {
852
- const property = e.srcElement.dataset.property
853
- const value = e.srcElement.dataset.value
854
- if (e.srcElement.checked) {
855
- this.getMap().options.advancedFilters[property].push(value)
856
- } else {
857
- this.getMap().options.advancedFilters[property].splice(
858
- this.getMap().options.advancedFilters[property].indexOf(value),
859
- 1
860
- )
861
- }
862
- L.bind(filterFeatures, this)()
863
- },
864
- this
865
- )
866
- return property_li
867
- }
868
-
869
- const addProperty = function (property) {
870
- const container = L.DomUtil.create(
871
- 'div',
872
- 'property-container',
873
- propertiesContainer
874
- ),
875
- headline = L.DomUtil.add('h5', '', container, property)
876
- const ul = L.DomUtil.create('ul', '', container)
877
- const orderedValues = advancedFiltersFull[property]
878
- orderedValues.sort()
879
- orderedValues.forEach((value) => {
880
- ul.appendChild(L.bind(addPropertyValue, this)(property, value))
881
- })
882
- }
883
-
884
815
  const filterFeatures = function () {
885
- let noResults = true
816
+ let found = false
886
817
  this.eachBrowsableDataLayer((datalayer) => {
887
- datalayer.eachFeature(function (feature) {
888
- feature.properties.isVisible = true
889
- for (const [property, values] of Object.entries(
890
- this.map.options.advancedFilters
891
- )) {
892
- if (values.length > 0) {
893
- if (
894
- !feature.properties[property] ||
895
- !values.includes(feature.properties[property])
896
- ) {
897
- feature.properties.isVisible = false
898
- }
899
- }
900
- }
901
- if (feature.properties.isVisible) {
902
- noResults = false
903
- if (!this.isLoaded()) this.fetchData()
904
- this.map.addLayer(feature)
905
- this.fire('show')
906
- } else {
907
- this.map.removeLayer(feature)
908
- this.fire('hide')
909
- }
910
- })
818
+ datalayer.resetLayer(true)
819
+ if (datalayer.hasDataVisible()) found = true
911
820
  })
912
- if (noResults) {
913
- this.help.show('advancedFiltersNoResults')
914
- } else {
915
- this.help.hide()
916
- }
821
+ // TODO: display a results counter in the panel instead.
822
+ if (!found)
823
+ this.ui.alert({ content: L._('No results for these facets'), level: 'info' })
917
824
  }
918
825
 
919
- propertiesContainer.innerHTML = ''
920
- advancedFilterKeys.forEach((property) => {
921
- L.bind(addProperty, this)(property)
826
+ const fields = keys.map((current) => [
827
+ `facets.${current}`,
828
+ {
829
+ handler: 'FacetSearch',
830
+ choices: knownValues[current],
831
+ label: this.getFacetKeys()[current],
832
+ },
833
+ ])
834
+ const builder = new L.U.FormBuilder(this, fields, {
835
+ makeDirty: false,
836
+ callback: filterFeatures,
837
+ callbackContext: this,
922
838
  })
839
+ container.appendChild(builder.build())
840
+
841
+ this.ui.openPanel({ data: { html: container }, actions: [this._aboutLink()] })
842
+ },
923
843
 
844
+ _aboutLink: function () {
924
845
  const link = L.DomUtil.create('li', '')
925
846
  L.DomUtil.create('i', 'umap-icon-16 umap-caption', link)
926
847
  const label = L.DomUtil.create('span', '', link)
927
848
  label.textContent = label.title = L._('About')
928
849
  L.DomEvent.on(link, 'click', this.displayCaption, this)
929
- this.ui.openPanel({ data: { html: filterContainer }, actions: [link] })
850
+ return link
930
851
  },
931
852
 
932
853
  displayCaption: function () {
@@ -1008,11 +929,11 @@ L.U.Map.include({
1008
929
  labelBrowser.textContent = labelBrowser.title = L._('Browse data')
1009
930
  L.DomEvent.on(browser, 'click', this.openBrowser, this)
1010
931
  const actions = [browser]
1011
- if (this.options.advancedFilterKey) {
932
+ if (this.options.facetKey) {
1012
933
  const filter = L.DomUtil.create('li', '')
1013
934
  L.DomUtil.create('i', 'umap-icon-16 umap-add', filter)
1014
935
  const labelFilter = L.DomUtil.create('span', '', filter)
1015
- labelFilter.textContent = labelFilter.title = L._('Select data')
936
+ labelFilter.textContent = labelFilter.title = L._('Facet search')
1016
937
  L.DomEvent.on(filter, 'click', this.openFilter, this)
1017
938
  actions.push(filter)
1018
939
  }
@@ -1032,7 +953,7 @@ L.U.Map.include({
1032
953
  return togpx(map.toGeoJSON())
1033
954
  },
1034
955
  ext: '.gpx',
1035
- filetype: 'application/xml',
956
+ filetype: 'application/gpx+xml',
1036
957
  },
1037
958
  kml: {
1038
959
  formatter: function (map) {
@@ -1052,6 +973,76 @@ L.U.Map.include({
1052
973
  },
1053
974
  },
1054
975
 
976
+ renderEditToolbar: function () {
977
+ const container = L.DomUtil.create(
978
+ 'div',
979
+ 'umap-main-edit-toolbox with-transition dark',
980
+ this._controlContainer
981
+ ),
982
+ logo = L.DomUtil.add('a', 'logo', container),
983
+ name = L.DomUtil.create('a', 'map-name', container),
984
+ share_status = L.DomUtil.create('a', 'share-status', container),
985
+ update = () => {
986
+ name.textContent = this.getDisplayName()
987
+ share_status.textContent = L._('Visibility: {status}', {
988
+ status: this.permissions.getShareStatusDisplay(),
989
+ })
990
+ }
991
+ update()
992
+ name.href = '#'
993
+ share_status.href = '#'
994
+ logo.href = '/'
995
+ if (this.options.user) {
996
+ const userLabel = L.DomUtil.add(
997
+ 'a',
998
+ 'umap-user',
999
+ container,
1000
+ L._(`My maps ({username})`, { username: this.options.user.name })
1001
+ )
1002
+ userLabel.href = this.options.user.url
1003
+ }
1004
+ this.help.button(container, 'edit')
1005
+ L.DomEvent.on(name, 'click', this.edit, this)
1006
+ L.DomEvent.on(share_status, 'click', this.permissions.edit, this.permissions)
1007
+ this.on('postsync', L.bind(update, this))
1008
+ const save = L.DomUtil.create('a', 'leaflet-control-edit-save button', container)
1009
+ save.href = '#'
1010
+ save.title = `${L._('Save current edits')} (Ctrl+S)`
1011
+ save.textContent = L._('Save')
1012
+ const cancel = L.DomUtil.create('a', 'leaflet-control-edit-cancel', container)
1013
+ cancel.href = '#'
1014
+ cancel.title = `${L._('Cancel edits')} (Ctrl+Z)`
1015
+ cancel.textContent = L._('Cancel all')
1016
+ const disable = L.DomUtil.create('a', 'leaflet-control-edit-disable', container)
1017
+ disable.href = '#'
1018
+ disable.textContent = L._('Disable editing')
1019
+ disable.title = `${disable.textContent} (Ctrl+E)`
1020
+
1021
+ L.DomEvent.addListener(disable, 'click', L.DomEvent.stop).addListener(
1022
+ disable,
1023
+ 'click',
1024
+ function (e) {
1025
+ this.disableEdit(e)
1026
+ this.ui.closePanel()
1027
+ },
1028
+ this
1029
+ )
1030
+
1031
+ L.DomEvent.addListener(save, 'click', L.DomEvent.stop).addListener(
1032
+ save,
1033
+ 'click',
1034
+ this.save,
1035
+ this
1036
+ )
1037
+
1038
+ L.DomEvent.addListener(cancel, 'click', L.DomEvent.stop).addListener(
1039
+ cancel,
1040
+ 'click',
1041
+ this.askForReset,
1042
+ this
1043
+ )
1044
+ },
1045
+
1055
1046
  renderShareBox: function () {
1056
1047
  const container = L.DomUtil.create('div', 'umap-share')
1057
1048
  const embedTitle = L.DomUtil.add('h4', '', container, L._('Embed the map'))
@@ -1216,7 +1207,6 @@ L.U.TileLayerControl = L.Control.extend({
1216
1207
  'click',
1217
1208
  function () {
1218
1209
  this.map.selectTileLayer(tilelayer)
1219
- this.map.ui.closePanel()
1220
1210
  if (options && options.callback) options.callback(tilelayer)
1221
1211
  },
1222
1212
  this
@@ -253,6 +253,10 @@ L.Util.buildQueryString = (params) => {
253
253
 
254
254
  L.Util.getBaseUrl = () => `//${window.location.host}${window.location.pathname}`
255
255
 
256
+ L.Util.hasVar = (value) => {
257
+ return typeof value === 'string' && value.indexOf('{') != -1
258
+ }
259
+
256
260
  L.DomUtil.add = (tagName, className, container, content) => {
257
261
  const el = L.DomUtil.create(tagName, className, container)
258
262
  if (content) {
@@ -548,7 +552,9 @@ L.U.Help = L.Class.extend({
548
552
  'A comma separated list of numbers that defines the stroke dash pattern. Ex.: "5, 10, 15".'
549
553
  ),
550
554
  zoomTo: L._('Zoom level for automatic zooms'),
551
- labelKey: L._('The name of the property to use as feature label (eg.: "nom"). You can also use properties inside brackets to use more than one or mix with static content (eg.: "{name} in {place}")'),
555
+ labelKey: L._(
556
+ 'The name of the property to use as feature label (eg.: "nom"). You can also use properties inside brackets to use more than one or mix with static content (eg.: "{name} in {place}")'
557
+ ),
552
558
  stroke: L._('Whether to display or not polygons paths.'),
553
559
  fill: L._('Whether to fill polygons with color.'),
554
560
  fillColor: L._('Optional. Same as color if not set.'),
@@ -557,13 +563,14 @@ L.U.Help = L.Class.extend({
557
563
  permanentCredit: L._(
558
564
  'Will be permanently visible in the bottom left corner of the map'
559
565
  ),
560
- sortKey: L._('Comma separated list of properties to use for sorting features. To reverse the sort, put a minus sign (-) before. Eg. mykey,-otherkey.'),
566
+ sortKey: L._(
567
+ 'Comma separated list of properties to use for sorting features. To reverse the sort, put a minus sign (-) before. Eg. mykey,-otherkey.'
568
+ ),
561
569
  slugKey: L._('The name of the property to use as feature unique identifier.'),
562
570
  filterKey: L._('Comma separated list of properties to use when filtering features'),
563
- advancedFilterKey: L._(
564
- 'Comma separated list of properties to use for checkbox filtering'
571
+ facetKey: L._(
572
+ 'Comma separated list of properties to use for facet search (eg.: mykey,otherkey). To control label, add it after a | (eg.: mykey|My Key,otherkey|Other Key)'
565
573
  ),
566
- advancedFiltersNoResults: L._('No results for these filters'),
567
574
  interactive: L._('If false, the polygon will act as a part of the underlying map.'),
568
575
  outlink: L._('Define link to open in a new window on polygon click.'),
569
576
  dynamicRemoteData: L._('Fetch data each time map view changes.'),
@@ -86,7 +86,13 @@ L.U.FeatureMixin = {
86
86
 
87
87
  edit: function (e) {
88
88
  if (!this.map.editEnabled || this.isReadOnly()) return
89
- const container = L.DomUtil.create('div', 'umap-datalayer-container')
89
+ const container = L.DomUtil.create('div', 'umap-feature-container')
90
+ L.DomUtil.add(
91
+ 'h3',
92
+ `umap-feature-properties ${this.getClassName()}`,
93
+ container,
94
+ L._('Feature properties')
95
+ )
90
96
 
91
97
  let builder = new L.U.FormBuilder(this, ['datalayer'], {
92
98
  callback: function () {
@@ -184,7 +190,7 @@ L.U.FeatureMixin = {
184
190
  if (fallback === undefined) fallback = this.datalayer.options.name
185
191
  const key = this.getOption('labelKey') || 'name'
186
192
  // Variables mode.
187
- if (key.indexOf('{') != -1)
193
+ if (L.Util.hasVar(key))
188
194
  return L.Util.greedyTemplate(key, this.extendedProperties())
189
195
  // Simple mode.
190
196
  return this.properties[key] || this.properties.title || fallback
@@ -276,11 +282,9 @@ L.U.FeatureMixin = {
276
282
  getDynamicOption: function (option, fallback) {
277
283
  let value = this.getOption(option, fallback)
278
284
  // There is a variable inside.
279
- if (typeof value === 'string' && value.indexOf('{') != -1) {
280
- value = L.Util.greedyTemplate(value, this.properties)
281
- // We've not been able to replace the variable, let's reset
282
- // so we can set a decent default at next step.
283
- if (value.indexOf('{') != -1) value = undefined
285
+ if (L.Util.hasVar(value)) {
286
+ value = L.Util.greedyTemplate(value, this.properties, true)
287
+ if (L.Util.hasVar(value)) value = this.map.getDefaultOption(option)
284
288
  }
285
289
  return value
286
290
  },
@@ -444,6 +448,7 @@ L.U.FeatureMixin = {
444
448
  },
445
449
 
446
450
  resetTooltip: function () {
451
+ if (!this.hasGeom()) return
447
452
  const displayName = this.getDisplayName(null)
448
453
  let showLabel = this.getOption('showLabel')
449
454
  const oldLabelHover = this.getOption('labelHover')
@@ -469,6 +474,17 @@ L.U.FeatureMixin = {
469
474
  return false
470
475
  },
471
476
 
477
+ matchFacets: function () {
478
+ const facets = this.map.facets
479
+ for (const [property, expected] of Object.entries(facets)) {
480
+ if (expected.length) {
481
+ let value = this.properties[property]
482
+ if (!value || !expected.includes(value)) return false
483
+ }
484
+ }
485
+ return true
486
+ },
487
+
472
488
  onVertexRawClick: function (e) {
473
489
  new L.Toolbar.Popup(e.latlng, {
474
490
  className: 'leaflet-inplace-toolbar',
@@ -494,15 +510,17 @@ L.U.FeatureMixin = {
494
510
  extendedProperties: function () {
495
511
  // Include context properties
496
512
  properties = this.map.getGeoContext()
497
- center = this.getCenter()
498
- properties.lat = center.lat
499
- properties.lon = center.lng
500
- properties.lng = center.lng
501
- properties.rank = this.getRank() + 1
502
513
  if (L.locale) properties.locale = L.locale
503
514
  if (L.lang) properties.lang = L.lang
504
- if (typeof this.getMeasure !== 'undefined') {
505
- properties.measure = this.getMeasure()
515
+ properties.rank = this.getRank() + 1
516
+ if (this.hasGeom()) {
517
+ center = this.getCenter()
518
+ properties.lat = center.lat
519
+ properties.lon = center.lng
520
+ properties.lng = center.lng
521
+ if (typeof this.getMeasure !== 'undefined') {
522
+ properties.measure = this.getMeasure()
523
+ }
506
524
  }
507
525
  return L.extend(properties, this.properties)
508
526
  },
@@ -535,6 +553,10 @@ L.U.Marker = L.Marker.extend({
535
553
  this._popupHandlersAdded = true // prevent Leaflet from binding event on bindPopup
536
554
  },
537
555
 
556
+ hasGeom: function () {
557
+ return !!this._latlng
558
+ },
559
+
538
560
  _onMouseOut: function () {
539
561
  if (
540
562
  this.dragging &&
@@ -679,6 +701,10 @@ L.U.Marker = L.Marker.extend({
679
701
  })
680
702
 
681
703
  L.U.PathMixin = {
704
+ hasGeom: function () {
705
+ return !this.isEmpty()
706
+ },
707
+
682
708
  connectToDataLayer: function (datalayer) {
683
709
  L.U.FeatureMixin.connectToDataLayer.call(this, datalayer)
684
710
  // We keep markers on their own layer on top of the paths.