umap-project 1.5.0__py3-none-any.whl → 1.6.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.
@@ -9,7 +9,7 @@ msgid ""
9
9
  msgstr ""
10
10
  "Project-Id-Version: uMap\n"
11
11
  "Report-Msgid-Bugs-To: \n"
12
- "POT-Creation-Date: 2023-07-17 13:14+0000\n"
12
+ "POT-Creation-Date: 2023-08-21 15:24+0000\n"
13
13
  "PO-Revision-Date: 2013-11-22 14:00+0000\n"
14
14
  "Last-Translator: Yaya - Nurul Azeera Hidayah @ Muhammad Nur Hidayat Yasuyoshi (MNH48) <admin@mnh48.moe>, 2021,2023\n"
15
15
  "Language-Team: Malay (http://app.transifex.com/openstreetmap/umap/language/ms/)\n"
@@ -36,107 +36,107 @@ msgstr "Hanya boleh disunting dengan pautan rahsia"
36
36
  msgid "Site is readonly for maintenance"
37
37
  msgstr "Laman dalam mod baca sahaja untuk penyenggaraan"
38
38
 
39
- #: models.py:40
39
+ #: models.py:48
40
40
  msgid "name"
41
41
  msgstr "nama"
42
42
 
43
- #: models.py:71
43
+ #: models.py:79
44
44
  msgid "details"
45
45
  msgstr "perincian"
46
46
 
47
- #: models.py:72
47
+ #: models.py:80
48
48
  msgid "Link to a page where the licence is detailed."
49
49
  msgstr "Pautan ke halaman yang menyatakan lesennya."
50
50
 
51
- #: models.py:82
51
+ #: models.py:90
52
52
  msgid "URL template using OSM tile format"
53
53
  msgstr "Templat URL menggunakan format fail OSM"
54
54
 
55
- #: models.py:88
55
+ #: models.py:96
56
56
  msgid "Order of the tilelayers in the edit box"
57
57
  msgstr "Kedudukan lapisan jubin dalam kotak suntingan"
58
58
 
59
- #: models.py:134
59
+ #: models.py:142
60
60
  msgid "Everyone"
61
61
  msgstr "Semua orang"
62
62
 
63
- #: models.py:135 models.py:141
63
+ #: models.py:143 models.py:149
64
64
  msgid "Editors only"
65
65
  msgstr "Penyunting sahaja"
66
66
 
67
- #: models.py:136
67
+ #: models.py:144
68
68
  msgid "Owner only"
69
69
  msgstr "Pemilik sahaja"
70
70
 
71
- #: models.py:139
71
+ #: models.py:147
72
72
  msgid "Everyone (public)"
73
73
  msgstr "Semua orang (umum)"
74
74
 
75
- #: models.py:140
75
+ #: models.py:148
76
76
  msgid "Anyone with link"
77
77
  msgstr "Sesiapa yang ada pautan"
78
78
 
79
- #: models.py:142
79
+ #: models.py:150
80
80
  msgid "Blocked"
81
81
  msgstr "Disekat"
82
82
 
83
- #: models.py:145 models.py:295
83
+ #: models.py:153 models.py:307
84
84
  msgid "description"
85
85
  msgstr "keterangan"
86
86
 
87
- #: models.py:146
87
+ #: models.py:154
88
88
  msgid "center"
89
89
  msgstr "pertengahkan"
90
90
 
91
- #: models.py:147
91
+ #: models.py:155
92
92
  msgid "zoom"
93
93
  msgstr "zum"
94
94
 
95
- #: models.py:149
95
+ #: models.py:157
96
96
  msgid "locate"
97
97
  msgstr "mengesan"
98
98
 
99
- #: models.py:149
99
+ #: models.py:157
100
100
  msgid "Locate user on load?"
101
101
  msgstr "Kesan kedudukan pengguna semasa dimuatkan?"
102
102
 
103
- #: models.py:153
103
+ #: models.py:161
104
104
  msgid "Choose the map licence."
105
105
  msgstr "Pilih lesen peta."
106
106
 
107
- #: models.py:154
107
+ #: models.py:162
108
108
  msgid "licence"
109
109
  msgstr "lesen"
110
110
 
111
- #: models.py:164
111
+ #: models.py:172
112
112
  msgid "owner"
113
113
  msgstr "pemilik"
114
114
 
115
- #: models.py:168
115
+ #: models.py:176
116
116
  msgid "editors"
117
117
  msgstr "penyunting"
118
118
 
119
- #: models.py:171
119
+ #: models.py:181
120
120
  msgid "edit status"
121
121
  msgstr "status suntingan"
122
122
 
123
- #: models.py:174
123
+ #: models.py:186
124
124
  msgid "share status"
125
125
  msgstr "status perkongsian"
126
126
 
127
- #: models.py:177
127
+ #: models.py:189 models.py:316
128
128
  msgid "settings"
129
129
  msgstr "tetapan"
130
130
 
131
- #: models.py:250
131
+ #: models.py:262
132
132
  msgid "Clone of"
133
133
  msgstr "Klon bagi"
134
134
 
135
- #: models.py:299
135
+ #: models.py:311
136
136
  msgid "display on load"
137
137
  msgstr "paparkan semasa dimuatkan"
138
138
 
139
- #: models.py:300
139
+ #: models.py:312
140
140
  msgid "Display this layer on load."
141
141
  msgstr "Paparkan lapisan ini ketika dimuatkan."
142
142
 
@@ -154,6 +154,33 @@ msgstr "Layari peta %(current_user)s"
154
154
  msgid "%(current_user)s has no maps."
155
155
  msgstr "%(current_user)s tidak mempunyai peta."
156
156
 
157
+ #: templates/auth/user_form.html:6 templates/umap/user_dashboard.html:4
158
+ #: templates/umap/user_dashboard.html:10
159
+ msgid "My dashboard"
160
+ msgstr "Papan pemuka saya"
161
+
162
+ #: templates/auth/user_form.html:6 templates/umap/user_dashboard.html:10
163
+ msgid "My profile"
164
+ msgstr "Profil saya"
165
+
166
+ #: templates/auth/user_form.html:19
167
+ msgid "Save"
168
+ msgstr "Simpan"
169
+
170
+ #: templates/auth/user_form.html:24
171
+ msgid "Your current providers"
172
+ msgstr "Penyedia semasa anda"
173
+
174
+ #: templates/auth/user_form.html:30
175
+ msgid "Connect to another provider"
176
+ msgstr "Sambung ke penyedia lain"
177
+
178
+ #: templates/auth/user_form.html:32
179
+ msgid ""
180
+ "It's a good habit to connect your account to more than one provider, in case"
181
+ " one provider becomes unavailable, temporarily or even permanently."
182
+ msgstr "Lebih baik anda sambung akaun anda ke beberapa penyedia berlainan, kalau-kalau satu penyedia tidak tersedia, secara sementara atau secara kekal."
183
+
157
184
  #: templates/auth/user_stars.html:5
158
185
  #, python-format
159
186
  msgid "Browse %(current_user)s's starred maps"
@@ -231,7 +258,7 @@ msgid "And it's <a href=\"%(repo_url)s\">open source</a>!"
231
258
  msgstr "Dan ia <a href=\"%(repo_url)s\">bersumber terbuka</a>!"
232
259
 
233
260
  #: templates/umap/about_summary.html:48 templates/umap/navigation.html:42
234
- #: templates/umap/user_dashboard.html:18
261
+ #: templates/umap/user_dashboard.html:20
235
262
  msgid "Create a map"
236
263
  msgstr "Cipta peta"
237
264
 
@@ -266,7 +293,7 @@ msgstr "Dapatkan inspirasi, layari peta-peta"
266
293
  msgid "You are logged in. Continuing..."
267
294
  msgstr "Anda telah log masuk. Menyambung..."
268
295
 
269
- #: templates/umap/map_list.html:9 views.py:281
296
+ #: templates/umap/map_list.html:9 views.py:300
270
297
  msgid "by"
271
298
  msgstr "oleh"
272
299
 
@@ -398,60 +425,56 @@ msgstr "Cari peta"
398
425
  msgid "Search"
399
426
  msgstr "Cari"
400
427
 
401
- #: templates/umap/user_dashboard.html:4 templates/umap/user_dashboard.html:9
402
- msgid "My dashboard"
403
- msgstr "Papan pemuka saya"
404
-
405
428
  #: templates/umap/user_dashboard.html:7
406
429
  msgid "Search my maps"
407
430
  msgstr "Gelintar peta saya"
408
431
 
409
- #: templates/umap/user_dashboard.html:18
432
+ #: templates/umap/user_dashboard.html:20
410
433
  msgid "You have no map yet."
411
434
  msgstr "Anda belum ada peta."
412
435
 
413
- #: views.py:286
436
+ #: views.py:305
414
437
  msgid "View the map"
415
438
  msgstr "Lihat peta"
416
439
 
417
- #: views.py:607
440
+ #: views.py:628
418
441
  msgid "Map has been updated!"
419
442
  msgstr "Peta telah dikemas kini!"
420
443
 
421
- #: views.py:632
444
+ #: views.py:653
422
445
  msgid "Map editors updated with success!"
423
446
  msgstr "Penyunting peta telah dikemas kini dengan jayanya!"
424
447
 
425
- #: views.py:670
448
+ #: views.py:691
426
449
  #, python-format
427
450
  msgid "The uMap edit link for your map: %(map_name)s"
428
451
  msgstr "Pautan suntingan uMap untuk peta anda: %(map_name)s"
429
452
 
430
- #: views.py:673
453
+ #: views.py:694
431
454
  #, python-format
432
455
  msgid "Here is your secret edit link: %(link)s"
433
456
  msgstr "Ini pautan suntingan rahsia anda: %(link)s"
434
457
 
435
- #: views.py:679
458
+ #: views.py:700
436
459
  #, python-format
437
460
  msgid "Email sent to %(email)s"
438
461
  msgstr "E-mel telah dihantar ke %(email)s"
439
462
 
440
- #: views.py:690
463
+ #: views.py:711
441
464
  msgid "Only its owner can delete the map."
442
465
  msgstr "Hanya pemiliknya sahaja mampu memadamkan peta."
443
466
 
444
- #: views.py:713
467
+ #: views.py:734
445
468
  #, python-format
446
469
  msgid ""
447
470
  "Your map has been cloned! If you want to edit this map from another "
448
471
  "computer, please use this link: %(anonymous_url)s"
449
472
  msgstr "Peta anda telah diklon! Jika anda ingin menyunting peta ini dari komputer lain, sila gunakan pautan ini: %(anonymous_url)s"
450
473
 
451
- #: views.py:718
474
+ #: views.py:739
452
475
  msgid "Congratulations, your map has been cloned!"
453
476
  msgstr "Tahniah, peta anda telah berjaya diklon!"
454
477
 
455
- #: views.py:884
478
+ #: views.py:922
456
479
  msgid "Layer successfully deleted."
457
480
  msgstr "Lapisan telah berjaya dipadamkan."
@@ -0,0 +1,19 @@
1
+ # Generated by Django 4.2.2 on 2023-08-16 05:24
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+ dependencies = [
8
+ ("umap", "0011_alter_map_edit_status_alter_map_share_status"),
9
+ ]
10
+
11
+ operations = [
12
+ migrations.AddField(
13
+ model_name="datalayer",
14
+ name="settings",
15
+ field=models.JSONField(
16
+ blank=True, default=dict, null=True, verbose_name="settings"
17
+ ),
18
+ ),
19
+ ]
umap/models.py CHANGED
@@ -176,10 +176,14 @@ class Map(NamedModel):
176
176
  settings.AUTH_USER_MODEL, blank=True, verbose_name=_("editors")
177
177
  )
178
178
  edit_status = models.SmallIntegerField(
179
- choices=EDIT_STATUS, default=get_default_edit_status, verbose_name=_("edit status")
179
+ choices=EDIT_STATUS,
180
+ default=get_default_edit_status,
181
+ verbose_name=_("edit status"),
180
182
  )
181
183
  share_status = models.SmallIntegerField(
182
- choices=SHARE_STATUS, default=get_default_share_status, verbose_name=_("share status")
184
+ choices=SHARE_STATUS,
185
+ default=get_default_share_status,
186
+ verbose_name=_("share status"),
183
187
  )
184
188
  settings = models.JSONField(
185
189
  blank=True, null=True, verbose_name=_("settings"), default=dict
@@ -308,6 +312,9 @@ class DataLayer(NamedModel):
308
312
  help_text=_("Display this layer on load."),
309
313
  )
310
314
  rank = models.SmallIntegerField(default=0)
315
+ settings = models.JSONField(
316
+ blank=True, null=True, verbose_name=_("settings"), default=dict
317
+ )
311
318
 
312
319
  class Meta:
313
320
  ordering = ("rank",)
@@ -340,7 +347,14 @@ class DataLayer(NamedModel):
340
347
 
341
348
  @property
342
349
  def metadata(self):
343
- return {"name": self.name, "id": self.pk, "displayOnLoad": self.display_on_load}
350
+ # Retrocompat: minimal settings for maps not saved after settings property
351
+ # has been introduced
352
+ obj = self.settings or {
353
+ "name": self.name,
354
+ "displayOnLoad": self.display_on_load,
355
+ }
356
+ obj["id"] = self.pk
357
+ return obj
344
358
 
345
359
  def clone(self, map_inst=None):
346
360
  new = self.__class__.objects.get(pk=self.pk)
umap/settings/base.py CHANGED
@@ -129,6 +129,8 @@ DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
129
129
 
130
130
  EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
131
131
  FROM_EMAIL = None
132
+ # https://docs.djangoproject.com/en/4.2/releases/4.1/#forms
133
+ FORM_RENDERER = "django.forms.renderers.DjangoDivFormRenderer"
132
134
 
133
135
  # =============================================================================
134
136
  # Calculation of directories relative to the project module location
@@ -262,8 +264,6 @@ LEAFLET_ZOOM = env.int('LEAFLET_ZOOM', default=6)
262
264
  COMPRESS_ENABLED = True
263
265
  COMPRESS_OFFLINE = True
264
266
 
265
- SOCIAL_AUTH_NO_DEFAULT_PROTECTED_USER_FIELDS = True
266
- SOCIAL_AUTH_PROTECTED_USER_FIELDS = ("id", )
267
267
  LOGIN_URL = "login"
268
268
  SOCIAL_AUTH_LOGIN_REDIRECT_URL = "/login/popup/end/"
269
269
 
umap/static/umap/base.css CHANGED
@@ -194,6 +194,10 @@ select[multiple="multiple"] {
194
194
  font-size: 10px;
195
195
  border-radius: 0 2px;
196
196
  }
197
+ .content .helptext {
198
+ background-color: #eee;
199
+ color: #000;
200
+ }
197
201
  input + .help-text {
198
202
  margin-top: -14px;
199
203
  }
@@ -214,6 +218,9 @@ label {
214
218
  line-height: 21px;
215
219
  width: 100%;
216
220
  }
221
+ .content label {
222
+ font-weight: bold;
223
+ }
217
224
  input[type="checkbox"] + label {
218
225
  display: inline;
219
226
  padding: 0 14px;
@@ -133,6 +133,13 @@ h2.section {
133
133
  text-align: center;
134
134
  padding-top: 28px;
135
135
  }
136
+ h2.tabs a {
137
+ font-weight: normal;
138
+ color: #666;
139
+ }
140
+ h2.tabs a:hover {
141
+ text-decoration: underline;
142
+ }
136
143
  .showcase-map .map_fragment {
137
144
  height: 400px;
138
145
  }
@@ -663,7 +663,7 @@ L.U.DataLayer.include({
663
663
  L.U.DataLayer.addInitHook(function () {
664
664
  this.on('hide', this.propagateHide)
665
665
  this.on('show', this.propagateShow)
666
- this.propagateShow()
666
+ if (this.isVisible()) this.propagateShow()
667
667
  })
668
668
 
669
669
  L.U.Map.include({
@@ -934,7 +934,7 @@ L.U.Map.include({
934
934
  L.DomUtil.create('i', 'umap-icon-16 umap-add', filter)
935
935
  const labelFilter = L.DomUtil.create('span', '', filter)
936
936
  labelFilter.textContent = labelFilter.title = L._('Facet search')
937
- L.DomEvent.on(filter, 'click', this.openFilter, this)
937
+ L.DomEvent.on(filter, 'click', this.openFacet, this)
938
938
  actions.push(filter)
939
939
  }
940
940
  this.ui.openPanel({ data: { html: container }, actions: actions })
@@ -983,12 +983,15 @@ L.U.Map.include({
983
983
  name = L.DomUtil.create('a', 'map-name', container),
984
984
  share_status = L.DomUtil.create('a', 'share-status', container),
985
985
  update = () => {
986
+ const status = this.permissions.getShareStatusDisplay()
986
987
  name.textContent = this.getDisplayName()
987
- share_status.textContent = L._('Visibility: {status}', {
988
- status: this.permissions.getShareStatusDisplay(),
988
+ // status is not set until map is saved once
989
+ if (status) share_status.textContent = L._('Visibility: {status}', {
990
+ status: status,
989
991
  })
990
992
  }
991
993
  update()
994
+ this.once('saved', L.bind(update, this))
992
995
  name.href = '#'
993
996
  share_status.href = '#'
994
997
  logo.href = '/'
@@ -1269,6 +1272,7 @@ L.U.Search = L.PhotonSearch.extend({
1269
1272
  initialize: function (map, input, options) {
1270
1273
  L.PhotonSearch.prototype.initialize.call(this, map, input, options)
1271
1274
  this.options.url = map.options.urls.search
1275
+ if (map.options.maxBounds) this.options.bbox = map.options.maxBounds.toBBoxString()
1272
1276
  },
1273
1277
 
1274
1278
  onBlur: function (e) {
@@ -1,7 +1,7 @@
1
1
  L.Map.mergeOptions({
2
2
  overlay: null,
3
3
  datalayers: [],
4
- center: [4, 50],
4
+ center: [50, 4],
5
5
  zoom: 6,
6
6
  hash: true,
7
7
  default_color: 'DarkBlue',
@@ -85,6 +85,10 @@ L.U.Map.include({
85
85
  : true
86
86
  geojson.properties.fullscreenControl = false
87
87
  L.Util.setBooleanFromQueryString(geojson.properties, 'scrollWheelZoom')
88
+
89
+ // Before calling parent initialize
90
+ if (geojson.geometry) this.options.center = this.latLng(geojson.geometry)
91
+
88
92
  L.Map.prototype.initialize.call(this, el, geojson.properties)
89
93
 
90
94
  this.ui = new L.U.UI(this._container)
@@ -96,7 +100,6 @@ L.U.Map.include({
96
100
  this.name = this.options.name
97
101
  this.description = this.options.description
98
102
  this.demoTileInfos = this.options.demoTileInfos
99
- if (geojson.geometry) this.options.center = geojson.geometry
100
103
  this.options.zoomControl = zoomControl
101
104
  this.options.fullscreenControl = fullscreenControl
102
105
  L.Util.setBooleanFromQueryString(this.options, 'moreControl')
@@ -159,10 +162,12 @@ L.U.Map.include({
159
162
  this.facets = {}
160
163
 
161
164
  if (this.options.hash) this.addHash()
165
+ this.initTileLayers(this.options.tilelayers)
166
+ // Needs tilelayer to exist for minimap
162
167
  this.initControls()
168
+ // Needs locate control and hash to exist
163
169
  this.initCenter()
164
170
  this.handleLimitBounds()
165
- this.initTileLayers(this.options.tilelayers)
166
171
  this.initDatalayers()
167
172
 
168
173
  if (this.options.displayCaptionOnLoad) {
@@ -248,11 +248,6 @@ L.U.DataLayer = L.Evented.extend({
248
248
  }
249
249
  this.setUmapId(data.id)
250
250
  this.setOptions(data)
251
- this.backupOptions()
252
- this.connectToMap()
253
- if (this.displayedOnLoad()) this.show()
254
- if (!this.umap_id) this.isDirty = true
255
-
256
251
  // Retrocompat
257
252
  if (this.options.remoteData && this.options.remoteData.from) {
258
253
  this.options.fromZoom = this.options.remoteData.from
@@ -260,11 +255,15 @@ L.U.DataLayer = L.Evented.extend({
260
255
  if (this.options.remoteData && this.options.remoteData.to) {
261
256
  this.options.toZoom = this.options.remoteData.to
262
257
  }
258
+ this.backupOptions()
259
+ this.connectToMap()
260
+ if (this.displayedOnLoad() && this.showAtZoom()) this.show()
261
+ if (!this.umap_id) this.isDirty = true
263
262
 
264
263
  this.onceLoaded(function () {
265
264
  this.map.on('moveend', this.onMoveEnd, this)
266
- this.map.on('zoomend', this.onZoomEnd, this)
267
265
  })
266
+ this.map.on('zoomend', this.onZoomEnd, this)
268
267
  },
269
268
 
270
269
  onMoveEnd: function (e) {
@@ -313,7 +312,7 @@ L.U.DataLayer = L.Evented.extend({
313
312
  const Class = L.U.Layer[this.options.type] || L.U.Layer.Default
314
313
  this.layer = new Class(this)
315
314
  this.eachLayer((feature) => this.showFeature(feature))
316
- if (visible) this.map.addLayer(this.layer)
315
+ if (visible) this.show()
317
316
  this.propagateRemote()
318
317
  },
319
318
 
@@ -335,12 +334,15 @@ L.U.DataLayer = L.Evented.extend({
335
334
 
336
335
  fetchData: function () {
337
336
  if (!this.umap_id) return
337
+ if (this._loading) return
338
+ this._loading = true
338
339
  this.map.get(this._dataUrl(), {
339
340
  callback: function (geojson, response) {
340
341
  this._last_modified = response.getResponseHeader('Last-Modified')
341
342
  this.fromUmapGeoJSON(geojson)
342
343
  this.backupOptions()
343
344
  this.fire('loaded')
345
+ this._loading = false
344
346
  },
345
347
  context: this,
346
348
  })
@@ -390,8 +392,7 @@ L.U.DataLayer = L.Evented.extend({
390
392
  const from = parseInt(this.options.fromZoom, 10),
391
393
  to = parseInt(this.options.toZoom, 10),
392
394
  zoom = this.map.getZoom()
393
- if (isNaN(from) || isNaN(to)) return false
394
- return (zoom >= from && zoom <= to)
395
+ return !((!isNaN(from) && zoom < from) || (!isNaN(to) && zoom > to))
395
396
  },
396
397
 
397
398
  fetchRemoteData: function () {
@@ -1183,6 +1184,7 @@ L.U.DataLayer = L.Evented.extend({
1183
1184
  formData.append('name', this.options.name)
1184
1185
  formData.append('display_on_load', !!this.options.displayOnLoad)
1185
1186
  formData.append('rank', this.getRank())
1187
+ formData.append('settings', JSON.stringify(this.options))
1186
1188
  // Filename support is shaky, don't do it for now.
1187
1189
  const blob = new Blob([JSON.stringify(geojson)], { type: 'application/json' })
1188
1190
  formData.append('geojson', blob)
@@ -289,7 +289,7 @@ describe('L.U.Map', function () {
289
289
  })
290
290
 
291
291
  it('should update title bar (umap format import)', function () {
292
- var title = qs('#map div.umap-main-edit-toolbox h3 a.umap-click-to-edit')
292
+ var title = qs('#map div.umap-main-edit-toolbox a.map-name')
293
293
  assert.equal(title.innerHTML, 'Imported map')
294
294
  })
295
295
 
@@ -136,6 +136,11 @@ function initMap(options) {
136
136
  },
137
137
  default_iconUrl: '../src/img/marker.png',
138
138
  zoom: 6,
139
+ share_statuses: [
140
+ [1, 'Tout le monde (public)'],
141
+ [2, 'Quiconque a le lien'],
142
+ [3, 'Éditeurs uniquement'],
143
+ ],
139
144
  tilelayers: [
140
145
  {
141
146
  attribution: '\u00a9 OSM Contributors',