From 871230bcbeef223cae8c96a841708b85ac99ff38 Mon Sep 17 00:00:00 2001 From: Norbert Renner Date: Fri, 5 Apr 2019 19:07:29 +0200 Subject: [PATCH] Prepend language and country code to layer tree, ordering, i18n (#146) --- css/style.css | 6 ++ js/LayersConfig.js | 138 +++++++++++++++++++++++++++++----------- js/control/LayersTab.js | 100 ++++++++++++++++++----------- locales/en.json | 10 +++ locales/keys.js | 11 +++- 5 files changed, 189 insertions(+), 76 deletions(-) diff --git a/css/style.css b/css/style.css index b038e0d..1d4394d 100644 --- a/css/style.css +++ b/css/style.css @@ -423,6 +423,12 @@ table.dataTable.display tbody tr.even:hover { margin-top: 5px; } +.tree-code { + font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace; + margin-right: 7px; + color: #666; /* like root nodes, jstree-disabled */ +} + /* hide currently unused bottom tabs container because of touch border artefacts */ .leaflet-sidebar-tabs > ul:last-child { diff --git a/js/LayersConfig.js b/js/LayersConfig.js index 952e6d9..9cb033a 100644 --- a/js/LayersConfig.js +++ b/js/LayersConfig.js @@ -83,46 +83,103 @@ BR.LayersConfig = L.Class.extend({ BR.layerIndex['HikeBike.HillShading'].properties.overlay = true; + var propertyOverrides = { + 'standard': { + 'name': i18next.t('map.layer.osm'), + 'mapUrl': 'https://www.openstreetmap.org/#map={zoom}/{lat}/{lon}' + }, + 'osm-mapnik-german_style': { + 'name': i18next.t('map.layer.osmde'), + 'language_code': 'de', + 'mapUrl': 'https://www.openstreetmap.de/karte.html?zoom={zoom}&lat={lat}&lon={lon}&layers=B000TF' + }, + 'OpenTopoMap': { + 'name': i18next.t('map.layer.topo'), + 'mapUrl': 'https://opentopomap.org/#map={zoom}/{lat}/{lon}' + }, + 'Stamen.Terrain': { + 'name': i18next.t('map.layer.stamen-terrain'), + 'mapUrl': 'http://maps.stamen.com/#terrain/{zoom}/{lat}/{lon}' + }, + 'opencylemap': { + 'name': i18next.t('map.layer.cycle'), + 'nameShort': 'OpenCycleMap', + 'mapUrl': 'https://www.opencyclemap.org/?zoom={zoom}&lat={lat}&lon={lon}&layers=B0000' + }, + '1061': { + 'name': i18next.t('map.layer.outdoors'), + 'nameShort': 'Outdoors', + 'mapUrl': 'https://www.opencyclemap.org/?zoom={zoom}&lat={lat}&lon={lon}&layers=000B0' + }, + 'Esri.WorldImagery': { + 'name': i18next.t('map.layer.esri'), + 'nameShort': i18next.t('credits.esri-tiles'), + 'mapUrl': 'http://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9' + }, + 'HikeBike.HillShading': { + 'name': i18next.t('map.layer.hikebike-hillshading'), + 'nameShort': i18next.t('map.hikebike-hillshading'), + 'mapUrl': 'http://hikebikemap.org/?zoom={zoom}&lat={lat}&lon={lon}&layer=HikeBikeMap' + }, + 'Waymarked_Trails-Cycling': { + 'name': i18next.t('map.layer.cycling'), + 'nameShort': i18next.t('map.cycling'), + 'mapUrl': 'http://cycling.waymarkedtrails.org/#?map={zoom}!{lat}!{lon}' + }, + 'Waymarked_Trails-Hiking': { + 'name': i18next.t('map.layer.hiking'), + 'nameShort': i18next.t('map.hiking'), + 'mapUrl': 'http://hiking.waymarkedtrails.org/#?map={zoom}!{lat}!{lon}' + }, + 'OpenStreetMap.CH': { + 'country_code': 'CH' + }, + 'topplus-open': { + 'country_code': 'DE' + }, + 'osm-cambodia_laos_thailand_vietnam-bilingual': { + 'country_code': 'TH+' + }, + 'osmfr': { + 'language_code': 'fr' + }, + // kosmosnimki.ru + '1023': { + 'language_code': 'ru' + }, + // sputnik.ru + '1021': { + 'language_code': 'ru' + }, + // Osmapa.pl - Mapa OpenStreetMap Polska + '1017': { + 'language_code': 'pl' + }, + 'osmfr-basque': { + 'language_code': 'eu' + }, + 'osmfr-breton': { + 'language_code': 'br' + }, + 'osmfr-occitan': { + 'language_code': 'oc' + } + }; + + for (id in propertyOverrides) { + var layer = BR.layerIndex[id]; - function setProperty(layerId, key, value) { - var layer = BR.layerIndex[layerId]; if (layer) { - layer.properties[key] = value; + var properties = propertyOverrides[id]; + + for (key in properties) { + var value = properties[key]; + layer.properties[key] = value; + } } else { - console.error('Layer not found: ' + layerId); + console.error('Layer not found: ' + id); } } - function setMapUrl(layerId, url) { - setProperty(layerId, 'mapUrl', url); - } - function setName(layerId, url) { - setProperty(layerId, 'name', url); - } - - // Layer attribution here only as short link to original site, - // to keep current position use placeholders: {zoom}/{lat}/{lon} - // Copyright attribution in index.html #credits - setMapUrl('standard', 'OpenStreetMap'); - setMapUrl('osm-mapnik-german_style', 'OpenStreetMap.de'); - setMapUrl('OpenTopoMap', 'OpenTopoMap'); - setMapUrl('Stamen.Terrain', '' + i18next.t('map.layer.stamen-terrain') + ''); - setMapUrl('opencylemap', 'OpenCycleMap'); - setMapUrl('1061', 'Outdoors'); - setMapUrl('Esri.WorldImagery', '' + i18next.t('credits.esri-tiles') + ''); - setMapUrl('HikeBike.HillShading', '' + i18next.t('map.hikebike-hillshading') + ''); - setMapUrl('Waymarked_Trails-Cycling', '' + i18next.t('map.cycling') + ''); - setMapUrl('Waymarked_Trails-Hiking', '' + i18next.t('map.hiking') + ''); - - setName('standard', i18next.t('map.layer.osm')); - setName('osm-mapnik-german_style', i18next.t('map.layer.osmde')); - setName('OpenTopoMap', i18next.t('map.layer.topo')); - setName('Stamen.Terrain', i18next.t('map.layer.stamen-terrain')); - setName('opencylemap', i18next.t('map.layer.cycle')); - setName('1061', i18next.t('map.layer.outdoors')); - setName('Esri.WorldImagery', i18next.t('map.layer.esri')); - setName('HikeBike.HillShading', i18next.t('map.layer.hikebike-hillshading')); - setName('Waymarked_Trails-Cycling', i18next.t('map.layer.cycling')); - setName('Waymarked_Trails-Hiking', i18next.t('map.layer.hiking')); }, isDefaultLayer: function(id, overlay) { @@ -212,9 +269,11 @@ BR.LayersConfig = L.Class.extend({ var options = { - maxZoom: this._map.getMaxZoom(), - mapUrl: props.mapUrl + maxZoom: this._map.getMaxZoom() }; + if (props.mapUrl) { + options.mapLink = '' + (props.nameShort || props.name) + ''; + } var keyObj = this.getKeyName(url); if (keyObj && BR.keys[keyObj.name]) { @@ -257,8 +316,11 @@ BR.LayersConfig = L.Class.extend({ } } + // Layer attribution here only as short link to original site, + // to keep current position use placeholders: {zoom}/{lat}/{lon} + // Copyright attribution in index.html #credits var getAttribution = function () { - return this.options.mapUrl; + return this.options.mapLink; } layer.getAttribution = getAttribution; diff --git a/js/control/LayersTab.js b/js/control/LayersTab.js index 560cc96..4b9fb37 100644 --- a/js/control/LayersTab.js +++ b/js/control/LayersTab.js @@ -19,8 +19,8 @@ BR.LayersTab = BR.ControlLayers.extend({ this.initButtons(); var structure = { - 'Base layers': { - 'Worldwide international': [ + 'base-layers': { + 'worldwide-international': [ 'standard', 'OpenTopoMap', 'Stamen.Terrain', @@ -34,49 +34,63 @@ BR.LayersTab = BR.ControlLayers.extend({ '1016', // 4UMaps, 'openmapsurfer' ], - 'Worldwide monolingual': [ + 'worldwide-monolingual': [ 'osm-mapnik-german_style', 'osmfr', - '1023', // Osmapa.pl - Mapa OpenStreetMap Polska - '1021', // kosmosnimki.ru - '1017' // sputnik.ru + '1017', // Osmapa.pl - Mapa OpenStreetMap Polska + '1023', // kosmosnimki.ru + '1021' // sputnik.ru ], - 'Europe': [ + 'europe': [ 'MtbMap', '1069' // MRI (maps.refuges.info) ], - 'Country': [ - 'topplus-open', - 'OpenStreetMap.CH', - 'Freemap.sk-Car', - 'Freemap.sk-Hiking', - 'Freemap.sk-Cyclo', - 'OpenStreetMap-turistautak', - 'Israel_Hiking', - 'Israel_MTB', - 'osmbe', - 'osmbe-fr', - 'osmbe-nl', + 'europe-monolingual': [ 'osmfr-basque', 'osmfr-breton', - 'osmfr-occitan', + 'osmfr-occitan' + ], + 'country': [ + { + 'BE': [ + 'osmbe', + 'osmbe-fr', + 'osmbe-nl', + ] + }, + 'OpenStreetMap.CH', + 'topplus-open', + 'OpenStreetMap-turistautak', + { + 'IL': [ + 'Israel_Hiking', + 'Israel_MTB', + ] + }, 'mtbmap-no', + { + 'SK': [ + 'Freemap.sk-Car', + 'Freemap.sk-Hiking', + 'Freemap.sk-Cyclo', + ] + }, 'osm-cambodia_laos_thailand_vietnam-bilingual' ] }, - 'Overlays': { - 'World-wide': [ + 'overlays': { + 'worldwide': [ 'HikeBike.HillShading', - 'Waymarked_Trails-Hiking', 'Waymarked_Trails-Cycling', + 'Waymarked_Trails-Hiking', 'Waymarked_Trails-MTB', 'mapillary-coverage-raster' ], - 'Country': [ + 'country': [ 'historic-place-contours', 'hu-hillshade', { - 'PL - Poland': [ + 'PL': [ 'mapaszlakow-cycle', 'mapaszlakow-bike', 'mapaszlakow-hike', @@ -123,7 +137,7 @@ BR.LayersTab = BR.ControlLayers.extend({ }; var onUncheckNode = function (e, data) { - var obj = this.getLayer(data.node.text); + var obj = this.getLayerById(data.node.id); if (!obj) return; this.removeLayer(obj.layer); @@ -195,22 +209,34 @@ BR.LayersTab = BR.ControlLayers.extend({ }, toJsTree: function (layerTree) { - var data = []; + var data = { + children: [] + }; var self = this; function createRootNode(name) { - var children = []; var rootNode = { - 'text': name, + 'text': i18next.t('sidebar.layers.category.' + name, name), 'state': { 'disabled': true }, - 'children': children + 'children': [] }; return rootNode; } - function createNode(id, layerData) { + function getText(props, parent) { + var text = ''; + var code = props.country_code || props.language_code; + if (code && parent.text !== code) { + text += '' + code + ''; + } + text += props.name; + + return text; + } + + function createNode(id, layerData, parent) { var props = layerData.properties; var url = props.url; var keyObj = self.layersConfig.getKeyName(url); @@ -220,7 +246,7 @@ BR.LayersTab = BR.ControlLayers.extend({ if (!keyObj || keyObj && BR.keys[keyObj.name]) { childNode = { 'id': id, - 'text': props.name, + 'text': getText(props, parent), 'state': { 'checked': self.layersConfig.isDefaultLayer(id, props.overlay) } @@ -235,8 +261,8 @@ BR.LayersTab = BR.ControlLayers.extend({ var value = obj[name]; var rootNode = createRootNode(name) - outTree.push(rootNode); - walkTree(value, rootNode.children); + outTree.children.push(rootNode); + walkTree(value, rootNode); } } @@ -249,9 +275,9 @@ BR.LayersTab = BR.ControlLayers.extend({ var layer = BR.layerIndex[entry]; if (layer) { - var childNode = createNode(entry, layer); + var childNode = createNode(entry, layer, outTree); if (childNode) { - outTree.push(childNode); + outTree.children.push(childNode); } } else { console.error('Layer "' + entry + '" not found'); @@ -264,7 +290,7 @@ BR.LayersTab = BR.ControlLayers.extend({ } walkTree(layerTree, data); - return data; + return data.children; }, storeDefaultLayers: function () { diff --git a/locales/en.json b/locales/en.json index a941489..d420af6 100644 --- a/locales/en.json +++ b/locales/en.json @@ -160,6 +160,16 @@ "title": "Itinerary" }, "layers": { + "category": { + "base-layers": "Base layers", + "country": "Country", + "europe": "Europe", + "europe-monolingual": "Europe monolingual", + "overlays": "Overlays", + "worldwide": "Worldwide", + "worldwide-international": "Worldwide international", + "worldwide-monolingual": "Worldwide monolingual" + }, "collapse": "Collapse all", "custom-layers": "Custom layers", "customize": "Add or remove custom layers", diff --git a/locales/keys.js b/locales/keys.js index d62adfd..23f5255 100644 --- a/locales/keys.js +++ b/locales/keys.js @@ -18,4 +18,13 @@ i18next.t('navbar.profile.trekking-noferries'); i18next.t('navbar.profile.trekking-nosteps'); i18next.t('navbar.profile.trekking-steep'); i18next.t('navbar.profile.vm-forum-liegerad-schnell'); -i18next.t('navbar.profile.vm-forum-velomobil-schnell'); \ No newline at end of file +i18next.t('navbar.profile.vm-forum-velomobil-schnell'); + +i18next.t('sidebar.layers.category.base-layers', 'Base layers'); +i18next.t('sidebar.layers.category.worldwide-international', 'Worldwide international'); +i18next.t('sidebar.layers.category.worldwide-monolingual', 'Worldwide monolingual'); +i18next.t('sidebar.layers.category.europe', 'Europe'); +i18next.t('sidebar.layers.category.europe-monolingual', 'Europe monolingual'); +i18next.t('sidebar.layers.category.country', 'Country'); +i18next.t('sidebar.layers.category.overlays', 'Overlays'); +i18next.t('sidebar.layers.category.worldwide', 'Worldwide');