umap-project 2.6.0b1__py3-none-any.whl → 2.6.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.

Potentially problematic release.


This version of umap-project might be problematic. Click here for more details.

Files changed (38) hide show
  1. umap/__init__.py +1 -1
  2. umap/decorators.py +2 -3
  3. umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
  4. umap/locale/fa_IR/LC_MESSAGES/django.po +9 -9
  5. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/hu/LC_MESSAGES/django.po +18 -18
  7. umap/models.py +29 -16
  8. umap/static/umap/js/modules/data/features.js +10 -5
  9. umap/static/umap/js/modules/data/layer.js +1 -1
  10. umap/static/umap/js/modules/rendering/ui.js +25 -4
  11. umap/static/umap/js/modules/rules.js +16 -3
  12. umap/static/umap/locale/en.js +3 -1
  13. umap/static/umap/locale/en.json +3 -1
  14. umap/static/umap/locale/eu.js +8 -6
  15. umap/static/umap/locale/eu.json +8 -6
  16. umap/static/umap/locale/fa_IR.js +14 -12
  17. umap/static/umap/locale/fa_IR.json +14 -12
  18. umap/static/umap/locale/fr.js +3 -1
  19. umap/static/umap/locale/fr.json +3 -1
  20. umap/static/umap/locale/hu.js +14 -12
  21. umap/static/umap/locale/hu.json +14 -12
  22. umap/static/umap/map.css +2 -2
  23. umap/static/umap/vars.css +1 -0
  24. umap/static/umap/vendors/editable/Leaflet.Editable.js +2079 -1937
  25. umap/static/umap/vendors/markercluster/MarkerCluster.Default.css +1 -1
  26. umap/templatetags/umap_tags.py +1 -1
  27. umap/tests/conftest.py +5 -0
  28. umap/tests/integration/test_browser.py +20 -0
  29. umap/tests/integration/test_conditional_rules.py +102 -17
  30. umap/tests/integration/test_draw_polygon.py +28 -0
  31. umap/tests/test_datalayer.py +63 -33
  32. umap/tests/test_map.py +30 -21
  33. umap/views.py +11 -19
  34. {umap_project-2.6.0b1.dist-info → umap_project-2.6.1.dist-info}/METADATA +6 -6
  35. {umap_project-2.6.0b1.dist-info → umap_project-2.6.1.dist-info}/RECORD +38 -38
  36. {umap_project-2.6.0b1.dist-info → umap_project-2.6.1.dist-info}/WHEEL +0 -0
  37. {umap_project-2.6.0b1.dist-info → umap_project-2.6.1.dist-info}/entry_points.txt +0 -0
  38. {umap_project-2.6.0b1.dist-info → umap_project-2.6.1.dist-info}/licenses/LICENSE +0 -0
umap/__init__.py CHANGED
@@ -1 +1 @@
1
- VERSION = "2.6.0b1"
1
+ VERSION = "2.6.1"
umap/decorators.py CHANGED
@@ -33,12 +33,11 @@ def can_edit_map(view_func):
33
33
  @wraps(view_func)
34
34
  def wrapper(request, *args, **kwargs):
35
35
  map_inst = get_object_or_404(Map, pk=kwargs["map_id"])
36
- user = request.user
37
36
  kwargs["map_inst"] = map_inst # Avoid rerequesting the map in the view
38
37
  if map_inst.edit_status >= map_inst.COLLABORATORS:
39
- can_edit = map_inst.can_edit(user=user, request=request)
38
+ can_edit = map_inst.can_edit(request=request)
40
39
  if not can_edit:
41
- if map_inst.owner and not user.is_authenticated:
40
+ if map_inst.owner and not request.user.is_authenticated:
42
41
  return simple_json_response(login_required=str(LOGIN_URL))
43
42
  return HttpResponseForbidden()
44
43
  return view_func(request, *args, **kwargs)
Binary file
@@ -12,7 +12,7 @@ msgid ""
12
12
  msgstr ""
13
13
  "Project-Id-Version: uMap\n"
14
14
  "Report-Msgid-Bugs-To: \n"
15
- "POT-Creation-Date: 2024-08-30 18:23+0000\n"
15
+ "POT-Creation-Date: 2024-09-04 14:02+0000\n"
16
16
  "PO-Revision-Date: 2013-11-22 14:00+0000\n"
17
17
  "Last-Translator: imni <iriman@chmail.ir>, 2024\n"
18
18
  "Language-Team: Persian (Iran) (http://app.transifex.com/openstreetmap/umap/language/fa_IR/)\n"
@@ -326,19 +326,19 @@ msgstr "این یک نمونهٔ نمایشی است که برای آزمایش
326
326
 
327
327
  #: templates/umap/content_footer.html:5
328
328
  msgid "An OpenStreetMap project"
329
- msgstr ""
329
+ msgstr "پروژه‌ای با اوپن‌استریت‌مپ"
330
330
 
331
331
  #: templates/umap/content_footer.html:6
332
332
  msgid "version"
333
- msgstr ""
333
+ msgstr "نسخه"
334
334
 
335
335
  #: templates/umap/content_footer.html:7
336
336
  msgid "Hosted by"
337
- msgstr ""
337
+ msgstr "میزبانی‌شده در"
338
338
 
339
339
  #: templates/umap/content_footer.html:8
340
340
  msgid "Contact"
341
- msgstr ""
341
+ msgstr "تماس"
342
342
 
343
343
  #: templates/umap/content_footer.html:9 templates/umap/navigation.html:25
344
344
  msgid "Help"
@@ -373,11 +373,11 @@ msgstr "الهام بگیرید، نقشه‌ها را مرور کنید"
373
373
  msgid "You are logged in. Continuing..."
374
374
  msgstr "شما وارد شده‌اید. ادامه..."
375
375
 
376
- #: templates/umap/map_list.html:10 views.py:433
376
+ #: templates/umap/map_list.html:11 views.py:433
377
377
  msgid "by"
378
378
  msgstr "ساختهٔ"
379
379
 
380
- #: templates/umap/map_list.html:18
380
+ #: templates/umap/map_list.html:20
381
381
  msgid "More"
382
382
  msgstr "بیشتر"
383
383
 
@@ -553,12 +553,12 @@ msgstr "جستجو"
553
553
  #: templates/umap/team_detail.html:10
554
554
  #, python-format
555
555
  msgid "Browse %(current_team)s's maps"
556
- msgstr ""
556
+ msgstr "مرور نقشه‌های %(current_team)s"
557
557
 
558
558
  #: templates/umap/team_detail.html:22
559
559
  #, python-format
560
560
  msgid "%(current_team)s has no public maps."
561
- msgstr ""
561
+ msgstr "%(current_team)s نقشهٔ عمومی ندارد."
562
562
 
563
563
  #: templates/umap/team_form.html:24
564
564
  msgid "Delete this team"
Binary file
@@ -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: 2024-08-30 18:23+0000\n"
12
+ "POT-Creation-Date: 2024-09-04 14:02+0000\n"
13
13
  "PO-Revision-Date: 2013-11-22 14:00+0000\n"
14
14
  "Last-Translator: Gábor Babos <gabor.babos@gmail.com>, 2017-2019,2023-2024\n"
15
15
  "Language-Team: Hungarian (http://app.transifex.com/openstreetmap/umap/language/hu/)\n"
@@ -65,7 +65,7 @@ msgstr "Mindenki"
65
65
 
66
66
  #: models.py:168 models.py:174 models.py:425
67
67
  msgid "Editors and team only"
68
- msgstr ""
68
+ msgstr "Csak a szerkesztők és a csoport"
69
69
 
70
70
  #: models.py:169 models.py:426
71
71
  msgid "Owner only"
@@ -117,7 +117,7 @@ msgstr "szerkesztők"
117
117
 
118
118
  #: models.py:207
119
119
  msgid "team"
120
- msgstr ""
120
+ msgstr "csoport"
121
121
 
122
122
  #: models.py:213 models.py:447
123
123
  msgid "edit status"
@@ -323,19 +323,19 @@ msgstr "Ez egy demonstrációs változat, amelyet tesztelésre és még nem nyil
323
323
 
324
324
  #: templates/umap/content_footer.html:5
325
325
  msgid "An OpenStreetMap project"
326
- msgstr ""
326
+ msgstr "OpenStreetMap projekt"
327
327
 
328
328
  #: templates/umap/content_footer.html:6
329
329
  msgid "version"
330
- msgstr ""
330
+ msgstr "verzió"
331
331
 
332
332
  #: templates/umap/content_footer.html:7
333
333
  msgid "Hosted by"
334
- msgstr ""
334
+ msgstr "Tárhely:"
335
335
 
336
336
  #: templates/umap/content_footer.html:8
337
337
  msgid "Contact"
338
- msgstr ""
338
+ msgstr "Kapcsolat:"
339
339
 
340
340
  #: templates/umap/content_footer.html:9 templates/umap/navigation.html:25
341
341
  msgid "Help"
@@ -356,7 +356,7 @@ msgstr "Saját profil"
356
356
 
357
357
  #: templates/umap/dashboard_menu.html:13
358
358
  msgid "My teams"
359
- msgstr ""
359
+ msgstr "Csoportjaim"
360
360
 
361
361
  #: templates/umap/home.html:14
362
362
  msgid "Map of the uMaps"
@@ -370,11 +370,11 @@ msgstr "Szerezzen ihletet, böngésszen a térképek között!"
370
370
  msgid "You are logged in. Continuing..."
371
371
  msgstr "Be van jelentkezve. Továbblépés…"
372
372
 
373
- #: templates/umap/map_list.html:10 views.py:433
373
+ #: templates/umap/map_list.html:11 views.py:433
374
374
  msgid "by"
375
375
  msgstr "– készítette:"
376
376
 
377
- #: templates/umap/map_list.html:18
377
+ #: templates/umap/map_list.html:20
378
378
  msgid "More"
379
379
  msgstr "Még több"
380
380
 
@@ -550,20 +550,20 @@ msgstr "Keresés"
550
550
  #: templates/umap/team_detail.html:10
551
551
  #, python-format
552
552
  msgid "Browse %(current_team)s's maps"
553
- msgstr ""
553
+ msgstr "%(current_team)s csoport térképeinek böngészése"
554
554
 
555
555
  #: templates/umap/team_detail.html:22
556
556
  #, python-format
557
557
  msgid "%(current_team)s has no public maps."
558
- msgstr ""
558
+ msgstr "%(current_team)s csoportnak nincs nyilvános térképe."
559
559
 
560
560
  #: templates/umap/team_form.html:24
561
561
  msgid "Delete this team"
562
- msgstr ""
562
+ msgstr "Csoport törlése"
563
563
 
564
564
  #: templates/umap/team_form.html:47
565
565
  msgid "Add user"
566
- msgstr ""
566
+ msgstr "Felhasználó hozzáadása"
567
567
 
568
568
  #: templates/umap/user_dashboard.html:9 templates/umap/user_dashboard.html:25
569
569
  msgid "Search my maps"
@@ -584,20 +584,20 @@ msgstr "Önnek még nincs térképe."
584
584
 
585
585
  #: templates/umap/user_teams.html:17
586
586
  msgid "Users"
587
- msgstr ""
587
+ msgstr "Felhasználók"
588
588
 
589
589
  #: templates/umap/user_teams.html:48
590
590
  msgid "New team"
591
- msgstr ""
591
+ msgstr "Új csoport"
592
592
 
593
593
  #: views.py:235
594
594
  msgid "Cannot delete a team with more than one member"
595
- msgstr ""
595
+ msgstr "Egynél több tagú csoport nem törölhető"
596
596
 
597
597
  #: views.py:239
598
598
  #, python-format
599
599
  msgid "Team “%(name)s” has been deleted"
600
- msgstr ""
600
+ msgstr "%(name)s csoport törölve"
601
601
 
602
602
  #: views.py:438
603
603
  msgid "View the map"
umap/models.py CHANGED
@@ -281,8 +281,10 @@ class Map(NamedModel):
281
281
  def get_author(self):
282
282
  return self.team or self.owner
283
283
 
284
- def is_owner(self, user=None, request=None):
285
- if user and self.owner == user:
284
+ def is_owner(self, request=None):
285
+ if not request:
286
+ return False
287
+ if request.user and self.owner == request.user:
286
288
  return True
287
289
  return self.is_anonymous_owner(request)
288
290
 
@@ -297,14 +299,16 @@ class Map(NamedModel):
297
299
  has_anonymous_cookie = False
298
300
  return has_anonymous_cookie
299
301
 
300
- def can_delete(self, user=None, request=None):
301
- if self.owner and user != self.owner:
302
+ def can_delete(self, request=None):
303
+ if not request:
304
+ return False
305
+ if self.owner and request.user != self.owner:
302
306
  return False
303
307
  if not self.owner and not self.is_anonymous_owner(request):
304
308
  return False
305
309
  return True
306
310
 
307
- def can_edit(self, user=None, request=None):
311
+ def can_edit(self, request=None):
308
312
  """
309
313
  Define if a user can edit or not the instance, according to his account
310
314
  or the request.
@@ -318,12 +322,18 @@ class Map(NamedModel):
318
322
  - anyone otherwise (ANONYMOUS)
319
323
  """
320
324
  can = False
321
- if request and not self.owner:
322
- if settings.UMAP_ALLOW_ANONYMOUS and self.is_anonymous_owner(request):
323
- can = True
324
- if self.edit_status == self.ANONYMOUS:
325
+ if not request:
326
+ return False
327
+ user = request.user
328
+ if (
329
+ not self.owner
330
+ and settings.UMAP_ALLOW_ANONYMOUS
331
+ and self.is_anonymous_owner(request)
332
+ ):
333
+ can = True
334
+ elif self.edit_status == self.ANONYMOUS:
325
335
  can = True
326
- elif user is None:
336
+ elif not user.is_authenticated:
327
337
  can = False
328
338
  elif user == self.owner:
329
339
  can = True
@@ -477,7 +487,7 @@ class DataLayer(NamedModel):
477
487
  path.append(str(self.map.pk))
478
488
  return os.path.join(*path)
479
489
 
480
- def metadata(self, user=None, request=None):
490
+ def metadata(self, request=None):
481
491
  # Retrocompat: minimal settings for maps not saved after settings property
482
492
  # has been introduced
483
493
  obj = self.settings or {
@@ -488,7 +498,7 @@ class DataLayer(NamedModel):
488
498
  obj["old_id"] = self.old_id
489
499
  obj["id"] = self.pk
490
500
  obj["permissions"] = {"edit_status": self.edit_status}
491
- obj["editMode"] = "advanced" if self.can_edit(user, request) else "disabled"
501
+ obj["editMode"] = "advanced" if self.can_edit(request) else "disabled"
492
502
  return obj
493
503
 
494
504
  def clone(self, map_inst=None):
@@ -557,22 +567,25 @@ class DataLayer(NamedModel):
557
567
  if name.startswith(prefixes) and name.endswith(".gz"):
558
568
  self.geojson.storage.delete(os.path.join(root, name))
559
569
 
560
- def can_edit(self, user=None, request=None):
570
+ def can_edit(self, request=None):
561
571
  """
562
572
  Define if a user can edit or not the instance, according to his account
563
573
  or the request.
564
574
  """
565
575
  if self.edit_status == self.INHERIT:
566
- return self.map.can_edit(user, request)
576
+ return self.map.can_edit(request)
567
577
  can = False
578
+ if not request:
579
+ return False
580
+ user = request.user
568
581
  if not self.map.owner:
569
582
  if settings.UMAP_ALLOW_ANONYMOUS and self.map.is_anonymous_owner(request):
570
583
  can = True
571
584
  if self.edit_status == self.ANONYMOUS:
572
585
  can = True
573
- elif user is not None and user == self.map.owner:
586
+ elif user.is_authenticated and user == self.map.owner:
574
587
  can = True
575
- elif user is not None and self.edit_status == self.COLLABORATORS:
588
+ elif user.is_authenticated and self.edit_status == self.COLLABORATORS:
576
589
  if user in self.map.editors.all() or self.map.team in user.teams.all():
577
590
  can = True
578
591
  return can
@@ -98,8 +98,8 @@ class Feature {
98
98
  this.pushGeometry()
99
99
  }
100
100
 
101
- isOnScreen() {
102
- return this.ui?.isOnScreen()
101
+ isOnScreen(bounds) {
102
+ return this.ui?.isOnScreen(bounds)
103
103
  }
104
104
 
105
105
  pushGeometry() {
@@ -261,7 +261,7 @@ class Feature {
261
261
  builder.helpers['properties.name'].input.focus()
262
262
  })
263
263
  this.map.editedFeature = this
264
- if (!this.ui.isOnScreen()) this.zoomTo(event)
264
+ if (!this.ui.isOnScreen(this.map.getBounds())) this.zoomTo(event)
265
265
  }
266
266
 
267
267
  getAdvancedEditActions(container) {
@@ -508,7 +508,12 @@ class Feature {
508
508
 
509
509
  matchFilter(filter, keys) {
510
510
  filter = filter.toLowerCase()
511
- if (Utils.hasVar(keys)) {
511
+ // When user hasn't touched settings, when a feature has no name
512
+ // it will use the datalayer's name, so let's make the filtering
513
+ // consistent.
514
+ // Also, if the user has defined a labelKey with vars, let's
515
+ // compute before filtering
516
+ if (Utils.hasVar(keys) || keys === 'displayName') {
512
517
  return this.getDisplayName().toLowerCase().indexOf(filter) !== -1
513
518
  }
514
519
  keys = keys.split(',')
@@ -680,8 +685,8 @@ class Path extends Feature {
680
685
 
681
686
  edit(event) {
682
687
  if (this.map.editEnabled) {
683
- if (!this.ui.editEnabled()) this.ui.enableEdit()
684
688
  super.edit(event)
689
+ if (!this.ui.editEnabled()) this.ui.makeGeometryEditable()
685
690
  }
686
691
  }
687
692
 
@@ -1115,7 +1115,7 @@ export class DataLayer {
1115
1115
  if (this.map.options.filterKey) return this.map.options.filterKey
1116
1116
  if (this.getOption('labelKey')) return this.getOption('labelKey')
1117
1117
  if (this.map.options.sortKey) return this.map.options.sortKey
1118
- return 'name'
1118
+ return 'displayName'
1119
1119
  }
1120
1120
 
1121
1121
  renderLegend(container) {
@@ -93,13 +93,21 @@ const FeatureMixin = {
93
93
  getContextMenuItems: function (event) {
94
94
  const permalink = this.feature.getPermalink()
95
95
  let items = []
96
- if (permalink)
96
+ if (permalink) {
97
97
  items.push({
98
98
  text: translate('Permalink'),
99
99
  callback: () => {
100
100
  window.open(permalink)
101
101
  },
102
102
  })
103
+ }
104
+ items.push({
105
+ text: translate('Copy as GeoJSON'),
106
+ callback: () => {
107
+ L.Util.copyToClipboard(JSON.stringify(this.feature.toGeoJSON()))
108
+ this._map.tooltip.open({ content: L._('✅ Copied!') })
109
+ },
110
+ })
103
111
  if (this._map.editEnabled && !this.feature.isReadOnly()) {
104
112
  items = items.concat(this.getContextMenuEditItems(event))
105
113
  }
@@ -148,7 +156,6 @@ const FeatureMixin = {
148
156
 
149
157
  const PointMixin = {
150
158
  isOnScreen: function (bounds) {
151
- bounds = bounds || this._map.getBounds()
152
159
  return bounds.contains(this.getCenter())
153
160
  },
154
161
  }
@@ -281,6 +288,21 @@ const PathMixin = {
281
288
  }
282
289
  },
283
290
 
291
+ makeGeometryEditable: function () {
292
+ if (this._map.editedFeature !== this.feature) {
293
+ this.disableEdit()
294
+ return
295
+ }
296
+ this._map.once('moveend', this.makeGeometryEditable, this)
297
+ const pointsCount = this._parts.reduce((acc, part) => acc + part.length, 0)
298
+ if (pointsCount > 100 && this._map.getZoom() < this._map.getMaxZoom()) {
299
+ this._map.tooltip.open({ content: L._('Please zoom in to edit the geometry') })
300
+ this.disableEdit()
301
+ } else {
302
+ this.enableEdit()
303
+ }
304
+ },
305
+
284
306
  addInteractions: function () {
285
307
  FeatureMixin.addInteractions.call(this)
286
308
  this.on('editable:disable', this.onCommit)
@@ -376,7 +398,7 @@ const PathMixin = {
376
398
  getContextMenuEditItems: function (event) {
377
399
  const items = FeatureMixin.getContextMenuEditItems.call(this, event)
378
400
  if (
379
- this._map?.editedFeature !== this &&
401
+ this._map?.editedFeature !== this.feature &&
380
402
  this.feature.isSameClass(this._map.editedFeature)
381
403
  ) {
382
404
  items.push({
@@ -420,7 +442,6 @@ const PathMixin = {
420
442
  ],
421
443
 
422
444
  isOnScreen: function (bounds) {
423
- bounds = bounds || this._map.getBounds()
424
445
  return bounds.overlaps(this.getBounds())
425
446
  },
426
447
  }
@@ -3,6 +3,8 @@ import { translate } from './i18n.js'
3
3
  import * as Utils from './utils.js'
4
4
  import { AutocompleteDatalist } from './autocomplete.js'
5
5
 
6
+ const EMPTY_VALUES = ['', undefined, null]
7
+
6
8
  class Rule {
7
9
  get condition() {
8
10
  return this._condition
@@ -75,13 +77,22 @@ class Rule {
75
77
  if (vars.length !== 2) return
76
78
  this.key = vars[0]
77
79
  this.expected = vars[1]
80
+ if (EMPTY_VALUES.includes(this.expected)) {
81
+ this.cast = (v) => EMPTY_VALUES.includes(v)
82
+ }
78
83
  // Special cases where we want to be lousy when checking isNaN without
79
84
  // coercing to a Number first because we handle multiple types.
80
85
  // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/
81
86
  // Reference/Global_Objects/Number/isNaN
82
87
  // biome-ignore lint/suspicious/noGlobalIsNan: expected might not be a number.
83
- if (!isNaN(this.expected)) this.cast = Number.parseFloat
84
- else if (['true', 'false'].includes(this.expected)) this.cast = (v) => !!v
88
+ else if (!isNaN(this.expected)) {
89
+ this.cast = Number.parseFloat
90
+ } else if (['true', 'false'].includes(this.expected)) {
91
+ this.cast = (v) => {
92
+ if (`${v}`.toLowerCase() === 'true') return true
93
+ if (`${v}`.toLowerCase() === 'false') return false
94
+ }
95
+ }
85
96
  this.expected = this.cast(this.expected)
86
97
  }
87
98
 
@@ -133,7 +144,9 @@ class Rule {
133
144
  autocomplete.suggestions = [`${value}=`, `${value}!=`, `${value}>`, `${value}<`]
134
145
  } else if (value.endsWith('=')) {
135
146
  const key = value.split('!')[0].split('=')[0]
136
- autocomplete.suggestions = this.map.sortedValues(key).map((str) => `${value}${str || ''}`)
147
+ autocomplete.suggestions = this.map
148
+ .sortedValues(key)
149
+ .map((str) => `${value}${str || ''}`)
137
150
  }
138
151
  })
139
152
  this.map.editPanel.open({ content: container })
@@ -504,7 +504,9 @@ const locale = {
504
504
  "Property name to compute circles": "Property name to compute circles",
505
505
  "Min circle radius": "Min circle radius",
506
506
  "Max circle radius": "Max circle radius",
507
- "Display the open browser control": "Display the open browser control"
507
+ "Display the open browser control": "Display the open browser control",
508
+ "Copy as GeoJSON": "Copy as GeoJSON",
509
+ "Please zoom in to edit the geometry": "Please zoom in to edit the geometry"
508
510
  }
509
511
  L.registerLocale("en", locale)
510
512
  L.setLocale("en")
@@ -504,5 +504,7 @@
504
504
  "Property name to compute circles": "Property name to compute circles",
505
505
  "Min circle radius": "Min circle radius",
506
506
  "Max circle radius": "Max circle radius",
507
- "Display the open browser control": "Display the open browser control"
507
+ "Display the open browser control": "Display the open browser control",
508
+ "Copy as GeoJSON": "Copy as GeoJSON",
509
+ "Please zoom in to edit the geometry": "Please zoom in to edit the geometry"
508
510
  }
@@ -498,13 +498,15 @@ const locale = {
498
498
  "Expression is empty": "Esamoldea hutsa dago",
499
499
  "OK": "Ados",
500
500
  "Cancel": "Utzi",
501
- "Attach map to a team": "Attach map to a team",
502
- "Display the polygon inverted": "Display the polygon inverted",
503
- "Proportional circles": "Proportional circles",
501
+ "Attach map to a team": "Erantsi mapa talde bati",
502
+ "Display the polygon inverted": "Bistaratu poligonoa alderantziz",
503
+ "Proportional circles": "Zirkulu proportzionalak",
504
504
  "Property name to compute circles": "Property name to compute circles",
505
- "Min circle radius": "Min circle radius",
506
- "Max circle radius": "Max circle radius",
507
- "Display the open browser control": "Display the open browser control"
505
+ "Min circle radius": "Zirkuluaren gutxieneko erradioa",
506
+ "Max circle radius": "Zirkuluaren gehieneko erradioa",
507
+ "Display the open browser control": "Display the open browser control",
508
+ "Copy as GeoJSON": "Kopiatu GeoJSON gisa",
509
+ "Please zoom in to edit the geometry": "Mesedez, handitu geometria editatzeko"
508
510
  }
509
511
  L.registerLocale("eu", locale)
510
512
  L.setLocale("eu")
@@ -498,11 +498,13 @@
498
498
  "Expression is empty": "Esamoldea hutsa dago",
499
499
  "OK": "Ados",
500
500
  "Cancel": "Utzi",
501
- "Attach map to a team": "Attach map to a team",
502
- "Display the polygon inverted": "Display the polygon inverted",
503
- "Proportional circles": "Proportional circles",
501
+ "Attach map to a team": "Erantsi mapa talde bati",
502
+ "Display the polygon inverted": "Bistaratu poligonoa alderantziz",
503
+ "Proportional circles": "Zirkulu proportzionalak",
504
504
  "Property name to compute circles": "Property name to compute circles",
505
- "Min circle radius": "Min circle radius",
506
- "Max circle radius": "Max circle radius",
507
- "Display the open browser control": "Display the open browser control"
505
+ "Min circle radius": "Zirkuluaren gutxieneko erradioa",
506
+ "Max circle radius": "Zirkuluaren gehieneko erradioa",
507
+ "Display the open browser control": "Display the open browser control",
508
+ "Copy as GeoJSON": "Kopiatu GeoJSON gisa",
509
+ "Please zoom in to edit the geometry": "Mesedez, handitu geometria editatzeko"
508
510
  }
@@ -160,7 +160,7 @@ const locale = {
160
160
  "fill color": "رنگ پرکردن",
161
161
  "fill opacity": "شفافیت پرشدگی",
162
162
  "fill": "پرکردن",
163
- "Fit all data": "Fit all data",
163
+ "Fit all data": "گنجیدن همهٔ داده‌ها",
164
164
  "Format": "قالب",
165
165
  "From zoom": "از زوم",
166
166
  "full backup": "پشتیبان کامل",
@@ -218,7 +218,7 @@ const locale = {
218
218
  "Link to…": "پیوند به…",
219
219
  "Link with text: [[http://example.com|text of the link]]": "پیوند با متن:\n[[http://example.com|text of the link]]",
220
220
  "Long credits": "یادکردهای بلند",
221
- "Longitude": "عرض جغرافیایی",
221
+ "Longitude": "طول جغرافیایی",
222
222
  "Make main shape": "شکل اصلی را ایجاد کنید",
223
223
  "Manage layers": "مدیریت لایه‌ها",
224
224
  "Manual": "دستی",
@@ -237,7 +237,7 @@ const locale = {
237
237
  "max zoom": "بیشینهٔ بزرگنمایی",
238
238
  "Measure distances": "اندازه‌گیری مسافت‌ها",
239
239
  "Merge lines": "ادغام خطوط",
240
- "mi": "مایل",
240
+ "mi": "mi",
241
241
  "miles": "مایل",
242
242
  "min zoom": "کمینهٔ بزرگنمایی",
243
243
  "More controls": "دکمه‌های بیشتر",
@@ -304,7 +304,7 @@ const locale = {
304
304
  "Save this center and zoom": "ذخیره‌سازی این مرکزیت و بزرگنمایی",
305
305
  "Save this location as new feature": "این مکان را به عنوان عنصر جدید ذخیره کنید",
306
306
  "Save": "ذخیره",
307
- "Saved center and zoom": "مرکزیت و بزرگنمایی ذخیره شد",
307
+ "Saved center and zoom": "مرکزیت و بزرگنمایی ذخیره‌شده",
308
308
  "Search location": "جستجوی مکان",
309
309
  "Search": "جستجو",
310
310
  "Secret edit link:": "پیوند محرمانه برای ویرایش:",
@@ -354,14 +354,14 @@ const locale = {
354
354
  "Type char or paste emoji": "نویسه‌ای بنویسید یا شکلکی بچسبانید",
355
355
  "Type of layer": "نوع لایه",
356
356
  "Unable to detect format of file {filename}": "قالب فایل {filename} تشخیص داده نشد",
357
- "Untitled layer": "لایهٔ بدون عنوان",
358
- "Untitled map": "نقشهٔ بدون عنوان",
357
+ "Untitled layer": "لایهٔ بی‌عنوان",
358
+ "Untitled map": "نقشهٔ بی‌عنوان",
359
359
  "Update permissions and editors": "روزآمدسازی مجوزها و ویرایشگران",
360
360
  "Update permissions": "روزآمدسازی مجوزها",
361
361
  "Update who can see and edit the map": "چه کسی می‌تواند نقشه را ببیند و ویرایش کند",
362
362
  "Url": "نشانی اینترنتی",
363
363
  "URL": "URL",
364
- "Use current bounds": "از کران‌های فعلی استفاده شود",
364
+ "Use current bounds": "استفاده از کران‌های فعلی",
365
365
  "Use placeholders with feature properties between brackets, eg. &#123;name&#125;, they will be dynamically replaced by the corresponding values.": "هر کدام از ویژگی‌های عنصر را بین آکولاد قرار دهید و جانگهدار بسازید. مثال: &#123;name&#125;. این جانگهدارها به طور پویا به مقدار متناظرشان تغییر می‌کنند.",
366
366
  "User content credits": "یادکردهای محتوای کاربر",
367
367
  "User interface options": "گزینه‌های رابط کاربری",
@@ -500,11 +500,13 @@ const locale = {
500
500
  "Cancel": "لغو",
501
501
  "Attach map to a team": "Attach map to a team",
502
502
  "Display the polygon inverted": "Display the polygon inverted",
503
- "Proportional circles": "Proportional circles",
504
- "Property name to compute circles": "Property name to compute circles",
505
- "Min circle radius": "Min circle radius",
506
- "Max circle radius": "Max circle radius",
507
- "Display the open browser control": "Display the open browser control"
503
+ "Proportional circles": "دایره‌های نسبی",
504
+ "Property name to compute circles": "نام ویژگی برای محاسبهٔ دایره‌ها",
505
+ "Min circle radius": "کمترین شعاع دایره",
506
+ "Max circle radius": "بیشتری شعاع دایره",
507
+ "Display the open browser control": "نمایش دکمهٔ بازکردن مرورگر",
508
+ "Copy as GeoJSON": "Copy as GeoJSON",
509
+ "Please zoom in to edit the geometry": "لطفاً برای ویرایش هندسه زوم کنید"
508
510
  }
509
511
  L.registerLocale("fa_IR", locale)
510
512
  L.setLocale("fa_IR")