umap-project 2.0.4__py3-none-any.whl → 2.1.1__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 (106) hide show
  1. umap/__init__.py +1 -1
  2. umap/fields.py +3 -1
  3. umap/locale/br/LC_MESSAGES/django.po +76 -71
  4. umap/locale/en/LC_MESSAGES/django.po +41 -41
  5. umap/locale/hu/LC_MESSAGES/django.po +42 -42
  6. umap/locale/it/LC_MESSAGES/django.po +64 -58
  7. umap/locale/ms/LC_MESSAGES/django.po +62 -57
  8. umap/migrations/0018_datalayer_uuid.py +62 -0
  9. umap/migrations/0019_migrate_internal_remote_datalayers.py +52 -0
  10. umap/models.py +20 -3
  11. umap/settings/base.py +1 -0
  12. umap/settings/dev.py +1 -0
  13. umap/static/umap/js/modules/browser.js +2 -2
  14. umap/static/umap/js/modules/global.js +14 -4
  15. umap/static/umap/js/modules/i18n.js +35 -0
  16. umap/static/umap/js/modules/leaflet-configure.js +7 -0
  17. umap/static/umap/js/modules/schema.js +388 -0
  18. umap/static/umap/js/modules/urls.js +17 -2
  19. umap/static/umap/js/modules/utils.js +24 -0
  20. umap/static/umap/js/umap.controls.js +9 -10
  21. umap/static/umap/js/umap.core.js +5 -5
  22. umap/static/umap/js/umap.features.js +23 -9
  23. umap/static/umap/js/umap.forms.js +49 -299
  24. umap/static/umap/js/umap.icon.js +2 -2
  25. umap/static/umap/js/umap.js +26 -129
  26. umap/static/umap/js/umap.layer.js +9 -9
  27. umap/static/umap/js/umap.popup.js +3 -0
  28. umap/static/umap/js/umap.share.js +1 -1
  29. umap/static/umap/locale/am_ET.json +229 -225
  30. umap/static/umap/locale/ar.json +229 -225
  31. umap/static/umap/locale/ast.json +229 -225
  32. umap/static/umap/locale/bg.json +229 -225
  33. umap/static/umap/locale/br.json +237 -233
  34. umap/static/umap/locale/ca.json +229 -225
  35. umap/static/umap/locale/cs_CZ.json +229 -225
  36. umap/static/umap/locale/da.json +229 -225
  37. umap/static/umap/locale/de.json +229 -225
  38. umap/static/umap/locale/el.json +229 -225
  39. umap/static/umap/locale/en.json +230 -233
  40. umap/static/umap/locale/en_US.json +229 -225
  41. umap/static/umap/locale/es.json +229 -225
  42. umap/static/umap/locale/et.json +229 -225
  43. umap/static/umap/locale/eu.json +226 -198
  44. umap/static/umap/locale/fa_IR.json +229 -225
  45. umap/static/umap/locale/fi.json +229 -225
  46. umap/static/umap/locale/fr.json +229 -232
  47. umap/static/umap/locale/gl.json +229 -225
  48. umap/static/umap/locale/he.json +229 -225
  49. umap/static/umap/locale/hr.json +229 -225
  50. umap/static/umap/locale/hu.json +229 -232
  51. umap/static/umap/locale/id.json +229 -225
  52. umap/static/umap/locale/is.json +229 -225
  53. umap/static/umap/locale/it.json +229 -232
  54. umap/static/umap/locale/ja.json +229 -225
  55. umap/static/umap/locale/ko.json +229 -225
  56. umap/static/umap/locale/lt.json +229 -225
  57. umap/static/umap/locale/ms.json +229 -232
  58. umap/static/umap/locale/nl.json +232 -228
  59. umap/static/umap/locale/no.json +229 -225
  60. umap/static/umap/locale/pl.json +229 -225
  61. umap/static/umap/locale/pl_PL.json +229 -225
  62. umap/static/umap/locale/pt.json +229 -225
  63. umap/static/umap/locale/pt_BR.json +229 -225
  64. umap/static/umap/locale/pt_PT.json +229 -225
  65. umap/static/umap/locale/ro.json +229 -225
  66. umap/static/umap/locale/ru.json +229 -225
  67. umap/static/umap/locale/sk_SK.json +229 -225
  68. umap/static/umap/locale/sl.json +229 -225
  69. umap/static/umap/locale/sr.json +229 -225
  70. umap/static/umap/locale/sv.json +229 -225
  71. umap/static/umap/locale/th_TH.json +229 -225
  72. umap/static/umap/locale/tr.json +229 -225
  73. umap/static/umap/locale/uk_UA.json +229 -225
  74. umap/static/umap/locale/vi.json +229 -225
  75. umap/static/umap/locale/vi_VN.json +229 -225
  76. umap/static/umap/locale/zh.json +229 -225
  77. umap/static/umap/locale/zh_CN.json +229 -225
  78. umap/static/umap/locale/zh_TW.Big5.json +229 -225
  79. umap/static/umap/locale/zh_TW.json +229 -232
  80. umap/static/umap/test/index.html +0 -2
  81. umap/static/umap/{test → unittests}/URLs.js +5 -0
  82. umap/static/umap/vendors/leaflet/leaflet-src.esm.js +7064 -7064
  83. umap/static/umap/vendors/photon/leaflet.photon.js +3 -0
  84. umap/templates/umap/js.html +8 -6
  85. umap/templatetags/umap_tags.py +3 -2
  86. umap/tests/integration/test_browser.py +40 -0
  87. umap/tests/integration/test_collaborative_editing.py +72 -3
  88. umap/tests/integration/test_export_map.py +226 -9
  89. umap/tests/integration/test_features_id_generation.py +51 -0
  90. umap/tests/integration/test_owned_map.py +14 -1
  91. umap/tests/integration/test_statics.py +3 -3
  92. umap/tests/integration/test_tilelayer.py +3 -3
  93. umap/tests/settings.py +3 -3
  94. umap/tests/test_datalayer_views.py +77 -20
  95. umap/tests/test_map_views.py +20 -0
  96. umap/tests/test_merge_features.py +25 -5
  97. umap/urls.py +12 -12
  98. umap/utils.py +7 -0
  99. umap/views.py +58 -49
  100. umap/wsgi.py +1 -0
  101. {umap_project-2.0.4.dist-info → umap_project-2.1.1.dist-info}/METADATA +9 -9
  102. {umap_project-2.0.4.dist-info → umap_project-2.1.1.dist-info}/RECORD +105 -99
  103. umap/static/umap/test/Map.Export.js +0 -106
  104. {umap_project-2.0.4.dist-info → umap_project-2.1.1.dist-info}/WHEEL +0 -0
  105. {umap_project-2.0.4.dist-info → umap_project-2.1.1.dist-info}/entry_points.txt +0 -0
  106. {umap_project-2.0.4.dist-info → umap_project-2.1.1.dist-info}/licenses/LICENSE +0 -0
@@ -340,15 +340,6 @@ L.FormBuilder.TextColorPicker = L.FormBuilder.ColorPicker.extend({
340
340
  ],
341
341
  })
342
342
 
343
- L.FormBuilder.IconClassSwitcher = L.FormBuilder.Select.extend({
344
- selectOptions: [
345
- ['Default', L._('Default')],
346
- ['Circle', L._('Circle')],
347
- ['Drop', L._('Drop')],
348
- ['Ball', L._('Ball')],
349
- ],
350
- })
351
-
352
343
  L.FormBuilder.ProxyTTLSelect = L.FormBuilder.Select.extend({
353
344
  selectOptions: [
354
345
  [undefined, L._('No cache')],
@@ -358,24 +349,6 @@ L.FormBuilder.ProxyTTLSelect = L.FormBuilder.Select.extend({
358
349
  ],
359
350
  })
360
351
 
361
- L.FormBuilder.PopupShape = L.FormBuilder.Select.extend({
362
- selectOptions: [
363
- ['Default', L._('Popup')],
364
- ['Large', L._('Popup (large)')],
365
- ['Panel', L._('Side panel')],
366
- ],
367
- })
368
-
369
- L.FormBuilder.PopupContent = L.FormBuilder.Select.extend({
370
- selectOptions: [
371
- ['Default', L._('Default')],
372
- ['Table', L._('Table')],
373
- ['GeoRSSImage', L._('GeoRSS (title + image)')],
374
- ['GeoRSSLink', L._('GeoRSS (only link)')],
375
- ['OSM', L._('OpenStreetMap')],
376
- ],
377
- })
378
-
379
352
  L.FormBuilder.LayerTypeChooser = L.FormBuilder.Select.extend({
380
353
  getOptions: function () {
381
354
  const layer_classes = [
@@ -427,24 +400,6 @@ L.FormBuilder.DataLayerSwitcher = L.FormBuilder.Select.extend({
427
400
  },
428
401
  })
429
402
 
430
- L.FormBuilder.DefaultView = L.FormBuilder.Select.extend({
431
- selectOptions: [
432
- ['center', L._('Saved center and zoom')],
433
- ['data', L._('Fit all data')],
434
- ['latest', L._('Latest feature')],
435
- ['locate', L._('User location')],
436
- ],
437
- })
438
-
439
- L.FormBuilder.OnLoadPanel = L.FormBuilder.Select.extend({
440
- selectOptions: [
441
- ['none', L._('None')],
442
- ['caption', L._('Caption')],
443
- ['databrowser', L._('Data browser')],
444
- ['facet', L._('Facet search')],
445
- ],
446
- })
447
-
448
403
  L.FormBuilder.DataFormat = L.FormBuilder.Select.extend({
449
404
  selectOptions: [
450
405
  [undefined, L._('Choose the data format')],
@@ -457,16 +412,6 @@ L.FormBuilder.DataFormat = L.FormBuilder.Select.extend({
457
412
  ],
458
413
  })
459
414
 
460
- L.FormBuilder.LabelDirection = L.FormBuilder.Select.extend({
461
- selectOptions: [
462
- ['auto', L._('Automatic')],
463
- ['left', L._('On the left')],
464
- ['right', L._('On the right')],
465
- ['top', L._('On the top')],
466
- ['bottom', L._('On the bottom')],
467
- ],
468
- })
469
-
470
415
  L.FormBuilder.LicenceChooser = L.FormBuilder.Select.extend({
471
416
  getOptions: function () {
472
417
  const licences = []
@@ -708,7 +653,7 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
708
653
  },
709
654
 
710
655
  isDefault: function () {
711
- return !this.value() || this.value() === U.DEFAULT_ICON_URL
656
+ return !this.value() || this.value() === U.SCHEMA.iconUrl.default
712
657
  },
713
658
 
714
659
  addGrid: function (onSearch) {
@@ -905,7 +850,7 @@ L.FormBuilder.TernaryChoices = L.FormBuilder.MultiChoice.extend({
905
850
  },
906
851
  })
907
852
 
908
- L.FormBuilder.ControlChoice = L.FormBuilder.TernaryChoices.extend({
853
+ L.FormBuilder.NullableChoices = L.FormBuilder.TernaryChoices.extend({
909
854
  choices: [
910
855
  [true, L._('always')],
911
856
  [false, L._('never')],
@@ -913,17 +858,7 @@ L.FormBuilder.ControlChoice = L.FormBuilder.TernaryChoices.extend({
913
858
  ],
914
859
  })
915
860
 
916
- L.FormBuilder.LabelChoice = L.FormBuilder.TernaryChoices.extend({
917
- default: false,
918
-
919
- choices: [
920
- [true, L._('always')],
921
- [false, L._('never')],
922
- ['null', L._('on hover')],
923
- ],
924
- })
925
-
926
- L.FormBuilder.DataLayersControl = L.FormBuilder.ControlChoice.extend({
861
+ L.FormBuilder.DataLayersControl = L.FormBuilder.TernaryChoices.extend({
927
862
  choices: [
928
863
  [true, L._('collapsed')],
929
864
  ['expanded', L._('expanded')],
@@ -934,21 +869,11 @@ L.FormBuilder.DataLayersControl = L.FormBuilder.ControlChoice.extend({
934
869
  toJS: function () {
935
870
  let value = this.value()
936
871
  if (value !== 'expanded')
937
- value = L.FormBuilder.ControlChoice.prototype.toJS.call(this)
872
+ value = L.FormBuilder.TernaryChoices.prototype.toJS.call(this)
938
873
  return value
939
874
  },
940
875
  })
941
876
 
942
- L.FormBuilder.OutlinkTarget = L.FormBuilder.MultiChoice.extend({
943
- default: 'blank',
944
-
945
- choices: [
946
- ['blank', L._('new window')],
947
- ['self', L._('iframe')],
948
- ['parent', L._('parent window')],
949
- ],
950
- })
951
-
952
877
  L.FormBuilder.Range = L.FormBuilder.FloatInput.extend({
953
878
  type: function () {
954
879
  return 'range'
@@ -1052,230 +977,55 @@ U.FormBuilder = L.FormBuilder.extend({
1052
977
  className: 'umap-form',
1053
978
  },
1054
979
 
1055
- defaultOptions: {
1056
- name: { label: L._('name') },
1057
- description: {
1058
- label: L._('description'),
1059
- handler: 'Textarea',
1060
- helpEntries: 'textFormatting',
1061
- },
1062
- color: {
1063
- handler: 'ColorPicker',
1064
- label: L._('color'),
1065
- helpEntries: 'colorValue',
1066
- inheritable: true,
1067
- },
1068
- iconOpacity: {
1069
- handler: 'Range',
1070
- min: 0.1,
1071
- max: 1,
1072
- step: 0.1,
1073
- label: L._('icon opacity'),
1074
- inheritable: true,
1075
- },
1076
- opacity: {
1077
- handler: 'Range',
1078
- min: 0.1,
1079
- max: 1,
1080
- step: 0.1,
1081
- label: L._('opacity'),
1082
- inheritable: true,
1083
- },
1084
- stroke: {
1085
- handler: 'Switch',
1086
- label: L._('stroke'),
1087
- helpEntries: 'stroke',
1088
- inheritable: true,
1089
- },
1090
- weight: {
1091
- handler: 'Range',
1092
- min: 1,
1093
- max: 20,
1094
- step: 1,
1095
- label: L._('weight'),
1096
- inheritable: true,
1097
- },
1098
- fill: {
1099
- handler: 'Switch',
1100
- label: L._('fill'),
1101
- helpEntries: 'fill',
1102
- inheritable: true,
1103
- },
1104
- fillColor: {
1105
- handler: 'ColorPicker',
1106
- label: L._('fill color'),
1107
- helpEntries: 'fillColor',
1108
- inheritable: true,
1109
- },
1110
- fillOpacity: {
1111
- handler: 'Range',
1112
- min: 0.1,
1113
- max: 1,
1114
- step: 0.1,
1115
- label: L._('fill opacity'),
1116
- inheritable: true,
1117
- },
1118
- smoothFactor: {
1119
- handler: 'Range',
1120
- min: 0,
1121
- max: 10,
1122
- step: 0.5,
1123
- label: L._('Simplify'),
1124
- helpEntries: 'smoothFactor',
1125
- inheritable: true,
1126
- },
1127
- dashArray: {
1128
- label: L._('dash array'),
1129
- helpEntries: 'dashArray',
1130
- inheritable: true,
1131
- },
1132
- iconClass: {
1133
- handler: 'IconClassSwitcher',
1134
- label: L._('Icon shape'),
1135
- inheritable: true,
1136
- },
1137
- iconUrl: {
1138
- handler: 'IconUrl',
1139
- label: L._('Icon symbol'),
1140
- inheritable: true,
1141
- helpText: U.Help.formatIconSymbol,
1142
- },
1143
- popupShape: { handler: 'PopupShape', label: L._('Popup shape'), inheritable: true },
1144
- popupTemplate: {
1145
- handler: 'PopupContent',
1146
- label: L._('Popup content style'),
1147
- inheritable: true,
1148
- },
1149
- popupContentTemplate: {
1150
- label: L._('Popup content template'),
1151
- handler: 'Textarea',
1152
- helpEntries: ['dynamicProperties', 'textFormatting'],
1153
- placeholder: '# {name}',
1154
- inheritable: true,
1155
- },
1156
- datalayer: {
1157
- handler: 'DataLayerSwitcher',
1158
- label: L._('Choose the layer of the feature'),
1159
- },
1160
- moreControl: {
1161
- handler: 'Switch',
1162
- label: L._('Do you want to display the «more» control?'),
1163
- },
1164
- scrollWheelZoom: { handler: 'Switch', label: L._('Allow scroll wheel zoom?') },
1165
- miniMap: { handler: 'Switch', label: L._('Do you want to display a minimap?') },
1166
- scaleControl: {
1167
- handler: 'Switch',
1168
- label: L._('Do you want to display the scale control?'),
1169
- },
1170
- onLoadPanel: {
1171
- handler: 'OnLoadPanel',
1172
- label: L._('Do you want to display a panel on load?'),
1173
- },
1174
- defaultView: {
1175
- handler: 'DefaultView',
1176
- label: L._('Default view'),
1177
- },
1178
- displayPopupFooter: {
1179
- handler: 'Switch',
1180
- label: L._('Do you want to display popup footer?'),
1181
- },
1182
- captionBar: {
1183
- handler: 'Switch',
1184
- label: L._('Do you want to display a caption bar?'),
1185
- },
1186
- captionMenus: {
1187
- handler: 'Switch',
1188
- label: L._('Do you want to display caption menus?'),
1189
- },
1190
- zoomTo: {
1191
- handler: 'IntInput',
1192
- placeholder: L._('Inherit'),
1193
- helpEntries: 'zoomTo',
1194
- label: L._('Default zoom level'),
1195
- inheritable: true,
1196
- },
1197
- showLabel: {
1198
- handler: 'LabelChoice',
1199
- label: L._('Display label'),
1200
- inheritable: true,
1201
- },
1202
- labelDirection: {
1203
- handler: 'LabelDirection',
1204
- label: L._('Label direction'),
1205
- inheritable: true,
1206
- },
1207
- labelInteractive: {
1208
- handler: 'Switch',
1209
- label: L._('Labels are clickable'),
1210
- inheritable: true,
1211
- },
1212
- outlink: {
1213
- label: L._('Link to…'),
1214
- helpEntries: 'outlink',
1215
- placeholder: 'http://...',
1216
- inheritable: true,
1217
- },
1218
- outlinkTarget: {
1219
- handler: 'OutlinkTarget',
1220
- label: L._('Open link in…'),
1221
- inheritable: true,
1222
- },
1223
- labelKey: {
1224
- helpEntries: 'labelKey',
1225
- placeholder: L._('Default: name'),
1226
- label: L._('Label key'),
1227
- inheritable: true,
1228
- },
1229
- zoomControl: { handler: 'ControlChoice', label: L._('Display the zoom control') },
1230
- searchControl: {
1231
- handler: 'ControlChoice',
1232
- label: L._('Display the search control'),
1233
- },
1234
- fullscreenControl: {
1235
- handler: 'ControlChoice',
1236
- label: L._('Display the fullscreen control'),
1237
- },
1238
- embedControl: { handler: 'ControlChoice', label: L._('Display the embed control') },
1239
- locateControl: {
1240
- handler: 'ControlChoice',
1241
- label: L._('Display the locate control'),
1242
- },
1243
- measureControl: {
1244
- handler: 'ControlChoice',
1245
- label: L._('Display the measure control'),
1246
- },
1247
- tilelayersControl: {
1248
- handler: 'ControlChoice',
1249
- label: L._('Display the tile layers control'),
1250
- },
1251
- editinosmControl: {
1252
- handler: 'ControlChoice',
1253
- label: L._('Display the control to open OpenStreetMap editor'),
1254
- },
1255
- datalayersControl: {
1256
- handler: 'DataLayersControl',
1257
- label: L._('Display the data layers control'),
1258
- },
1259
- starControl: {
1260
- handler: 'ControlChoice',
1261
- label: L._('Display the star map button'),
1262
- },
1263
- fromZoom: {
1264
- handler: 'IntInput',
1265
- label: L._('From zoom'),
1266
- helpText: L._('Optional.'),
1267
- },
1268
- toZoom: { handler: 'IntInput', label: L._('To zoom'), helpText: L._('Optional.') },
1269
- interactive: {
1270
- handler: 'Switch',
1271
- label: L._('Allow interactions'),
1272
- helpEntries: 'interactive',
1273
- inheritable: true,
1274
- },
980
+ computeDefaultOptions: function () {
981
+ for (let [key, schema] of Object.entries(U.SCHEMA)) {
982
+ if (schema.type === Boolean) {
983
+ if (schema.nullable) schema.handler = 'NullableChoices'
984
+ else schema.handler = 'Switch'
985
+ } else if (schema.type === 'Text') {
986
+ schema.handler = 'Textarea'
987
+ } else if (schema.type === Number) {
988
+ if (schema.step) schema.handler = 'Range'
989
+ else schema.handler = 'IntInput'
990
+ } else if (schema.choices) {
991
+ const text_length = schema.choices.reduce(
992
+ (acc, [value, label]) => acc + label.length,
993
+ 0
994
+ )
995
+ // Try to be smart and use MultiChoice only
996
+ // for choices where labels are shorts…
997
+ if (text_length < 40) {
998
+ schema.handler = 'MultiChoice'
999
+ } else {
1000
+ schema.handler = 'Select'
1001
+ schema.selectOptions = schema.choices
1002
+ }
1003
+ } else {
1004
+ switch (key) {
1005
+ case 'color':
1006
+ case 'fillColor':
1007
+ schema.handler = 'ColorPicker'
1008
+ break
1009
+ case 'iconUrl':
1010
+ schema.handler = 'IconUrl'
1011
+ break
1012
+ case 'datalayersControl':
1013
+ schema.handler = 'DataLayersControl'
1014
+ break
1015
+ case 'licence':
1016
+ schema.handler = 'LicenceChooser'
1017
+ break
1018
+ }
1019
+ }
1020
+ // FormBuilder use this key for the input type itself
1021
+ delete schema.type
1022
+ this.defaultOptions[key] = schema
1023
+ }
1275
1024
  },
1276
1025
 
1277
1026
  initialize: function (obj, fields, options) {
1278
1027
  this.map = obj.map || obj.getMap()
1028
+ this.computeDefaultOptions()
1279
1029
  L.FormBuilder.prototype.initialize.call(this, obj, fields, options)
1280
1030
  this.on('finish', this.finish)
1281
1031
  },
@@ -19,7 +19,7 @@ U.Icon = L.DivIcon.extend({
19
19
 
20
20
  _setRecent: function (url) {
21
21
  if (L.Util.hasVar(url)) return
22
- if (url === U.DEFAULT_ICON_URL) return
22
+ if (url === U.SCHEMA.iconUrl.default) return
23
23
  if (U.Icon.RECENT.indexOf(url) === -1) {
24
24
  U.Icon.RECENT.push(url)
25
25
  }
@@ -236,7 +236,7 @@ U.Icon.setIconContrast = function (icon, parent, src, bgcolor) {
236
236
  if (L.DomUtil.contrastedColor(parent, bgcolor)) {
237
237
  // Decide whether to switch svg to white or not, but do it
238
238
  // only for internal SVG, as invert could do weird things
239
- if (L.Util.isPath(src) && src.endsWith('.svg') && src !== U.DEFAULT_ICON_URL) {
239
+ if (L.Util.isPath(src) && src.endsWith('.svg') && src !== U.SCHEMA.iconUrl.default) {
240
240
  // Must be called after icon container is added to the DOM
241
241
  // An image
242
242
  icon.style.filter = 'invert(1)'
@@ -2,33 +2,12 @@ L.Map.mergeOptions({
2
2
  overlay: null,
3
3
  datalayers: [],
4
4
  hash: true,
5
- default_color: 'DarkBlue',
6
- default_smoothFactor: 1.0,
7
- default_opacity: 0.5,
8
- default_fillOpacity: 0.3,
9
- default_stroke: true,
10
- default_fill: true,
11
- default_weight: 3,
12
- default_iconOpacity: 1,
13
- default_iconClass: 'Default',
14
- default_popupContentTemplate: '# {name}\n{description}',
15
- default_interactive: true,
16
- default_labelDirection: 'auto',
17
5
  maxZoomLimit: 24,
18
6
  attributionControl: false,
19
7
  editMode: 'advanced',
20
- embedControl: true,
21
- zoomControl: true,
22
- datalayersControl: true,
23
- searchControl: true,
24
- editInOSMControl: false,
25
- editInOSMControlOptions: false,
26
- scaleControl: true,
27
8
  noControl: false, // Do not render any control.
28
- miniMap: false,
29
9
  name: '',
30
10
  description: '',
31
- displayPopupFooter: false,
32
11
  // When a TileLayer is in TMS mode, it needs -y instead of y.
33
12
  // This is usually handled by the TileLayer instance itself, but
34
13
  // we cannot rely on this because of the y is overriden by Leaflet
@@ -44,77 +23,14 @@ L.Map.mergeOptions({
44
23
  importPresets: [
45
24
  // {url: 'http://localhost:8019/en/datalayer/1502/', label: 'Simplified World Countries', format: 'geojson'}
46
25
  ],
47
- moreControl: true,
48
- captionBar: false,
49
- captionMenus: true,
50
26
  slideshow: {},
51
27
  clickable: true,
52
- easing: false,
53
28
  permissions: {},
54
- permanentCreditBackground: true,
55
29
  featuresHaveOwner: false,
56
30
  })
57
31
 
58
32
  U.Map = L.Map.extend({
59
33
  includes: [ControlsMixin],
60
- editableOptions: {
61
- zoom: undefined,
62
- scrollWheelZoom: Boolean,
63
- scaleControl: Boolean,
64
- moreControl: Boolean,
65
- miniMap: Boolean,
66
- displayPopupFooter: undefined,
67
- onLoadPanel: String,
68
- defaultView: String,
69
- name: String,
70
- description: String,
71
- licence: undefined,
72
- tilelayer: undefined,
73
- overlay: undefined,
74
- limitBounds: undefined,
75
- color: String,
76
- iconClass: String,
77
- iconUrl: String,
78
- smoothFactor: undefined,
79
- iconOpacity: undefined,
80
- opacity: undefined,
81
- weight: undefined,
82
- fill: undefined,
83
- fillColor: undefined,
84
- fillOpacity: undefined,
85
- dashArray: undefined,
86
- popupShape: String,
87
- popupTemplate: String,
88
- popupContentTemplate: String,
89
- zoomTo: Number,
90
- captionBar: Boolean,
91
- captionMenus: Boolean,
92
- slideshow: undefined,
93
- sortKey: undefined,
94
- labelKey: String,
95
- filterKey: undefined,
96
- facetKey: undefined,
97
- slugKey: undefined,
98
- showLabel: 'NullableBoolean',
99
- labelDirection: undefined,
100
- labelInteractive: undefined,
101
- outlinkTarget: undefined,
102
- shortCredit: undefined,
103
- longCredit: undefined,
104
- permanentCredit: undefined,
105
- permanentCreditBackground: undefined,
106
- zoomControl: 'NullableBoolean',
107
- datalayersControl: 'NullableBoolean',
108
- searchControl: 'NullableBoolean',
109
- locateControl: 'NullableBoolean',
110
- fullscreenControl: 'NullableBoolean',
111
- editinosmControl: 'NullableBoolean',
112
- embedControl: 'NullableBoolean',
113
- measureControl: 'NullableBoolean',
114
- tilelayersControl: 'NullableBoolean',
115
- starControl: 'NullableBoolean',
116
- easing: undefined,
117
- },
118
34
 
119
35
  initialize: function (el, geojson) {
120
36
  // Locale name (pt_PT, en_US…)
@@ -133,7 +49,8 @@ U.Map = L.Map.extend({
133
49
  geojson.properties.fullscreenControl = false
134
50
 
135
51
  L.Map.prototype.initialize.call(this, el, geojson.properties)
136
- U.DEFAULT_ICON_URL = this.options.default_iconUrl
52
+
53
+ if (geojson.properties.schema) this.overrideSchema(geojson.properties.schema)
137
54
 
138
55
  // After calling parent initialize, as we are doing initCenter our-selves
139
56
  if (geojson.geometry) this.options.center = this.latLng(geojson.geometry)
@@ -329,13 +246,11 @@ U.Map = L.Map.extend({
329
246
  // FIXME retrocompat
330
247
  L.Util.setBooleanFromQueryString(options, 'displayDataBrowserOnLoad')
331
248
  L.Util.setBooleanFromQueryString(options, 'displayCaptionOnLoad')
332
- for (const [key, type] of Object.entries(this.editableOptions)) {
333
- switch (type) {
249
+ for (const [key, schema] of Object.entries(U.SCHEMA)) {
250
+ switch (schema.type) {
334
251
  case Boolean:
335
- L.Util.setBooleanFromQueryString(options, key)
336
- break
337
- case 'NullableBoolean':
338
- L.Util.setNullableBooleanFromQueryString(options, key)
252
+ if (schema.nullable) L.Util.setNullableBooleanFromQueryString(options, key)
253
+ else L.Util.setBooleanFromQueryString(options, key)
339
254
  break
340
255
  case Number:
341
256
  L.Util.setNumberFromQueryString(options, key)
@@ -352,6 +267,12 @@ U.Map = L.Map.extend({
352
267
  }
353
268
  },
354
269
 
270
+ overrideSchema: function (schema) {
271
+ for (const [key, extra] of Object.entries(schema)) {
272
+ U.SCHEMA[key] = L.extend({}, U.SCHEMA[key], extra)
273
+ }
274
+ },
275
+
355
276
  initControls: function () {
356
277
  this.helpMenuActions = {}
357
278
  this._controls = {}
@@ -393,7 +314,7 @@ U.Map = L.Map.extend({
393
314
  title: { false: L._('View Fullscreen'), true: L._('Exit Fullscreen') },
394
315
  })
395
316
  this._controls.search = new U.SearchControl()
396
- this._controls.embed = new L.Control.Embed(this, this.options.embedOptions)
317
+ this._controls.embed = new L.Control.Embed(this)
397
318
  this._controls.tilelayersChooser = new U.TileLayerChooser(this)
398
319
  if (this.options.user) this._controls.star = new U.StarControl(this)
399
320
  this._controls.editinosm = new L.Control.EditInOSM({
@@ -459,7 +380,7 @@ U.Map = L.Map.extend({
459
380
  let name, status, control
460
381
  for (let i = 0; i < this.HIDDABLE_CONTROLS.length; i++) {
461
382
  name = this.HIDDABLE_CONTROLS[i]
462
- status = this.options[`${name}Control`]
383
+ status = this.getOption(`${name}Control`)
463
384
  if (status === false) continue
464
385
  control = this._controls[name]
465
386
  if (!control) continue
@@ -468,9 +389,9 @@ U.Map = L.Map.extend({
468
389
  L.DomUtil.addClass(control._container, 'display-on-more')
469
390
  else L.DomUtil.removeClass(control._container, 'display-on-more')
470
391
  }
471
- if (this.options.permanentCredit) this._controls.permanentCredit.addTo(this)
472
- if (this.options.moreControl) this._controls.more.addTo(this)
473
- if (this.options.scaleControl) this._controls.scale.addTo(this)
392
+ if (this.getOption('permanentCredit')) this._controls.permanentCredit.addTo(this)
393
+ if (this.getOption('moreControl')) this._controls.more.addTo(this)
394
+ if (this.getOption('scaleControl')) this._controls.scale.addTo(this)
474
395
  },
475
396
 
476
397
  initDataLayers: async function (datalayers) {
@@ -820,7 +741,7 @@ U.Map = L.Map.extend({
820
741
  },
821
742
 
822
743
  getDefaultOption: function (option) {
823
- return this.options[`default_${option}`]
744
+ return U.SCHEMA[option] && U.SCHEMA[option].default
824
745
  },
825
746
 
826
747
  getOption: function (option) {
@@ -904,7 +825,7 @@ U.Map = L.Map.extend({
904
825
 
905
826
  let mustReindex = false
906
827
 
907
- for (const option of Object.keys(this.editableOptions)) {
828
+ for (const option of Object.keys(U.SCHEMA)) {
908
829
  if (typeof importedData.properties[option] !== 'undefined') {
909
830
  this.options[option] = importedData.properties[option]
910
831
  if (option === 'sortKey') mustReindex = true
@@ -1033,7 +954,7 @@ U.Map = L.Map.extend({
1033
954
 
1034
955
  exportOptions: function () {
1035
956
  const properties = {}
1036
- for (const option of Object.keys(this.editableOptions)) {
957
+ for (const option of Object.keys(U.SCHEMA)) {
1037
958
  if (typeof this.options[option] !== 'undefined') {
1038
959
  properties[option] = this.options[option]
1039
960
  }
@@ -1555,35 +1476,11 @@ U.Map = L.Map.extend({
1555
1476
  _editCredits: function (container) {
1556
1477
  const credits = L.DomUtil.createFieldset(container, L._('Credits'))
1557
1478
  const creditsFields = [
1558
- ['options.licence', { handler: 'LicenceChooser', label: L._('licence') }],
1559
- [
1560
- 'options.shortCredit',
1561
- {
1562
- handler: 'Input',
1563
- label: L._('Short credits'),
1564
- helpEntries: ['shortCredit', 'textFormatting'],
1565
- },
1566
- ],
1567
- [
1568
- 'options.longCredit',
1569
- {
1570
- handler: 'Textarea',
1571
- label: L._('Long credits'),
1572
- helpEntries: ['longCredit', 'textFormatting'],
1573
- },
1574
- ],
1575
- [
1576
- 'options.permanentCredit',
1577
- {
1578
- handler: 'Textarea',
1579
- label: L._('Permanent credits'),
1580
- helpEntries: ['permanentCredit', 'textFormatting'],
1581
- },
1582
- ],
1583
- [
1584
- 'options.permanentCreditBackground',
1585
- { handler: 'Switch', label: L._('Permanent credits background') },
1586
- ],
1479
+ 'options.licence',
1480
+ 'options.shortCredit',
1481
+ 'options.longCredit',
1482
+ 'options.permanentCredit',
1483
+ 'options.permanentCreditBackground',
1587
1484
  ]
1588
1485
  const creditsBuilder = new U.FormBuilder(this, creditsFields, {
1589
1486
  callback: this.renderControls,
@@ -1691,7 +1588,7 @@ U.Map = L.Map.extend({
1691
1588
  name = L.DomUtil.create('h3', '', container)
1692
1589
  L.DomEvent.disableClickPropagation(container)
1693
1590
  this.permissions.addOwnerLink('span', container)
1694
- if (this.options.captionMenus) {
1591
+ if (this.getOption('captionMenus')) {
1695
1592
  L.DomUtil.createButton(
1696
1593
  'umap-about-link flat',
1697
1594
  container,