umap-project 2.3.0__py3-none-any.whl → 2.4.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.
- umap/__init__.py +1 -1
- umap/locale/en/LC_MESSAGES/django.po +81 -31
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +117 -66
- umap/locale/pl/LC_MESSAGES/django.mo +0 -0
- umap/locale/pl/LC_MESSAGES/django.po +83 -78
- umap/locale/pt/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt/LC_MESSAGES/django.po +129 -123
- umap/management/commands/run_websocket_server.py +23 -0
- umap/models.py +6 -1
- umap/settings/base.py +11 -3
- umap/static/umap/base.css +68 -186
- umap/static/umap/content.css +3 -2
- umap/static/umap/css/dialog.css +18 -0
- umap/static/umap/css/icon.css +8 -0
- umap/static/umap/css/importers.css +51 -0
- umap/static/umap/css/panel.css +18 -57
- umap/static/umap/css/tooltip.css +59 -0
- umap/static/umap/css/window.css +35 -0
- umap/static/umap/img/16-white.svg +1 -3
- umap/static/umap/img/alert-icon-error.svg +8 -0
- umap/static/umap/img/alert-icon-info.svg +4 -0
- umap/static/umap/img/alert-icon-success.svg +3 -0
- umap/static/umap/img/icon-external-link.svg +3 -0
- umap/static/umap/img/importers/communesfr.svg +5 -0
- umap/static/umap/img/importers/datasets.svg +13 -0
- umap/static/umap/img/importers/geodatamine.svg +10 -0
- umap/static/umap/img/importers/overpass.svg +7 -0
- umap/static/umap/img/importers/random.svg +18 -0
- umap/static/umap/img/importers/random1.svg +4 -0
- umap/static/umap/img/importers/random2.svg +4 -0
- umap/static/umap/img/source/16-white.svg +2 -4
- umap/static/umap/js/components/alerts/alert.css +160 -0
- umap/static/umap/js/components/alerts/alert.js +169 -0
- umap/static/umap/js/components/base.js +54 -0
- umap/static/umap/js/modules/autocomplete.js +347 -0
- umap/static/umap/js/modules/browser.js +14 -21
- umap/static/umap/js/modules/caption.js +119 -0
- umap/static/umap/js/modules/global.js +37 -11
- umap/static/umap/js/modules/help.js +255 -0
- umap/static/umap/js/modules/importer.js +308 -0
- umap/static/umap/js/modules/importers/communesfr.js +44 -0
- umap/static/umap/js/modules/importers/datasets.js +42 -0
- umap/static/umap/js/modules/importers/geodatamine.js +95 -0
- umap/static/umap/js/modules/importers/overpass.js +84 -0
- umap/static/umap/js/modules/request.js +12 -14
- umap/static/umap/js/modules/rules.js +241 -0
- umap/static/umap/js/modules/schema.js +63 -14
- umap/static/umap/js/modules/sync/engine.js +93 -0
- umap/static/umap/js/modules/sync/updaters.js +109 -0
- umap/static/umap/js/modules/sync/websocket.js +25 -0
- umap/static/umap/js/modules/ui/dialog.js +52 -0
- umap/static/umap/js/modules/{panel.js → ui/panel.js} +37 -20
- umap/static/umap/js/modules/ui/tooltip.js +116 -0
- umap/static/umap/js/modules/utils.js +25 -18
- umap/static/umap/js/umap.controls.js +37 -112
- umap/static/umap/js/umap.core.js +1 -327
- umap/static/umap/js/umap.features.js +77 -29
- umap/static/umap/js/umap.forms.js +17 -19
- umap/static/umap/js/umap.js +265 -228
- umap/static/umap/js/umap.layer.js +154 -76
- umap/static/umap/js/umap.permissions.js +5 -9
- umap/static/umap/js/umap.popup.js +2 -1
- umap/static/umap/js/umap.tableeditor.js +8 -8
- umap/static/umap/locale/am_ET.js +51 -16
- umap/static/umap/locale/am_ET.json +51 -16
- umap/static/umap/locale/ar.js +51 -16
- umap/static/umap/locale/ar.json +51 -16
- umap/static/umap/locale/ast.js +51 -16
- umap/static/umap/locale/ast.json +51 -16
- umap/static/umap/locale/bg.js +51 -16
- umap/static/umap/locale/bg.json +51 -16
- umap/static/umap/locale/br.js +55 -20
- umap/static/umap/locale/br.json +55 -20
- umap/static/umap/locale/ca.js +51 -16
- umap/static/umap/locale/ca.json +51 -16
- umap/static/umap/locale/cs_CZ.js +93 -58
- umap/static/umap/locale/cs_CZ.json +93 -58
- umap/static/umap/locale/da.js +51 -16
- umap/static/umap/locale/da.json +51 -16
- umap/static/umap/locale/de.js +56 -21
- umap/static/umap/locale/de.json +56 -21
- umap/static/umap/locale/el.js +51 -16
- umap/static/umap/locale/el.json +51 -16
- umap/static/umap/locale/en.js +52 -16
- umap/static/umap/locale/en.json +52 -16
- umap/static/umap/locale/en_US.json +51 -16
- umap/static/umap/locale/es.js +51 -16
- umap/static/umap/locale/es.json +51 -16
- umap/static/umap/locale/et.js +51 -16
- umap/static/umap/locale/et.json +51 -16
- umap/static/umap/locale/eu.js +51 -16
- umap/static/umap/locale/eu.json +51 -16
- umap/static/umap/locale/fa_IR.js +51 -16
- umap/static/umap/locale/fa_IR.json +51 -16
- umap/static/umap/locale/fi.js +51 -16
- umap/static/umap/locale/fi.json +51 -16
- umap/static/umap/locale/fr.js +61 -25
- umap/static/umap/locale/fr.json +61 -25
- umap/static/umap/locale/gl.js +51 -16
- umap/static/umap/locale/gl.json +51 -16
- umap/static/umap/locale/he.js +51 -16
- umap/static/umap/locale/he.json +51 -16
- umap/static/umap/locale/hr.js +51 -16
- umap/static/umap/locale/hr.json +51 -16
- umap/static/umap/locale/hu.js +51 -16
- umap/static/umap/locale/hu.json +51 -16
- umap/static/umap/locale/id.js +51 -16
- umap/static/umap/locale/id.json +51 -16
- umap/static/umap/locale/is.js +51 -16
- umap/static/umap/locale/is.json +51 -16
- umap/static/umap/locale/it.js +51 -16
- umap/static/umap/locale/it.json +51 -16
- umap/static/umap/locale/ja.js +51 -16
- umap/static/umap/locale/ja.json +51 -16
- umap/static/umap/locale/ko.js +51 -16
- umap/static/umap/locale/ko.json +51 -16
- umap/static/umap/locale/lt.js +51 -16
- umap/static/umap/locale/lt.json +51 -16
- umap/static/umap/locale/ms.js +51 -16
- umap/static/umap/locale/ms.json +51 -16
- umap/static/umap/locale/nl.js +51 -16
- umap/static/umap/locale/nl.json +51 -16
- umap/static/umap/locale/no.js +51 -16
- umap/static/umap/locale/no.json +51 -16
- umap/static/umap/locale/pl.js +93 -58
- umap/static/umap/locale/pl.json +93 -58
- umap/static/umap/locale/pl_PL.json +51 -16
- umap/static/umap/locale/pt.js +215 -180
- umap/static/umap/locale/pt.json +215 -180
- umap/static/umap/locale/pt_BR.js +51 -16
- umap/static/umap/locale/pt_BR.json +51 -16
- umap/static/umap/locale/pt_PT.js +51 -16
- umap/static/umap/locale/pt_PT.json +51 -16
- umap/static/umap/locale/ro.js +51 -16
- umap/static/umap/locale/ro.json +51 -16
- umap/static/umap/locale/ru.js +51 -16
- umap/static/umap/locale/ru.json +51 -16
- umap/static/umap/locale/si.js +51 -16
- umap/static/umap/locale/si.json +51 -16
- umap/static/umap/locale/sk_SK.js +51 -16
- umap/static/umap/locale/sk_SK.json +51 -16
- umap/static/umap/locale/sl.js +51 -16
- umap/static/umap/locale/sl.json +51 -16
- umap/static/umap/locale/sr.js +51 -16
- umap/static/umap/locale/sr.json +51 -16
- umap/static/umap/locale/sv.js +51 -16
- umap/static/umap/locale/sv.json +51 -16
- umap/static/umap/locale/th_TH.js +51 -16
- umap/static/umap/locale/th_TH.json +51 -16
- umap/static/umap/locale/tr.js +51 -16
- umap/static/umap/locale/tr.json +51 -16
- umap/static/umap/locale/uk_UA.js +51 -16
- umap/static/umap/locale/uk_UA.json +51 -16
- umap/static/umap/locale/vi.js +51 -16
- umap/static/umap/locale/vi.json +51 -16
- umap/static/umap/locale/vi_VN.json +51 -16
- umap/static/umap/locale/zh.js +51 -16
- umap/static/umap/locale/zh.json +51 -16
- umap/static/umap/locale/zh_CN.json +51 -16
- umap/static/umap/locale/zh_TW.Big5.json +51 -16
- umap/static/umap/locale/zh_TW.js +51 -16
- umap/static/umap/locale/zh_TW.json +51 -16
- umap/static/umap/map.css +40 -53
- umap/static/umap/unittests/sync.js +105 -0
- umap/static/umap/unittests/utils.js +78 -36
- umap/static/umap/vars.css +19 -1
- umap/static/umap/vendors/dompurify/purify.es.js +50 -15
- umap/static/umap/vendors/dompurify/purify.es.mjs.map +1 -1
- umap/static/umap/vendors/formbuilder/Leaflet.FormBuilder.js +2 -2
- umap/templates/umap/components/alerts/alert.html +89 -0
- umap/templates/umap/content.html +4 -3
- umap/templates/umap/css.html +4 -0
- umap/templates/umap/home.html +3 -0
- umap/templates/umap/js.html +0 -3
- umap/templates/umap/map_init.html +2 -8
- umap/templates/umap/messages.html +9 -11
- umap/templates/umap/search.html +3 -0
- umap/tests/base.py +3 -0
- umap/tests/integration/conftest.py +30 -0
- umap/tests/integration/test_anonymous_owned_map.py +8 -13
- umap/tests/integration/test_browser.py +81 -6
- umap/tests/integration/test_caption.py +27 -0
- umap/tests/integration/test_conditional_rules.py +201 -0
- umap/tests/integration/test_dashboard.py +1 -1
- umap/tests/integration/test_datalayer.py +2 -3
- umap/tests/integration/test_edit_datalayer.py +32 -3
- umap/tests/integration/test_edit_map.py +1 -1
- umap/tests/integration/test_facets_browser.py +7 -4
- umap/tests/integration/test_import.py +185 -49
- umap/tests/integration/test_map.py +31 -17
- umap/tests/integration/{test_collaborative_editing.py → test_optimistic_merge.py} +7 -7
- umap/tests/integration/test_owned_map.py +1 -1
- umap/tests/integration/test_picto.py +2 -2
- umap/tests/integration/test_statics.py +1 -1
- umap/tests/integration/test_view_marker.py +19 -2
- umap/tests/integration/test_websocket_sync.py +283 -0
- umap/tests/settings.py +5 -0
- umap/tests/test_datalayer_views.py +0 -1
- umap/tests/test_views.py +53 -0
- umap/urls.py +5 -0
- umap/views.py +40 -11
- umap/websocket_server.py +92 -0
- {umap_project-2.3.0.dist-info → umap_project-2.4.0.dist-info}/METADATA +13 -11
- {umap_project-2.3.0.dist-info → umap_project-2.4.0.dist-info}/RECORD +208 -172
- umap/static/umap/js/umap.autocomplete.js +0 -341
- umap/static/umap/js/umap.importer.js +0 -187
- umap/static/umap/js/umap.ui.js +0 -190
- {umap_project-2.3.0.dist-info → umap_project-2.4.0.dist-info}/WHEEL +0 -0
- {umap_project-2.3.0.dist-info → umap_project-2.4.0.dist-info}/entry_points.txt +0 -0
- {umap_project-2.3.0.dist-info → umap_project-2.4.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -60,6 +60,9 @@ U.Layer.Cluster = L.MarkerClusterGroup.extend({
|
|
|
60
60
|
|
|
61
61
|
initialize: function (datalayer) {
|
|
62
62
|
this.datalayer = datalayer
|
|
63
|
+
if (!U.Utils.isObject(this.datalayer.options.cluster)) {
|
|
64
|
+
this.datalayer.options.cluster = {}
|
|
65
|
+
}
|
|
63
66
|
const options = {
|
|
64
67
|
polygonOptions: {
|
|
65
68
|
color: this.datalayer.getColor(),
|
|
@@ -97,9 +100,6 @@ U.Layer.Cluster = L.MarkerClusterGroup.extend({
|
|
|
97
100
|
},
|
|
98
101
|
|
|
99
102
|
getEditableOptions: function () {
|
|
100
|
-
if (!U.Utils.isObject(this.datalayer.options.cluster)) {
|
|
101
|
-
this.datalayer.options.cluster = {}
|
|
102
|
-
}
|
|
103
103
|
return [
|
|
104
104
|
[
|
|
105
105
|
'options.cluster.radius',
|
|
@@ -179,12 +179,18 @@ U.Layer.Choropleth = L.FeatureGroup.extend({
|
|
|
179
179
|
return +feature.properties[key] // TODO: should we catch values non castable to int ?
|
|
180
180
|
},
|
|
181
181
|
|
|
182
|
-
|
|
182
|
+
getValues: function () {
|
|
183
183
|
const values = []
|
|
184
184
|
this.datalayer.eachLayer((layer) => {
|
|
185
185
|
let value = this._getValue(layer)
|
|
186
186
|
if (!isNaN(value)) values.push(value)
|
|
187
187
|
})
|
|
188
|
+
return values
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
computeBreaks: function () {
|
|
192
|
+
const values = this.getValues()
|
|
193
|
+
|
|
188
194
|
if (!values.length) {
|
|
189
195
|
this.options.breaks = []
|
|
190
196
|
this.options.colors = []
|
|
@@ -351,6 +357,9 @@ U.Layer.Heat = L.HeatLayer.extend({
|
|
|
351
357
|
initialize: function (datalayer) {
|
|
352
358
|
this.datalayer = datalayer
|
|
353
359
|
L.HeatLayer.prototype.initialize.call(this, [], this.datalayer.options.heat)
|
|
360
|
+
if (!U.Utils.isObject(this.datalayer.options.heat)) {
|
|
361
|
+
this.datalayer.options.heat = {}
|
|
362
|
+
}
|
|
354
363
|
},
|
|
355
364
|
|
|
356
365
|
addLayer: function (layer) {
|
|
@@ -383,9 +392,6 @@ U.Layer.Heat = L.HeatLayer.extend({
|
|
|
383
392
|
},
|
|
384
393
|
|
|
385
394
|
getEditableOptions: function () {
|
|
386
|
-
if (!U.Utils.isObject(this.datalayer.options.heat)) {
|
|
387
|
-
this.datalayer.options.heat = {}
|
|
388
|
-
}
|
|
389
395
|
return [
|
|
390
396
|
[
|
|
391
397
|
'options.heat.radius',
|
|
@@ -517,6 +523,7 @@ U.DataLayer = L.Evented.extend({
|
|
|
517
523
|
|
|
518
524
|
initialize: function (map, data) {
|
|
519
525
|
this.map = map
|
|
526
|
+
this.sync = map.sync_engine.proxy(this)
|
|
520
527
|
this._index = Array()
|
|
521
528
|
this._layers = {}
|
|
522
529
|
this._geojson = null
|
|
@@ -570,6 +577,10 @@ U.DataLayer = L.Evented.extend({
|
|
|
570
577
|
}
|
|
571
578
|
this.setUmapId(data.id)
|
|
572
579
|
this.setOptions(data)
|
|
580
|
+
|
|
581
|
+
if (!U.Utils.isObject(this.options.remoteData)) {
|
|
582
|
+
this.options.remoteData = {}
|
|
583
|
+
}
|
|
573
584
|
// Retrocompat
|
|
574
585
|
if (this.options.remoteData && this.options.remoteData.from) {
|
|
575
586
|
this.options.fromZoom = this.options.remoteData.from
|
|
@@ -597,6 +608,15 @@ U.DataLayer = L.Evented.extend({
|
|
|
597
608
|
this.on('datachanged', this.map.onDataLayersChanged, this.map)
|
|
598
609
|
},
|
|
599
610
|
|
|
611
|
+
getSyncMetadata: function () {
|
|
612
|
+
return {
|
|
613
|
+
subject: 'datalayer',
|
|
614
|
+
metadata: {
|
|
615
|
+
id: this.umap_id || null,
|
|
616
|
+
},
|
|
617
|
+
}
|
|
618
|
+
},
|
|
619
|
+
|
|
600
620
|
render: function (fields, builder) {
|
|
601
621
|
let impacts = U.Utils.getImpactsFromSchema(fields)
|
|
602
622
|
|
|
@@ -613,6 +633,7 @@ U.DataLayer = L.Evented.extend({
|
|
|
613
633
|
fields.forEach((field) => {
|
|
614
634
|
this.layer.onEdit(field, builder)
|
|
615
635
|
})
|
|
636
|
+
this.redraw()
|
|
616
637
|
this.show()
|
|
617
638
|
break
|
|
618
639
|
case 'remote-data':
|
|
@@ -863,10 +884,10 @@ U.DataLayer = L.Evented.extend({
|
|
|
863
884
|
},
|
|
864
885
|
|
|
865
886
|
isRemoteLayer: function () {
|
|
866
|
-
return
|
|
887
|
+
return Boolean(
|
|
867
888
|
this.options.remoteData &&
|
|
868
|
-
|
|
869
|
-
|
|
889
|
+
this.options.remoteData.url &&
|
|
890
|
+
this.options.remoteData.format
|
|
870
891
|
)
|
|
871
892
|
},
|
|
872
893
|
|
|
@@ -933,7 +954,14 @@ U.DataLayer = L.Evented.extend({
|
|
|
933
954
|
},
|
|
934
955
|
|
|
935
956
|
rawToGeoJSON: function (c, type, callback) {
|
|
936
|
-
const toDom = (x) =>
|
|
957
|
+
const toDom = (x) => {
|
|
958
|
+
const doc = new DOMParser().parseFromString(x, 'text/xml')
|
|
959
|
+
const errorNode = doc.querySelector('parsererror')
|
|
960
|
+
if (errorNode) {
|
|
961
|
+
U.Alert.error(L._('Cannot parse data'))
|
|
962
|
+
}
|
|
963
|
+
return doc
|
|
964
|
+
}
|
|
937
965
|
|
|
938
966
|
// TODO add a duck typing guessType
|
|
939
967
|
if (type === 'csv') {
|
|
@@ -965,7 +993,7 @@ U.DataLayer = L.Evented.extend({
|
|
|
965
993
|
message: err[0].message,
|
|
966
994
|
})
|
|
967
995
|
}
|
|
968
|
-
|
|
996
|
+
U.Alert.error(message, 10000)
|
|
969
997
|
console.error(err)
|
|
970
998
|
}
|
|
971
999
|
if (result && result.features.length) {
|
|
@@ -992,33 +1020,67 @@ U.DataLayer = L.Evented.extend({
|
|
|
992
1020
|
const gj = JSON.parse(c)
|
|
993
1021
|
callback(gj)
|
|
994
1022
|
} catch (err) {
|
|
995
|
-
|
|
1023
|
+
U.Alert.error(`Invalid JSON file: ${err}`)
|
|
996
1024
|
return
|
|
997
1025
|
}
|
|
998
1026
|
}
|
|
999
1027
|
},
|
|
1000
1028
|
|
|
1029
|
+
// The choice of the name is not ours, because it is required by Leaflet.
|
|
1030
|
+
// It is misleading, as the returned objects are uMap objects, and not
|
|
1031
|
+
// GeoJSON features.
|
|
1001
1032
|
geojsonToFeatures: function (geojson) {
|
|
1002
1033
|
if (!geojson) return
|
|
1003
1034
|
const features = geojson instanceof Array ? geojson : geojson.features
|
|
1004
1035
|
let i
|
|
1005
1036
|
let len
|
|
1006
|
-
let latlng
|
|
1007
|
-
let latlngs
|
|
1008
1037
|
|
|
1009
1038
|
if (features) {
|
|
1010
1039
|
U.Utils.sortFeatures(features, this.map.getOption('sortKey'), L.lang)
|
|
1011
1040
|
for (i = 0, len = features.length; i < len; i++) {
|
|
1012
1041
|
this.geojsonToFeatures(features[i])
|
|
1013
1042
|
}
|
|
1014
|
-
return this
|
|
1043
|
+
return this // Why returning "this" ?
|
|
1015
1044
|
}
|
|
1016
1045
|
|
|
1017
1046
|
const geometry = geojson.type === 'Feature' ? geojson.geometry : geojson
|
|
1047
|
+
|
|
1048
|
+
let feature = this.geoJSONToLeaflet({ geometry, geojson })
|
|
1049
|
+
if (feature) {
|
|
1050
|
+
this.addLayer(feature)
|
|
1051
|
+
feature.onCommit()
|
|
1052
|
+
return feature
|
|
1053
|
+
}
|
|
1054
|
+
},
|
|
1055
|
+
|
|
1056
|
+
/**
|
|
1057
|
+
* Create or update Leaflet features from GeoJSON geometries.
|
|
1058
|
+
*
|
|
1059
|
+
* If no `feature` is provided, a new feature will be created.
|
|
1060
|
+
* If `feature` is provided, it will be updated with the passed geometry.
|
|
1061
|
+
*
|
|
1062
|
+
* GeoJSON and Leaflet use incompatible formats to encode coordinates.
|
|
1063
|
+
* This method takes care of the convertion.
|
|
1064
|
+
*
|
|
1065
|
+
* @param geometry GeoJSON geometry field
|
|
1066
|
+
* @param geojson Enclosing GeoJSON. If none is provided, a new one will
|
|
1067
|
+
* be created
|
|
1068
|
+
* @param id Id of the feature
|
|
1069
|
+
* @param feature Leaflet feature that should be updated with the new geometry
|
|
1070
|
+
* @returns Leaflet feature.
|
|
1071
|
+
*/
|
|
1072
|
+
geoJSONToLeaflet: function ({
|
|
1073
|
+
geometry,
|
|
1074
|
+
geojson = null,
|
|
1075
|
+
id = null,
|
|
1076
|
+
feature = null,
|
|
1077
|
+
} = {}) {
|
|
1018
1078
|
if (!geometry) return // null geometry is valid geojson.
|
|
1019
1079
|
const coords = geometry.coordinates
|
|
1020
|
-
let
|
|
1021
|
-
|
|
1080
|
+
let latlng, latlngs
|
|
1081
|
+
|
|
1082
|
+
// Create a default geojson if none is provided
|
|
1083
|
+
if (geojson === undefined) geojson = { type: 'Feature', geometry: geometry }
|
|
1022
1084
|
|
|
1023
1085
|
switch (geometry.type) {
|
|
1024
1086
|
case 'Point':
|
|
@@ -1028,8 +1090,11 @@ U.DataLayer = L.Evented.extend({
|
|
|
1028
1090
|
console.error('Invalid latlng object from', coords)
|
|
1029
1091
|
break
|
|
1030
1092
|
}
|
|
1031
|
-
|
|
1032
|
-
|
|
1093
|
+
if (feature) {
|
|
1094
|
+
feature.setLatLng(latlng)
|
|
1095
|
+
return feature
|
|
1096
|
+
}
|
|
1097
|
+
return this._pointToLayer(geojson, latlng, id)
|
|
1033
1098
|
|
|
1034
1099
|
case 'MultiLineString':
|
|
1035
1100
|
case 'LineString':
|
|
@@ -1038,49 +1103,55 @@ U.DataLayer = L.Evented.extend({
|
|
|
1038
1103
|
geometry.type === 'LineString' ? 0 : 1
|
|
1039
1104
|
)
|
|
1040
1105
|
if (!latlngs.length) break
|
|
1041
|
-
|
|
1042
|
-
|
|
1106
|
+
if (feature) {
|
|
1107
|
+
feature.setLatLngs(latlngs)
|
|
1108
|
+
return feature
|
|
1109
|
+
}
|
|
1110
|
+
return this._lineToLayer(geojson, latlngs, id)
|
|
1043
1111
|
|
|
1044
1112
|
case 'MultiPolygon':
|
|
1045
1113
|
case 'Polygon':
|
|
1046
1114
|
latlngs = L.GeoJSON.coordsToLatLngs(coords, geometry.type === 'Polygon' ? 1 : 2)
|
|
1047
|
-
|
|
1048
|
-
|
|
1115
|
+
if (feature) {
|
|
1116
|
+
feature.setLatLngs(latlngs)
|
|
1117
|
+
return feature
|
|
1118
|
+
}
|
|
1119
|
+
return this._polygonToLayer(geojson, latlngs, id)
|
|
1049
1120
|
case 'GeometryCollection':
|
|
1050
1121
|
return this.geojsonToFeatures(geometry.geometries)
|
|
1051
1122
|
|
|
1052
1123
|
default:
|
|
1053
|
-
|
|
1054
|
-
|
|
1124
|
+
U.Alert.error(
|
|
1125
|
+
L._('Skipping unknown geometry.type: {type}', {
|
|
1055
1126
|
type: geometry.type || 'undefined',
|
|
1056
|
-
})
|
|
1057
|
-
|
|
1058
|
-
})
|
|
1059
|
-
}
|
|
1060
|
-
if (layer) {
|
|
1061
|
-
this.addLayer(layer)
|
|
1062
|
-
return layer
|
|
1127
|
+
})
|
|
1128
|
+
)
|
|
1063
1129
|
}
|
|
1064
1130
|
},
|
|
1065
1131
|
|
|
1066
|
-
_pointToLayer: function (geojson, latlng) {
|
|
1067
|
-
return new U.Marker(this.map, latlng, { geojson: geojson, datalayer: this })
|
|
1132
|
+
_pointToLayer: function (geojson, latlng, id) {
|
|
1133
|
+
return new U.Marker(this.map, latlng, { geojson: geojson, datalayer: this }, id)
|
|
1068
1134
|
},
|
|
1069
1135
|
|
|
1070
|
-
_lineToLayer: function (geojson, latlngs) {
|
|
1071
|
-
return new U.Polyline(
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1136
|
+
_lineToLayer: function (geojson, latlngs, id) {
|
|
1137
|
+
return new U.Polyline(
|
|
1138
|
+
this.map,
|
|
1139
|
+
latlngs,
|
|
1140
|
+
{
|
|
1141
|
+
geojson: geojson,
|
|
1142
|
+
datalayer: this,
|
|
1143
|
+
color: null,
|
|
1144
|
+
},
|
|
1145
|
+
id
|
|
1146
|
+
)
|
|
1076
1147
|
},
|
|
1077
1148
|
|
|
1078
|
-
_polygonToLayer: function (geojson, latlngs) {
|
|
1149
|
+
_polygonToLayer: function (geojson, latlngs, id) {
|
|
1079
1150
|
// Ensure no empty hole
|
|
1080
1151
|
// for (let i = latlngs.length - 1; i > 0; i--) {
|
|
1081
1152
|
// if (!latlngs.slice()[i].length) latlngs.splice(i, 1);
|
|
1082
1153
|
// }
|
|
1083
|
-
return new U.Polygon(this.map, latlngs, { geojson: geojson, datalayer: this })
|
|
1154
|
+
return new U.Polygon(this.map, latlngs, { geojson: geojson, datalayer: this }, id)
|
|
1084
1155
|
},
|
|
1085
1156
|
|
|
1086
1157
|
importRaw: function (raw, type) {
|
|
@@ -1301,9 +1372,12 @@ U.DataLayer = L.Evented.extend({
|
|
|
1301
1372
|
)
|
|
1302
1373
|
popupFieldset.appendChild(builder.build())
|
|
1303
1374
|
|
|
1375
|
+
// XXX I'm not sure **why** this is needed (as it's set during `this.initialize`)
|
|
1376
|
+
// but apparently it's needed.
|
|
1304
1377
|
if (!U.Utils.isObject(this.options.remoteData)) {
|
|
1305
1378
|
this.options.remoteData = {}
|
|
1306
1379
|
}
|
|
1380
|
+
|
|
1307
1381
|
const remoteDataFields = [
|
|
1308
1382
|
[
|
|
1309
1383
|
'options.remoteData.url',
|
|
@@ -1333,10 +1407,7 @@ U.DataLayer = L.Evented.extend({
|
|
|
1333
1407
|
helpEntries: 'proxyRemoteData',
|
|
1334
1408
|
},
|
|
1335
1409
|
])
|
|
1336
|
-
remoteDataFields.push(
|
|
1337
|
-
'options.remoteData.ttl',
|
|
1338
|
-
{ handler: 'ProxyTTLSelect', label: L._('Cache proxied request') },
|
|
1339
|
-
])
|
|
1410
|
+
remoteDataFields.push('options.remoteData.ttl')
|
|
1340
1411
|
}
|
|
1341
1412
|
|
|
1342
1413
|
const remoteDataContainer = L.DomUtil.createFieldset(container, L._('Remote data'))
|
|
@@ -1392,17 +1463,19 @@ U.DataLayer = L.Evented.extend({
|
|
|
1392
1463
|
'_blank'
|
|
1393
1464
|
)
|
|
1394
1465
|
}
|
|
1395
|
-
const
|
|
1396
|
-
|
|
1397
|
-
|
|
1466
|
+
const backButton = L.DomUtil.createButtonIcon(
|
|
1467
|
+
undefined,
|
|
1468
|
+
'icon-back',
|
|
1469
|
+
L._('Back to layers')
|
|
1470
|
+
)
|
|
1398
1471
|
// Fixme: remove me when this is merged and released
|
|
1399
1472
|
// https://github.com/Leaflet/Leaflet/pull/9052
|
|
1400
|
-
L.DomEvent.disableClickPropagation(
|
|
1401
|
-
L.DomEvent.on(
|
|
1473
|
+
L.DomEvent.disableClickPropagation(backButton)
|
|
1474
|
+
L.DomEvent.on(backButton, 'click', this.map.editDatalayers, this.map)
|
|
1402
1475
|
|
|
1403
1476
|
this.map.editPanel.open({
|
|
1404
1477
|
content: container,
|
|
1405
|
-
actions: [
|
|
1478
|
+
actions: [backButton],
|
|
1406
1479
|
})
|
|
1407
1480
|
},
|
|
1408
1481
|
|
|
@@ -1420,7 +1493,7 @@ U.DataLayer = L.Evented.extend({
|
|
|
1420
1493
|
} else if (this.layer && this.layer.defaults && this.layer.defaults[option]) {
|
|
1421
1494
|
return this.layer.defaults[option]
|
|
1422
1495
|
} else {
|
|
1423
|
-
return this.map.getOption(option)
|
|
1496
|
+
return this.map.getOption(option, feature)
|
|
1424
1497
|
}
|
|
1425
1498
|
},
|
|
1426
1499
|
|
|
@@ -1528,7 +1601,7 @@ U.DataLayer = L.Evented.extend({
|
|
|
1528
1601
|
},
|
|
1529
1602
|
|
|
1530
1603
|
isVisible: function () {
|
|
1531
|
-
return this.layer && this.map.hasLayer(this.layer)
|
|
1604
|
+
return Boolean(this.layer && this.map.hasLayer(this.layer))
|
|
1532
1605
|
},
|
|
1533
1606
|
|
|
1534
1607
|
getFeatureByIndex: function (index) {
|
|
@@ -1537,6 +1610,12 @@ U.DataLayer = L.Evented.extend({
|
|
|
1537
1610
|
return this._layers[id]
|
|
1538
1611
|
},
|
|
1539
1612
|
|
|
1613
|
+
// TODO Add an index
|
|
1614
|
+
// For now, iterate on all the features.
|
|
1615
|
+
getFeatureById: function (id) {
|
|
1616
|
+
return Object.values(this._layers).find((feature) => feature.id === id)
|
|
1617
|
+
},
|
|
1618
|
+
|
|
1540
1619
|
getNextFeature: function (feature) {
|
|
1541
1620
|
const id = this._index.indexOf(L.stamp(feature))
|
|
1542
1621
|
const nextId = this._index[id + 1]
|
|
@@ -1625,28 +1704,15 @@ U.DataLayer = L.Evented.extend({
|
|
|
1625
1704
|
const [data, response, error] = await this.map.server.post(url, headers, formData)
|
|
1626
1705
|
if (error) {
|
|
1627
1706
|
if (response && response.status === 412) {
|
|
1628
|
-
|
|
1629
|
-
|
|
1707
|
+
U.AlertConflict.error(
|
|
1708
|
+
L._(
|
|
1709
|
+
'Whoops! Other contributor(s) changed some of the same map elements as you. ' +
|
|
1710
|
+
'This situation is tricky, you have to choose carefully which version is pertinent.'
|
|
1711
|
+
),
|
|
1712
|
+
async () => {
|
|
1713
|
+
await this._trySave(url, {}, formData)
|
|
1714
|
+
}
|
|
1630
1715
|
)
|
|
1631
|
-
const actions = [
|
|
1632
|
-
{
|
|
1633
|
-
label: L._('Save anyway'),
|
|
1634
|
-
callback: async () => {
|
|
1635
|
-
// Save again,
|
|
1636
|
-
// but do not pass the reference version this time
|
|
1637
|
-
await this._trySave(url, {}, formData)
|
|
1638
|
-
},
|
|
1639
|
-
},
|
|
1640
|
-
{
|
|
1641
|
-
label: L._('Cancel'),
|
|
1642
|
-
},
|
|
1643
|
-
]
|
|
1644
|
-
this.map.ui.alert({
|
|
1645
|
-
content: msg,
|
|
1646
|
-
level: 'error',
|
|
1647
|
-
duration: 100000,
|
|
1648
|
-
actions: actions,
|
|
1649
|
-
})
|
|
1650
1716
|
}
|
|
1651
1717
|
} else {
|
|
1652
1718
|
// Response contains geojson only if save has conflicted and conflicts have
|
|
@@ -1657,6 +1723,8 @@ U.DataLayer = L.Evented.extend({
|
|
|
1657
1723
|
delete data.geojson
|
|
1658
1724
|
}
|
|
1659
1725
|
this._reference_version = response.headers.get('X-Datalayer-Version')
|
|
1726
|
+
this.sync.update('_reference_version', this._reference_version)
|
|
1727
|
+
|
|
1660
1728
|
this.setUmapId(data.id)
|
|
1661
1729
|
this.updateOptions(data)
|
|
1662
1730
|
this.backupOptions()
|
|
@@ -1689,6 +1757,16 @@ U.DataLayer = L.Evented.extend({
|
|
|
1689
1757
|
const editor = new U.TableEditor(this)
|
|
1690
1758
|
editor.edit()
|
|
1691
1759
|
},
|
|
1760
|
+
|
|
1761
|
+
getFilterKeys: function () {
|
|
1762
|
+
// This keys will be used to filter feature from the browser text input.
|
|
1763
|
+
// By default, it will we use the "name" property, which is also the one used as label in the features list.
|
|
1764
|
+
// When map owner has configured another label or sort key, we try to be smart and search in the same keys.
|
|
1765
|
+
if (this.map.options.filterKey) return this.map.options.filterKey
|
|
1766
|
+
else if (this.options.labelKey) return this.options.labelKey
|
|
1767
|
+
else if (this.map.options.sortKey) return this.map.options.sortKey
|
|
1768
|
+
else return 'name'
|
|
1769
|
+
},
|
|
1692
1770
|
})
|
|
1693
1771
|
|
|
1694
1772
|
L.TileLayer.include({
|
|
@@ -52,11 +52,9 @@ U.MapPermissions = L.Class.extend({
|
|
|
52
52
|
|
|
53
53
|
edit: function () {
|
|
54
54
|
if (this.map.options.editMode !== 'advanced') return
|
|
55
|
-
if (!this.map.options.umap_id)
|
|
56
|
-
return
|
|
57
|
-
|
|
58
|
-
level: 'info',
|
|
59
|
-
})
|
|
55
|
+
if (!this.map.options.umap_id) {
|
|
56
|
+
return U.Alert.info(L._('Please save the map first'))
|
|
57
|
+
}
|
|
60
58
|
const container = L.DomUtil.create('div', 'permissions-panel')
|
|
61
59
|
const fields = []
|
|
62
60
|
L.DomUtil.createTitle(container, L._('Update permissions'), 'icon-key')
|
|
@@ -109,6 +107,7 @@ U.MapPermissions = L.Class.extend({
|
|
|
109
107
|
{ handler: 'ManageEditors', label: L._("Map's editors") },
|
|
110
108
|
])
|
|
111
109
|
}
|
|
110
|
+
|
|
112
111
|
const builder = new U.FormBuilder(this, fields)
|
|
113
112
|
const form = builder.build()
|
|
114
113
|
container.appendChild(form)
|
|
@@ -139,10 +138,7 @@ U.MapPermissions = L.Class.extend({
|
|
|
139
138
|
const [data, response, error] = await this.map.server.post(this.getAttachUrl())
|
|
140
139
|
if (!error) {
|
|
141
140
|
this.options.owner = this.map.options.user
|
|
142
|
-
|
|
143
|
-
content: L._('Map has been attached to your account'),
|
|
144
|
-
level: 'info',
|
|
145
|
-
})
|
|
141
|
+
U.Alert.success(L._('Map has been attached to your account'))
|
|
146
142
|
this.map.editPanel.close()
|
|
147
143
|
}
|
|
148
144
|
},
|
|
@@ -55,6 +55,7 @@ U.Popup.Panel = U.Popup.extend({
|
|
|
55
55
|
},
|
|
56
56
|
|
|
57
57
|
onAdd: function (map) {
|
|
58
|
+
map.panel.setDefaultMode('expanded')
|
|
58
59
|
map.panel.open({
|
|
59
60
|
content: this._content,
|
|
60
61
|
actions: [U.Browser.backButton(map)],
|
|
@@ -106,7 +107,7 @@ U.PopupTemplate.Default = L.Class.extend({
|
|
|
106
107
|
renderBody: function () {
|
|
107
108
|
const template = this.feature.getOption('popupContentTemplate')
|
|
108
109
|
const target = this.feature.getOption('outlinkTarget')
|
|
109
|
-
const container = L.DomUtil.create('div', 'umap-popup-container')
|
|
110
|
+
const container = L.DomUtil.create('div', 'umap-popup-container text')
|
|
110
111
|
let content = ''
|
|
111
112
|
let properties
|
|
112
113
|
let center
|
|
@@ -83,10 +83,7 @@ U.TableEditor = L.Class.extend({
|
|
|
83
83
|
|
|
84
84
|
validateName: function (name) {
|
|
85
85
|
if (name.indexOf('.') !== -1) {
|
|
86
|
-
|
|
87
|
-
content: L._('Invalide property name: {name}', { name: name }),
|
|
88
|
-
level: 'error',
|
|
89
|
-
})
|
|
86
|
+
U.Alert.error(L._('Invalide property name: {name}', { name: name }))
|
|
90
87
|
return false
|
|
91
88
|
}
|
|
92
89
|
return true
|
|
@@ -98,10 +95,13 @@ U.TableEditor = L.Class.extend({
|
|
|
98
95
|
this.renderHeaders()
|
|
99
96
|
this.body.innerHTML = ''
|
|
100
97
|
this.datalayer.eachLayer(this.renderRow, this)
|
|
101
|
-
const addButton = L.DomUtil.
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
98
|
+
const addButton = L.DomUtil.createButton(
|
|
99
|
+
'flat',
|
|
100
|
+
undefined,
|
|
101
|
+
L._('Add a new property')
|
|
102
|
+
)
|
|
103
|
+
const iconElement = L.DomUtil.createIcon(addButton, 'icon-add')
|
|
104
|
+
addButton.insertBefore(iconElement, addButton.firstChild)
|
|
105
105
|
const addProperty = function () {
|
|
106
106
|
const newName = prompt(L._('Please enter the name of the property'))
|
|
107
107
|
if (!newName || !this.validateName(newName)) return
|
umap/static/umap/locale/am_ET.js
CHANGED
|
@@ -48,16 +48,12 @@ const locale = {
|
|
|
48
48
|
"by": "በ",
|
|
49
49
|
"Cache proxied request": "Cache proxied request",
|
|
50
50
|
"Cancel edits": "እርማቶችን ሰርዝ",
|
|
51
|
-
"Cancel": "አቁም/ሰርዝ",
|
|
52
51
|
"Caption": "ካፕሽን",
|
|
53
52
|
"Center map on your location": "መገኛዎን የሚያሳየውን ካርታ ወደ መሀል ያድርጉ",
|
|
54
53
|
"Change map background": "የካርታውን የጀርባ ገፅታ ይቀይሩ",
|
|
55
54
|
"Change tilelayers": "የታይልሌየሩን",
|
|
56
55
|
"Change": "Change",
|
|
57
|
-
"Choose a preset": "ፕሪሴት ምረጥ",
|
|
58
56
|
"Choose the data format": "የረጃውን ፎርማት ቀይር",
|
|
59
|
-
"Choose the format of the data to import": "ሊያመጡ የፈለጉትን የመረጃ ፎርማት ይምረጡ",
|
|
60
|
-
"Choose the layer to import in": "የሚያስገቡበት ሌየር ይምረጡ",
|
|
61
57
|
"Choropleth breakpoints": "Choropleth breakpoints",
|
|
62
58
|
"Choropleth classes": "Choropleth classes",
|
|
63
59
|
"Choropleth color palette": "Choropleth color palette",
|
|
@@ -87,7 +83,6 @@ const locale = {
|
|
|
87
83
|
"Congratulations, your map has been created!": "Congratulations, your map has been created!",
|
|
88
84
|
"Continue line": "መስመሩን ቀጥል",
|
|
89
85
|
"Coordinates": "ኮርዲኔቶች",
|
|
90
|
-
"Copy link": "Copy link",
|
|
91
86
|
"copy": "copy",
|
|
92
87
|
"Credits": "ክሬዲቶች",
|
|
93
88
|
"Current map view": "Current map view",
|
|
@@ -152,7 +147,6 @@ const locale = {
|
|
|
152
147
|
"Edit the title of the map": "Edit the title of the map",
|
|
153
148
|
"Edit this feature": "ይህንን ፊቸር አርም",
|
|
154
149
|
"Edit": "አርም",
|
|
155
|
-
"Email": "Email",
|
|
156
150
|
"Embed and link options": "Embed and link options",
|
|
157
151
|
"Embed the map": "ካርታውን አካትት",
|
|
158
152
|
"Emoji & Character": "Emoji & Character",
|
|
@@ -200,7 +194,6 @@ const locale = {
|
|
|
200
194
|
"Image: {{http://image.url.com}}": "ምስል፡{{http://image.url.com}}",
|
|
201
195
|
"Import data": "መረጃ አምጣ",
|
|
202
196
|
"Import in a new layer": "አዲስ ሌየር አምጣ",
|
|
203
|
-
"Import": "አምጣ",
|
|
204
197
|
"Imports all umap data, including layers and settings.": "ሌየር እና ሁኔታዎቹን ጨምሮ ሁሉንም የዩማፕ መረጃ ያመጣል",
|
|
205
198
|
"Include full screen link?": "ሙሉ ስክሪን ሊክን ያካትት?",
|
|
206
199
|
"Inherit": "ውረስ",
|
|
@@ -311,7 +304,6 @@ const locale = {
|
|
|
311
304
|
"Rename this property on all the features": "በሁሉም ፊቸሮች ይህንን ያባህርይ መጠሪያ ያሻሽሉ",
|
|
312
305
|
"Replace layer content": "Replace layer content",
|
|
313
306
|
"Restore this version": "ይህንን እትም መልስ",
|
|
314
|
-
"Save anyway": "ለማንኛውም አስቀምጥ/አድን",
|
|
315
307
|
"Save current edits": "የአሁኑን እርማቶች አስቀምጥ/አድን",
|
|
316
308
|
"Save map": "Save map",
|
|
317
309
|
"Save this center and zoom": "ይህንን ዙም እና መሀከል አስቀምጥ/አድን",
|
|
@@ -320,12 +312,9 @@ const locale = {
|
|
|
320
312
|
"Saved center and zoom": "Saved center and zoom",
|
|
321
313
|
"Search location": "Search location",
|
|
322
314
|
"Search": "Search",
|
|
323
|
-
"Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!",
|
|
324
315
|
"Secret edit link:": "Secret edit link:",
|
|
325
|
-
"See layers": "See layers",
|
|
326
316
|
"See full screen": "ሙሉውን ስክሪን ተመልከት",
|
|
327
317
|
"See on OpenStreetMap": "See on OpenStreetMap",
|
|
328
|
-
"Send me the link": "Send me the link",
|
|
329
318
|
"Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…",
|
|
330
319
|
"settings": "settings",
|
|
331
320
|
"Shape properties": "Shape properties",
|
|
@@ -398,9 +387,7 @@ const locale = {
|
|
|
398
387
|
"Will be displayed in the bottom right corner of the map": "ከታች በቀኝ ኮርነሩ ላይ ይታያል",
|
|
399
388
|
"Will be permanently visible in the bottom left corner of the map": "Will be permanently visible in the bottom left corner of the map",
|
|
400
389
|
"Will be visible in the caption of the map": "በካርታው ካፕሽን ላይ እንዲታይ ይደረጋል",
|
|
401
|
-
"Woops! Someone else seems to have edited the data. You can save anyway, but this will erase the changes made by others.": "ውይ! ሌላ ሰው መረጃውን ሳያርመው አይቀርም። ለማንኛውም ማዳን/ማስቀመጥ ይቻላል፣ ነገር ግን የሌሎች እርማቶች ይሰረዛሉ",
|
|
402
390
|
"yes": "አዎን",
|
|
403
|
-
"Your map has been created! As you are not logged in, here is your secret link to edit the map, please keep it safe:": "Your map has been created! As you are not logged in, here is your secret link to edit the map, please keep it safe:",
|
|
404
391
|
"Zoom in": "አጉላ",
|
|
405
392
|
"Zoom level for automatic zooms": "አውቶማቲክ ዙሞች የሚጎሉበት መጠን",
|
|
406
393
|
"Zoom out": "አርቅ",
|
|
@@ -444,9 +431,57 @@ const locale = {
|
|
|
444
431
|
"Filter data": "Filter data",
|
|
445
432
|
"Search map features…": "Search map features…",
|
|
446
433
|
"Reset all": "Reset all",
|
|
447
|
-
"
|
|
448
|
-
"
|
|
449
|
-
"
|
|
434
|
+
"Open browser": "Open browser",
|
|
435
|
+
"Open caption": "Open caption",
|
|
436
|
+
"Your map has been created with an anonymous account!": "Your map has been created with an anonymous account!",
|
|
437
|
+
"Real-time collaboration": "Real-time collaboration",
|
|
438
|
+
"Cannot parse data": "Cannot parse data",
|
|
439
|
+
"Start typing...": "Start typing...",
|
|
440
|
+
"No result": "No result",
|
|
441
|
+
"Data browser": "Data browser",
|
|
442
|
+
"When providing an URL, uMap can copy the remote data in a layer, or add this URL as remote source of the layer. In that case, data will always be fetched from that URL, and thus be up to date, but it will not be possible to edit it inside uMap.": "When providing an URL, uMap can copy the remote data in a layer, or add this URL as remote source of the layer. In that case, data will always be fetched from that URL, and thus be up to date, but it will not be possible to edit it inside uMap.",
|
|
443
|
+
"Overpass supported expressions": "Overpass supported expressions",
|
|
444
|
+
"key (eg. building)": "key (eg. building)",
|
|
445
|
+
"!key (eg. !name)": "!key (eg. !name)",
|
|
446
|
+
"key=value (eg. building=yes)": "key=value (eg. building=yes)",
|
|
447
|
+
"key!=value (eg. building!=yes)": "key!=value (eg. building!=yes)",
|
|
448
|
+
"key~value (eg. name~Grisy)": "key~value (eg. name~Grisy)",
|
|
449
|
+
"key=\"value|value2\" (eg. name=\"Paris|Berlin\")": "key=\"value|value2\" (eg. name=\"Paris|Berlin\")",
|
|
450
|
+
"More info about Overpass syntax": "More info about Overpass syntax",
|
|
451
|
+
"For more complex needs, see": "For more complex needs, see",
|
|
452
|
+
"Choose data": "Choose data",
|
|
453
|
+
"Import helpers:": "Import helpers:",
|
|
454
|
+
"Choose the format": "Choose the format",
|
|
455
|
+
"Choose the layer": "Choose the layer",
|
|
456
|
+
"Layer name": "Layer name",
|
|
457
|
+
"Choose import mode": "Choose import mode",
|
|
458
|
+
"Copy into the layer": "Copy into the layer",
|
|
459
|
+
"Link to the layer as remote data": "Link to the layer as remote data",
|
|
460
|
+
"Condition": "Condition",
|
|
461
|
+
"key=value or key!=value": "key=value or key!=value",
|
|
462
|
+
"Are you sure you want to delete this rule?": "Are you sure you want to delete this rule?",
|
|
463
|
+
"empty rule": "empty rule",
|
|
464
|
+
"Conditional style rules": "Conditional style rules",
|
|
465
|
+
"Add rule": "Add rule",
|
|
466
|
+
"Browser: data": "Browser: data",
|
|
467
|
+
"Browser: layers": "Browser: layers",
|
|
468
|
+
"Browser: filters": "Browser: filters",
|
|
469
|
+
"Enable real-time collaboration": "Enable real-time collaboration",
|
|
470
|
+
"✅ Copied!": "✅ Copied!",
|
|
471
|
+
"Choose a dataset": "Choose a dataset",
|
|
472
|
+
"Choose this dataset": "Choose this dataset",
|
|
473
|
+
"GeoDataMine: thematic data from OpenStreetMap": "GeoDataMine: thematic data from OpenStreetMap",
|
|
474
|
+
"Choose a theme": "Choose a theme",
|
|
475
|
+
"Symplify all geometries to points": "Symplify all geometries to points",
|
|
476
|
+
"Choose this data": "Choose this data",
|
|
477
|
+
"Search admin boundary": "Search admin boundary",
|
|
478
|
+
"Please choose a theme and a boundary first.": "Please choose a theme and a boundary first.",
|
|
479
|
+
"Expression": "Expression",
|
|
480
|
+
"Geometry mode": "Geometry mode",
|
|
481
|
+
"Only geometry centers": "Only geometry centers",
|
|
482
|
+
"Search area": "Search area",
|
|
483
|
+
"Type area name, or let empty to load data in current map view": "Type area name, or let empty to load data in current map view",
|
|
484
|
+
"Please define an expression for the query first": "Please define an expression for the query first"
|
|
450
485
|
}
|
|
451
486
|
L.registerLocale("am_ET", locale)
|
|
452
487
|
L.setLocale("am_ET")
|