Merge branch 'master' into project/natuurpunt

This commit is contained in:
pietervdvn 2021-07-07 18:20:22 +02:00
commit 1175562c18
13 changed files with 426 additions and 98 deletions

View file

@ -94,39 +94,7 @@ export default class LayoutConfig {
} }
); );
this.defaultBackgroundId = json.defaultBackgroundId; this.defaultBackgroundId = json.defaultBackgroundId;
this.layers = json.layers.map((layer, i) => { this.layers = LayoutConfig.ExtractLayers(json, this.units, official);
if (typeof layer === "string") {
if (AllKnownLayers.sharedLayersJson[layer] !== undefined) {
if (json.overrideAll !== undefined) {
let lyr = JSON.parse(JSON.stringify(AllKnownLayers.sharedLayersJson[layer]));
return new LayerConfig(Utils.Merge(json.overrideAll, lyr), this.units, `${this.id}+overrideAll.layers[${i}]`, official);
} else {
return AllKnownLayers.sharedLayers[layer]
}
} else {
throw "Unkown fixed layer " + layer;
}
}
// @ts-ignore
if (layer.builtin !== undefined) {
// @ts-ignore
const name = layer.builtin;
const shared = AllKnownLayers.sharedLayersJson[name];
if (shared === undefined) {
throw "Unkown fixed layer " + name;
}
// @ts-ignore
layer = Utils.Merge(layer.override, JSON.parse(JSON.stringify(shared))); // We make a deep copy of the shared layer, in order to protect it from changes
}
if (json.overrideAll !== undefined) {
layer = Utils.Merge(json.overrideAll, layer);
}
// @ts-ignore
return new LayerConfig(layer, this.units, `${this.id}.layers[${i}]`, official)
});
// ALl the layers are constructed, let them share tags in now! // ALl the layers are constructed, let them share tags in now!
const roaming: { r, source: LayerConfig }[] = [] const roaming: { r, source: LayerConfig }[] = []
@ -190,6 +158,61 @@ export default class LayoutConfig {
} }
private static ExtractLayers(json: LayoutConfigJson, units: Unit[], official: boolean): LayerConfig[] {
const result: LayerConfig[] = []
json.layers.forEach((layer, i) => {
if (typeof layer === "string") {
if (AllKnownLayers.sharedLayersJson[layer] !== undefined) {
if (json.overrideAll !== undefined) {
let lyr = JSON.parse(JSON.stringify(AllKnownLayers.sharedLayersJson[layer]));
const newLayer = new LayerConfig(Utils.Merge(json.overrideAll, lyr), units, `${json.id}+overrideAll.layers[${i}]`, official)
result.push(newLayer)
return
} else {
result.push(AllKnownLayers.sharedLayers[layer])
return
}
} else {
throw "Unknown fixed layer " + layer;
}
}
if (layer["builtin"] === undefined) {
if (json.overrideAll !== undefined) {
layer = Utils.Merge(json.overrideAll, layer);
}
// @ts-ignore
const newLayer = new LayerConfig(layer, units, `${json.id}.layers[${i}]`, official)
result.push(newLayer)
return
}
// @ts-ignore
let names = layer.builtin;
if (typeof names === "string") {
names = [names]
}
names.forEach(name => {
const shared = AllKnownLayers.sharedLayersJson[name];
if (shared === undefined) {
throw "Unknown fixed layer " + name;
}
// @ts-ignore
let newLayer: LayerConfigJson = Utils.Merge(layer.override, JSON.parse(JSON.stringify(shared))); // We make a deep copy of the shared layer, in order to protect it from changes
if (json.overrideAll !== undefined) {
newLayer = Utils.Merge(json.overrideAll, newLayer);
}
// @ts-ignore
const layerConfig = new LayerConfig(newLayer, units, `${json.id}.layers[${i}]`, official)
result.push(layerConfig)
return
})
});
return result
}
private static ExtractUnits(json: LayoutConfigJson, context: string): Unit[] { private static ExtractUnits(json: LayoutConfigJson, context: string): Unit[] {
const result: Unit[] = [] const result: Unit[] = []
if ((json.units ?? []).length !== 0) { if ((json.units ?? []).length !== 0) {

View file

@ -120,7 +120,7 @@ export interface LayoutConfigJson {
* *
* E.g.: if there are two layers defined: * E.g.: if there are two layers defined:
* ``` * ```
* "layers"[ * "layers":[
* {"title": ..., "tagRenderings": [...], "osmSource":{"tags": ...}}, * {"title": ..., "tagRenderings": [...], "osmSource":{"tags": ...}},
* {"title", ..., "tagRenderings", [...], "osmSource":{"tags" ...}} * {"title", ..., "tagRenderings", [...], "osmSource":{"tags" ...}}
* ] * ]
@ -132,13 +132,19 @@ export interface LayoutConfigJson {
* "osmSource":{"geoJsonSource":"xyz"} * "osmSource":{"geoJsonSource":"xyz"}
* } * }
* then the result will be that all the layers will have these properties applied and result in: * then the result will be that all the layers will have these properties applied and result in:
* "layers"[ * "layers":[
* {"title": ..., "tagRenderings": [...], "osmSource":{"tags": ..., "geoJsonSource":"xyz"}}, * {"title": ..., "tagRenderings": [...], "osmSource":{"tags": ..., "geoJsonSource":"xyz"}},
* {"title", ..., "tagRenderings", [...], "osmSource":{"tags" ..., "geoJsonSource":"xyz"}} * {"title", ..., "tagRenderings", [...], "osmSource":{"tags" ..., "geoJsonSource":"xyz"}}
* ] * ]
* ``` * ```
* *
* If the overrideAll contains a list where the keys starts with a plus, the values will be appended (instead of discarding the old list) * If the overrideAll contains a list where the keys starts with a plus, the values will be appended (instead of discarding the old list), for example
*
* "overrideAll": {
* "+tagRenderings": [ { ... some tagrendering ... }]
* }
*
* In the above scenario, `sometagrendering` will be added at the beginning of the tagrenderings of every layer
*/ */
overrideAll?: any; overrideAll?: any;
@ -182,10 +188,33 @@ export interface LayoutConfigJson {
* *layers can also remove 'leftover'-features if the leftovers overlap with a feature in the layer itself * *layers can also remove 'leftover'-features if the leftovers overlap with a feature in the layer itself
* *
* Note that builtin layers can be reused. Either put in the name of the layer to reuse, or use {builtin: "layername", override: ...} * Note that builtin layers can be reused. Either put in the name of the layer to reuse, or use {builtin: "layername", override: ...}
*
* The 'override'-object will be copied over the original values of the layer, which allows to change certain aspects of the layer * The 'override'-object will be copied over the original values of the layer, which allows to change certain aspects of the layer
* *
* For example: If you would like to use layer nature reserves, but only from a specific operator (eg. Natuurpunt) you would use the following in your theme:
*
* ```
* "layer": {
* "builtin": "nature_reserve",
* "override": {"source":
* {"osmTags": {
* "+and":["operator=Natuurpunt"]
* }
* }
* }
* }
* ```
*
* It's also possible to load multiple layers at once, for example, if you would like for both drinking water and benches to start at the zoomlevel at 12, you would use the following:
*
* ```
* "layer": {
* "builtin": ["benches", "drinking_water"],
* "override": {"minzoom": 12}
* }
*```
*/ */
layers: (LayerConfigJson | string | { builtin: string, override: any })[], layers: (LayerConfigJson | string | { builtin: string | string[], override: any })[],
/** /**
* In some cases, a value is represented in a certain unit (such as meters for heigt/distance/..., km/h for speed, ...) * In some cases, a value is represented in a certain unit (such as meters for heigt/distance/..., km/h for speed, ...)
@ -241,7 +270,7 @@ export interface LayoutConfigJson {
* Also, if a freeform text field is used, an extra dropdown with applicable denominations will be given * Also, if a freeform text field is used, an extra dropdown with applicable denominations will be given
* *
*/ */
units?: { units?: {
/** /**

View file

@ -18,15 +18,14 @@
Development Development
----------- -----------
**Windows users**: All scripts are made for linux devices. Use the Ubuntu terminal for Windows (or even better - make the switch ;) ) **Windows users**: All scripts are made for linux devices. Use the Ubuntu terminal for Windows (or even better - make the switch ;) ). If you are using Visual Studio, open everything in a 'new WSL Window'.
To develop and build MapComplete, yo To develop and build MapComplete, yo
0. Make sure you have a recent version of nodejs - at least 12.0, preferably 15 0. Make sure you have a recent version of nodejs - at least 12.0, preferably 15
0. Make a fork and clone the repository. 0. Make a fork and clone the repository.
1. Install `npm`. Linux: `sudo apt install npm` (or your favourite package manager), Windows: install nodeJS: https://nodejs.org/en/download/ 1. Install `npm`. Linux: `sudo apt install npm` (or your favourite package manager), Windows: install nodeJS: https://nodejs.org/en/download/
2. Run `npm install` to install the package dependencies 3. Run `npm run init` and generate some additional dependencies and generated files. Note that it'll install the dependencies too
3. Run `npm run init` and generate some additional dependencies and generated files
4. Run `npm run start` to host a local testversion at http://localhost:1234/index.html 4. Run `npm run start` to host a local testversion at http://localhost:1234/index.html
5. By default, a landing page with available themes is served. In order to load a single theme, use `layout=themename` or `userlayout=true#<layout configuration>` as [Query parameter](URL_Parameters.md). Note that the shorter URLs (e.g. `bookcases.html`, `aed.html`, ...) _don't_ exist on the development version. 5. By default, a landing page with available themes is served. In order to load a single theme, use `layout=themename` or `userlayout=true#<layout configuration>` as [Query parameter](URL_Parameters.md). Note that the shorter URLs (e.g. `bookcases.html`, `aed.html`, ...) _don't_ exist on the development version.

View file

@ -2,7 +2,7 @@ import { Utils } from "../Utils";
export default class Constants { export default class Constants {
public static vNumber = "0.8.3"; public static vNumber = "0.8.3a";
// The user journey states thresholds when a new feature gets unlocked // The user journey states thresholds when a new feature gets unlocked
public static userJourney = { public static userJourney = {

View file

@ -6,6 +6,7 @@ import Combine from "../Base/Combine";
import Translations from "../i18n/Translations"; import Translations from "../i18n/Translations";
import LayerConfig from "../../Customizations/JSON/LayerConfig"; import LayerConfig from "../../Customizations/JSON/LayerConfig";
import BaseUIElement from "../BaseUIElement"; import BaseUIElement from "../BaseUIElement";
import {Translation} from "../i18n/Translation";
/** /**
* Shows the panel with all layers and a toggle for each of them * Shows the panel with all layers and a toggle for each of them
@ -29,18 +30,21 @@ export default class LayerSelection extends Combine {
const leafletStyle = layer.layerDef.GenerateLeafletStyle( const leafletStyle = layer.layerDef.GenerateLeafletStyle(
new UIEventSource<any>({id: "node/-1"}), new UIEventSource<any>({id: "node/-1"}),
false) false)
const leafletStyleNa = layer.layerDef.GenerateLeafletStyle(
new UIEventSource<any>({id: "node/-1"}),
false)
const icon = new Combine([leafletStyle.icon.html]).SetClass("single-layer-selection-toggle") const icon = new Combine([leafletStyle.icon.html]).SetClass("single-layer-selection-toggle")
let iconUnselected: BaseUIElement = new Combine([leafletStyle.icon.html]) let iconUnselected: BaseUIElement = new Combine([leafletStyleNa.icon.html])
.SetClass("single-layer-selection-toggle") .SetClass("single-layer-selection-toggle")
.SetStyle("opacity:0.2;"); .SetStyle("opacity:0.2;");
const name = Translations.WT(layer.layerDef.name)?.Clone() if (layer.layerDef.name === undefined) {
?.SetStyle("font-size:large;margin-left: 0.5em;"); continue;
if ((name ?? "") === "") {
continue
} }
const name: Translation = Translations.WT(layer.layerDef.name)?.Clone()
name.SetStyle("font-size:large;margin-left: 0.5em;");
const zoomStatus = new VariableUiElement(State.state.locationControl.map(location => { const zoomStatus = new VariableUiElement(State.state.locationControl.map(location => {
if (location.zoom < layer.layerDef.minzoom) { if (location.zoom < layer.layerDef.minzoom) {
return Translations.t.general.layerSelection.zoomInToSeeThisLayer.Clone() return Translations.t.general.layerSelection.zoomInToSeeThisLayer.Clone()
@ -49,12 +53,21 @@ export default class LayerSelection extends Combine {
} }
return "" return ""
})) }))
const zoomStatusNonActive = new VariableUiElement(State.state.locationControl.map(location => {
if (location.zoom < layer.layerDef.minzoom) {
return Translations.t.general.layerSelection.zoomInToSeeThisLayer.Clone()
.SetClass("alert")
.SetStyle("display: block ruby;width:min-content;")
}
return ""
}))
const style = "display:flex;align-items:center;" const style = "display:flex;align-items:center;"
const styleWhole = "display:flex; flex-wrap: wrap" const styleWhole = "display:flex; flex-wrap: wrap"
checkboxes.push(new Toggle( checkboxes.push(new Toggle(
new Combine([new Combine([icon, name]).SetStyle(style), zoomStatus]) new Combine([new Combine([icon, name.Clone()]).SetStyle(style), zoomStatus])
.SetStyle(styleWhole), .SetStyle(styleWhole),
new Combine([new Combine([iconUnselected, "<del>", name, "</del>"]).SetStyle(style), zoomStatus]) new Combine([new Combine([iconUnselected, "<del>", name.Clone(), "</del>"]).SetStyle(style), zoomStatusNonActive])
.SetStyle(styleWhole), .SetStyle(styleWhole),
layer.isDisplayed).ToggleOnClick() layer.isDisplayed).ToggleOnClick()
.SetStyle("margin:0.3em;") .SetStyle("margin:0.3em;")

View file

@ -169,7 +169,8 @@
"ru": "Материал: дерево", "ru": "Материал: дерево",
"zh_Hans": "材质:木", "zh_Hans": "材质:木",
"nb_NO": "Materiale: tre", "nb_NO": "Materiale: tre",
"zh_Hant": "材質:木頭" "zh_Hant": "材質:木頭",
"pt_BR": "Material: madeira"
} }
}, },
{ {
@ -201,7 +202,8 @@
"ru": "Материал: камень", "ru": "Материал: камень",
"zh_Hans": "材质:石头", "zh_Hans": "材质:石头",
"nb_NO": "Materiale: stein", "nb_NO": "Materiale: stein",
"zh_Hant": "材質:石頭" "zh_Hant": "材質:石頭",
"pt_BR": "Material: pedra"
} }
}, },
{ {
@ -217,7 +219,8 @@
"ru": "Материал: бетон", "ru": "Материал: бетон",
"zh_Hans": "材质:混凝土", "zh_Hans": "材质:混凝土",
"nb_NO": "Materiale: betong", "nb_NO": "Materiale: betong",
"zh_Hant": "材質:水泥" "zh_Hant": "材質:水泥",
"pt_BR": "Material: concreto"
} }
}, },
{ {
@ -233,7 +236,8 @@
"ru": "Материал: пластик", "ru": "Материал: пластик",
"zh_Hans": "材质:塑料", "zh_Hans": "材质:塑料",
"nb_NO": "Materiale: plastikk", "nb_NO": "Materiale: plastikk",
"zh_Hant": "材質:塑膠" "zh_Hant": "材質:塑膠",
"pt_BR": "Material: plástico"
} }
}, },
{ {
@ -249,7 +253,8 @@
"ru": "Материал: сталь", "ru": "Материал: сталь",
"zh_Hans": "材质:不锈钢", "zh_Hans": "材质:不锈钢",
"nb_NO": "Materiale: stål", "nb_NO": "Materiale: stål",
"zh_Hant": "材質:鋼鐵" "zh_Hant": "材質:鋼鐵",
"pt_BR": "Material: aço"
} }
} }
], ],
@ -262,7 +267,8 @@
"it": "Di che materiale è fatta questa panchina?", "it": "Di che materiale è fatta questa panchina?",
"zh_Hans": "这个长椅(或座椅)是用什么材料做的?", "zh_Hans": "这个长椅(或座椅)是用什么材料做的?",
"ru": "Из какого материала сделана скамейка?", "ru": "Из какого материала сделана скамейка?",
"zh_Hant": "這個長椅 (座位) 是什麼做的?" "zh_Hant": "這個長椅 (座位) 是什麼做的?",
"pt_BR": "De que é feito o banco (assento)?"
} }
}, },
{ {
@ -275,7 +281,8 @@
"it": "In che direzione si guarda quando si è seduti su questa panchina?", "it": "In che direzione si guarda quando si è seduti su questa panchina?",
"ru": "В каком направлении вы смотрите, когда сидите на скамейке?", "ru": "В каком направлении вы смотрите, когда сидите на скамейке?",
"zh_Hans": "坐在长椅上的时候你目视的方向是哪边?", "zh_Hans": "坐在长椅上的时候你目视的方向是哪边?",
"zh_Hant": "坐在長椅時是面對那個方向?" "zh_Hant": "坐在長椅時是面對那個方向?",
"pt_BR": "Em que direção você olha quando está sentado no banco?"
}, },
"render": { "render": {
"en": "When sitting on the bench, one looks towards {direction}°.", "en": "When sitting on the bench, one looks towards {direction}°.",
@ -305,7 +312,8 @@
"id": "Warna: {colour}", "id": "Warna: {colour}",
"zh_Hans": "颜色: {colour}", "zh_Hans": "颜色: {colour}",
"zh_Hant": "顏色:{colour}", "zh_Hant": "顏色:{colour}",
"nb_NO": "Farge: {colour}" "nb_NO": "Farge: {colour}",
"pt_BR": "Cor: {colour}"
}, },
"question": { "question": {
"en": "Which colour does this bench have?", "en": "Which colour does this bench have?",
@ -316,7 +324,8 @@
"it": "Di che colore è questa panchina?", "it": "Di che colore è questa panchina?",
"ru": "Какого цвета скамейка?", "ru": "Какого цвета скамейка?",
"zh_Hans": "这个长椅是什么颜色的?", "zh_Hans": "这个长椅是什么颜色的?",
"zh_Hant": "這個長椅是什麼顏色的?" "zh_Hant": "這個長椅是什麼顏色的?",
"pt_BR": "Qual a cor dessa bancada?"
}, },
"freeform": { "freeform": {
"key": "colour", "key": "colour",
@ -335,7 +344,8 @@
"ru": "Цвет: коричневый", "ru": "Цвет: коричневый",
"zh_Hans": "颜色:棕", "zh_Hans": "颜色:棕",
"zh_Hant": "顏色:棕色", "zh_Hant": "顏色:棕色",
"nb_NO": "Farge: brun" "nb_NO": "Farge: brun",
"pt_BR": "Cor: marrom"
} }
}, },
{ {
@ -350,7 +360,8 @@
"ru": "Цвет: зеленый", "ru": "Цвет: зеленый",
"zh_Hans": "颜色:绿", "zh_Hans": "颜色:绿",
"zh_Hant": "顏色:綠色", "zh_Hant": "顏色:綠色",
"nb_NO": "Farge: grønn" "nb_NO": "Farge: grønn",
"pt_BR": "Cor: verde"
} }
}, },
{ {
@ -365,7 +376,8 @@
"ru": "Цвет: серый", "ru": "Цвет: серый",
"zh_Hans": "颜色:灰", "zh_Hans": "颜色:灰",
"zh_Hant": "顏色:灰色", "zh_Hant": "顏色:灰色",
"nb_NO": "Farge: grå" "nb_NO": "Farge: grå",
"pt_BR": "Cor: cinza"
} }
}, },
{ {
@ -380,7 +392,8 @@
"ru": "Цвет: белый", "ru": "Цвет: белый",
"zh_Hans": "颜色:白", "zh_Hans": "颜色:白",
"zh_Hant": "顏色:白色", "zh_Hant": "顏色:白色",
"nb_NO": "Farge: hvit" "nb_NO": "Farge: hvit",
"pt_BR": "Cor: branco"
} }
}, },
{ {
@ -395,7 +408,8 @@
"ru": "Цвет: красный", "ru": "Цвет: красный",
"zh_Hans": "颜色:红", "zh_Hans": "颜色:红",
"zh_Hant": "顏色:紅色", "zh_Hant": "顏色:紅色",
"nb_NO": "Farge: rød" "nb_NO": "Farge: rød",
"pt_BR": "Cor: vermelho"
} }
}, },
{ {
@ -410,7 +424,8 @@
"ru": "Цвет: чёрный", "ru": "Цвет: чёрный",
"zh_Hans": "颜色:黑", "zh_Hans": "颜色:黑",
"zh_Hant": "顏色:黑色", "zh_Hant": "顏色:黑色",
"nb_NO": "Farge: svart" "nb_NO": "Farge: svart",
"pt_BR": "Cor: preto"
} }
}, },
{ {
@ -425,7 +440,8 @@
"ru": "Цвет: синий", "ru": "Цвет: синий",
"zh_Hans": "颜色:蓝", "zh_Hans": "颜色:蓝",
"zh_Hant": "顏色:藍色", "zh_Hant": "顏色:藍色",
"nb_NO": "Farge: blå" "nb_NO": "Farge: blå",
"pt_BR": "Cor: azul"
} }
}, },
{ {
@ -440,7 +456,8 @@
"ru": "Цвет: желтый", "ru": "Цвет: желтый",
"zh_Hans": "颜色:黄", "zh_Hans": "颜色:黄",
"zh_Hant": "顏色:黃色", "zh_Hant": "顏色:黃色",
"nb_NO": "Farge: gul" "nb_NO": "Farge: gul",
"pt_BR": "Cor: amarelo"
} }
} }
] ]
@ -454,7 +471,8 @@
"zh_Hans": "上次对这个长椅实地调查是什么时候?", "zh_Hans": "上次对这个长椅实地调查是什么时候?",
"de": "Wann wurde diese Bank zuletzt überprüft?", "de": "Wann wurde diese Bank zuletzt überprüft?",
"ru": "Когда последний раз обследовали эту скамейку?", "ru": "Когда последний раз обследовали эту скамейку?",
"zh_Hant": "上一次探察長椅是什麼時候?" "zh_Hant": "上一次探察長椅是什麼時候?",
"pt_BR": "Quando esta bancada foi pesquisada pela última vez?"
}, },
"render": { "render": {
"en": "This bench was last surveyed on {survey:date}", "en": "This bench was last surveyed on {survey:date}",
@ -464,7 +482,8 @@
"zh_Hans": "这个长椅于 {survey:date}最后一次实地调查", "zh_Hans": "这个长椅于 {survey:date}最后一次实地调查",
"de": "Diese Bank wurde zuletzt überprüft am {survey:date}", "de": "Diese Bank wurde zuletzt überprüft am {survey:date}",
"ru": "Последний раз обследование этой скамейки проводилось {survey:date}", "ru": "Последний раз обследование этой скамейки проводилось {survey:date}",
"zh_Hant": "這個長椅最後是在 {survey:date} 探查的" "zh_Hant": "這個長椅最後是在 {survey:date} 探查的",
"pt_BR": "Esta bancada foi pesquisada pela última vez em {survey:date}"
}, },
"freeform": { "freeform": {
"key": "survey:date", "key": "survey:date",
@ -508,7 +527,8 @@
"id": "Bangku", "id": "Bangku",
"zh_Hans": "长椅", "zh_Hans": "长椅",
"nb_NO": "Benk", "nb_NO": "Benk",
"zh_Hant": "長椅" "zh_Hant": "長椅",
"pt_BR": "Banco"
}, },
"description": { "description": {
"en": "Add a new bench", "en": "Add a new bench",
@ -521,7 +541,8 @@
"ru": "Добавить новую скамейку", "ru": "Добавить новую скамейку",
"zh_Hans": "增加一个新的长椅", "zh_Hans": "增加一个新的长椅",
"nb_NO": "Legg til en ny benk", "nb_NO": "Legg til en ny benk",
"zh_Hant": "新增長椅" "zh_Hant": "新增長椅",
"pt_BR": "Adicionar um novo banco"
} }
} }
] ]

View file

@ -11,7 +11,8 @@
"ru": "Скамейки на остановках общественного транспорта", "ru": "Скамейки на остановках общественного транспорта",
"zh_Hans": "在公交站点的长椅", "zh_Hans": "在公交站点的长椅",
"nb_NO": "Benker", "nb_NO": "Benker",
"zh_Hant": "大眾運輸站點的長椅" "zh_Hant": "大眾運輸站點的長椅",
"pt_BR": "Bancos em pontos de transporte público"
}, },
"minzoom": 14, "minzoom": 14,
"source": { "source": {
@ -35,7 +36,8 @@
"id": "Bangku", "id": "Bangku",
"zh_Hans": "长椅", "zh_Hans": "长椅",
"nb_NO": "Benk", "nb_NO": "Benk",
"zh_Hant": "長椅" "zh_Hant": "長椅",
"pt_BR": "Banco"
}, },
"mappings": [ "mappings": [
{ {
@ -55,7 +57,8 @@
"it": "Panchina alla fermata del trasporto pubblico", "it": "Panchina alla fermata del trasporto pubblico",
"ru": "Скамейка на остановке общественного транспорта", "ru": "Скамейка на остановке общественного транспорта",
"zh_Hans": "在公交站点的长椅", "zh_Hans": "在公交站点的长椅",
"zh_Hant": "大眾運輸站點的長椅" "zh_Hant": "大眾運輸站點的長椅",
"pt_BR": "Banco em ponto de transporte público"
} }
}, },
{ {
@ -73,7 +76,8 @@
"it": "Panchina in un riparo", "it": "Panchina in un riparo",
"zh_Hans": "在庇护所的长椅", "zh_Hans": "在庇护所的长椅",
"ru": "Скамейка в укрытии", "ru": "Скамейка в укрытии",
"zh_Hant": "涼亭內的長椅" "zh_Hant": "涼亭內的長椅",
"pt_BR": "Banco em abrigo"
} }
} }
] ]
@ -91,7 +95,8 @@
"ru": "{name}", "ru": "{name}",
"id": "{name}", "id": "{name}",
"zh_Hans": "{name}", "zh_Hans": "{name}",
"zh_Hant": "{name}" "zh_Hant": "{name}",
"pt_BR": "{name}"
}, },
"freeform": { "freeform": {
"key": "name" "key": "name"

View file

@ -48,7 +48,8 @@
"it": "Una struttura dove le biciclette possono essere prestate per periodi di tempo più lunghi", "it": "Una struttura dove le biciclette possono essere prestate per periodi di tempo più lunghi",
"de": "Eine Einrichtung, in der Fahrräder für längere Zeit geliehen werden können", "de": "Eine Einrichtung, in der Fahrräder für längere Zeit geliehen werden können",
"ru": "Учреждение, где велосипед может быть арендован на более длительный срок", "ru": "Учреждение, где велосипед может быть арендован на более длительный срок",
"zh_Hant": "能夠長期租用單車的設施" "zh_Hant": "能夠長期租用單車的設施",
"pt_BR": "Uma instalação onde as bicicletas podem ser emprestadas por períodos mais longos"
}, },
"tagRenderings": [ "tagRenderings": [
"images", "images",
@ -89,7 +90,8 @@
"ru": "Сколько стоит прокат велосипеда?", "ru": "Сколько стоит прокат велосипеда?",
"de": "Wie viel kostet das Ausleihen eines Fahrrads?", "de": "Wie viel kostet das Ausleihen eines Fahrrads?",
"nb_NO": "Hvor mye koster det å leie en sykkel?", "nb_NO": "Hvor mye koster det å leie en sykkel?",
"zh_Hant": "租用單車的費用多少?" "zh_Hant": "租用單車的費用多少?",
"pt_BR": "Quanto custa um empréstimo de bicicleta?"
}, },
"render": { "render": {
"en": "Lending a bicycle costs {charge}", "en": "Lending a bicycle costs {charge}",
@ -100,7 +102,8 @@
"ru": "Стоимость аренды велосипеда {charge}", "ru": "Стоимость аренды велосипеда {charge}",
"de": "Das Ausleihen eines Fahrrads kostet {charge}", "de": "Das Ausleihen eines Fahrrads kostet {charge}",
"nb_NO": "Sykkelleie koster {charge}", "nb_NO": "Sykkelleie koster {charge}",
"zh_Hant": "租借單車需要 {charge}" "zh_Hant": "租借單車需要 {charge}",
"pt_BR": "Custos de empréstimo de bicicleta {charge}"
}, },
"freeform": { "freeform": {
"key": "charge", "key": "charge",
@ -125,7 +128,8 @@
"de": "Das Ausleihen eines Fahrrads ist kostenlos", "de": "Das Ausleihen eines Fahrrads ist kostenlos",
"ru": "Прокат велосипедов бесплатен", "ru": "Прокат велосипедов бесплатен",
"nb_NO": "Det er gratis å leie en sykkel", "nb_NO": "Det er gratis å leie en sykkel",
"zh_Hant": "租借單車免費" "zh_Hant": "租借單車免費",
"pt_BR": "Emprestar uma bicicleta é grátis"
} }
}, },
{ {
@ -156,7 +160,8 @@
"zh_Hans": "谁可以从这里借自行车?", "zh_Hans": "谁可以从这里借自行车?",
"de": "Wer kann hier Fahrräder ausleihen?", "de": "Wer kann hier Fahrräder ausleihen?",
"ru": "Кто здесь может арендовать велосипед?", "ru": "Кто здесь может арендовать велосипед?",
"zh_Hant": "誰可以在這裡租單車?" "zh_Hant": "誰可以在這裡租單車?",
"pt_BR": "Quem pode emprestar bicicletas aqui?"
}, },
"multiAnswer": true, "multiAnswer": true,
"mappings": [ "mappings": [
@ -170,7 +175,8 @@
"it": "Sono disponibili biciclette per bambini", "it": "Sono disponibili biciclette per bambini",
"de": "Fahrräder für Kinder verfügbar", "de": "Fahrräder für Kinder verfügbar",
"ru": "Доступны детские велосипеды", "ru": "Доступны детские велосипеды",
"zh_Hant": "提供兒童單車" "zh_Hant": "提供兒童單車",
"pt_BR": "Bicicletas para crianças disponíveis"
} }
}, },
{ {
@ -182,7 +188,8 @@
"it": "Sono disponibili biciclette per adulti", "it": "Sono disponibili biciclette per adulti",
"de": "Fahrräder für Erwachsene verfügbar", "de": "Fahrräder für Erwachsene verfügbar",
"ru": "Доступны велосипеды для взрослых", "ru": "Доступны велосипеды для взрослых",
"zh_Hant": "有提供成人單車" "zh_Hant": "有提供成人單車",
"pt_BR": "Bicicletas para adulto disponíveis"
} }
}, },
{ {
@ -194,7 +201,8 @@
"it": "Sono disponibili biciclette per disabili", "it": "Sono disponibili biciclette per disabili",
"de": "Fahrräder für Behinderte verfügbar", "de": "Fahrräder für Behinderte verfügbar",
"ru": "Доступны велосипеды для людей с ограниченными возможностями", "ru": "Доступны велосипеды для людей с ограниченными возможностями",
"zh_Hant": "有提供行動不便人士的單車" "zh_Hant": "有提供行動不便人士的單車",
"pt_BR": "Bicicletas para deficientes físicos disponíveis"
} }
} }
] ]

View file

@ -7,7 +7,8 @@
"it": "Distributore automatico di camere daria per bici", "it": "Distributore automatico di camere daria per bici",
"de": "Fahrradschlauch-Automat", "de": "Fahrradschlauch-Automat",
"ru": "Торговый автомат для велосипедистов", "ru": "Торговый автомат для велосипедистов",
"zh_Hant": "自行車內胎自動售貨機" "zh_Hant": "自行車內胎自動售貨機",
"pt_BR": "Máquina de venda automática de tubos de bicicleta"
}, },
"title": { "title": {
"render": { "render": {
@ -17,7 +18,8 @@
"it": "Distributore automatico di camere daria per bici", "it": "Distributore automatico di camere daria per bici",
"de": "Fahrradschlauch-Automat", "de": "Fahrradschlauch-Automat",
"ru": "Торговый автомат для велосипедистов", "ru": "Торговый автомат для велосипедистов",
"zh_Hant": "自行車內胎自動售貨機" "zh_Hant": "自行車內胎自動售貨機",
"pt_BR": "Máquina de venda automática de tubos de bicicleta"
}, },
"mappings": [ "mappings": [
{ {
@ -68,7 +70,8 @@
"it": "Distributore automatico di camere daria per bici", "it": "Distributore automatico di camere daria per bici",
"de": "Fahrradschlauch-Automat", "de": "Fahrradschlauch-Automat",
"ru": "Торговый автомат для велосипедистов", "ru": "Торговый автомат для велосипедистов",
"zh_Hant": "自行車內胎自動售貨機" "zh_Hant": "自行車內胎自動售貨機",
"pt_BR": "Máquina de venda automática de tubos de bicicleta"
}, },
"tags": [ "tags": [
"amenity=vending_machine", "amenity=vending_machine",
@ -89,7 +92,8 @@
"it": "Questo distributore automatico funziona ancora?", "it": "Questo distributore automatico funziona ancora?",
"ru": "Этот торговый автомат все еще работает?", "ru": "Этот торговый автомат все еще работает?",
"de": "Ist dieser Automat noch in Betrieb?", "de": "Ist dieser Automat noch in Betrieb?",
"zh_Hant": "這個自動販賣機仍有運作嗎?" "zh_Hant": "這個自動販賣機仍有運作嗎?",
"pt_BR": "Esta máquina de venda automática ainda está operacional?"
}, },
"render": { "render": {
"en": "The operational status is <i>{operational_status</i>", "en": "The operational status is <i>{operational_status</i>",
@ -115,7 +119,8 @@
"ru": "Этот торговый автомат работает", "ru": "Этот торговый автомат работает",
"zh_Hans": "这个借还机正常工作", "zh_Hans": "这个借还机正常工作",
"de": "Dieser Automat funktioniert", "de": "Dieser Automat funktioniert",
"zh_Hant": "這個自動販賣機仍運作" "zh_Hant": "這個自動販賣機仍運作",
"pt_BR": "Esta máquina de venda automática funciona"
} }
}, },
{ {
@ -129,7 +134,8 @@
"ru": "Этот торговый автомат сломан", "ru": "Этот торговый автомат сломан",
"zh_Hans": "这个借还机已经损坏", "zh_Hans": "这个借还机已经损坏",
"de": "Dieser Automat ist kaputt", "de": "Dieser Automat ist kaputt",
"zh_Hant": "這個自動販賣機沒有運作了" "zh_Hant": "這個自動販賣機沒有運作了",
"pt_BR": "Esta máquina de venda automática está quebrada"
} }
}, },
{ {
@ -143,7 +149,8 @@
"ru": "Этот торговый автомат закрыт", "ru": "Этот торговый автомат закрыт",
"zh_Hans": "这个借还机被关闭了", "zh_Hans": "这个借还机被关闭了",
"de": "Dieser Automat ist geschlossen", "de": "Dieser Automat ist geschlossen",
"zh_Hant": "這個自動販賣機已經關閉了" "zh_Hant": "這個自動販賣機已經關閉了",
"pt_BR": "Esta máquina de venda automática está fechada"
} }
} }
] ]

View file

@ -1 +1,143 @@
{} {
"bench": {
"tagRenderings": {
"3": {
"mappings": {
"0": {
"then": "Material: madeira"
},
"2": {
"then": "Material: pedra"
},
"3": {
"then": "Material: concreto"
},
"4": {
"then": "Material: plástico"
},
"5": {
"then": "Material: aço"
}
},
"question": "De que é feito o banco (assento)?"
},
"4": {
"question": "Em que direção você olha quando está sentado no banco?"
},
"5": {
"render": "Cor: {colour}",
"question": "Qual a cor dessa bancada?",
"mappings": {
"0": {
"then": "Cor: marrom"
},
"1": {
"then": "Cor: verde"
},
"2": {
"then": "Cor: cinza"
},
"3": {
"then": "Cor: branco"
},
"4": {
"then": "Cor: vermelho"
},
"5": {
"then": "Cor: preto"
},
"6": {
"then": "Cor: azul"
},
"7": {
"then": "Cor: amarelo"
}
}
},
"6": {
"question": "Quando esta bancada foi pesquisada pela última vez?",
"render": "Esta bancada foi pesquisada pela última vez em {survey:date}"
}
},
"presets": {
"0": {
"title": "Banco",
"description": "Adicionar um novo banco"
}
}
},
"bench_at_pt": {
"name": "Bancos em pontos de transporte público",
"title": {
"render": "Banco",
"mappings": {
"0": {
"then": "Banco em ponto de transporte público"
},
"1": {
"then": "Banco em abrigo"
}
}
},
"tagRenderings": {
"1": {
"render": "{name}"
}
}
},
"bicycle_library": {
"description": "Uma instalação onde as bicicletas podem ser emprestadas por períodos mais longos",
"tagRenderings": {
"6": {
"question": "Quanto custa um empréstimo de bicicleta?",
"render": "Custos de empréstimo de bicicleta {charge}",
"mappings": {
"0": {
"then": "Emprestar uma bicicleta é grátis"
}
}
},
"7": {
"question": "Quem pode emprestar bicicletas aqui?",
"mappings": {
"0": {
"then": "Bicicletas para crianças disponíveis"
},
"1": {
"then": "Bicicletas para adulto disponíveis"
},
"2": {
"then": "Bicicletas para deficientes físicos disponíveis"
}
}
}
}
},
"bicycle_tube_vending_machine": {
"name": "Máquina de venda automática de tubos de bicicleta",
"title": {
"render": "Máquina de venda automática de tubos de bicicleta"
},
"presets": {
"0": {
"title": "Máquina de venda automática de tubos de bicicleta"
}
},
"tagRenderings": {
"1": {
"question": "Esta máquina de venda automática ainda está operacional?",
"mappings": {
"0": {
"then": "Esta máquina de venda automática funciona"
},
"1": {
"then": "Esta máquina de venda automática está quebrada"
},
"2": {
"then": "Esta máquina de venda automática está fechada"
}
}
}
}
}
}

View file

@ -23,7 +23,12 @@
}, },
"general": { "general": {
"questions": { "questions": {
"phoneNumberOf": "Qual é o número de telefone de {category}?" "phoneNumberOf": "Qual é o número de telefone de {category}?",
"emailIs": "O endereço de e-mail deste {category} é <a href=\"mailto:{email}\" target=\"_blank\">{email}</a>",
"emailOf": "Qual é o endereço de e-mail de {category}?",
"websiteIs": "Site: <a href=\"{website}\" target=\"_blank\">{website}</a>",
"websiteOf": "Qual é o site de {category}?",
"phoneNumberIs": "O número de telefone deste {category} é <a target=\"_blank\">{phone}</a>"
}, },
"noNameCategory": "{category} sem nome", "noNameCategory": "{category} sem nome",
"nameInlineQuestion": "O nome desta {category} é $$$", "nameInlineQuestion": "O nome desta {category} é $$$",
@ -57,12 +62,90 @@
}, },
"loginToStart": "Faça login para responder a esta pergunta", "loginToStart": "Faça login para responder a esta pergunta",
"welcomeBack": "Você está logado, seja bem-vindo de volta!", "welcomeBack": "Você está logado, seja bem-vindo de volta!",
"loginWithOpenStreetMap": "Entrar com OpenStreetMap" "loginWithOpenStreetMap": "Entrar com OpenStreetMap",
"opening_hours": {
"ph_open": "aberto",
"ph_closed": "fechado",
"ph_not_known": " ",
"open_24_7": "Aberto 24 horas por dia",
"closed_permanently": "Fechado por tempo desconhecido",
"closed_until": "Fechado até {date}",
"not_all_rules_parsed": "O horário de funcionamento desta loja é complicado. As seguintes regras são ignoradas na entrada:",
"openTill": "até",
"opensAt": "desde",
"open_during_ph": "Durante um feriado, esse serviço está",
"error_loading": "Erro: não foi possível visualizar este horário de funcionamento."
},
"weekdays": {
"sunday": "Domingo",
"saturday": "Sábado",
"friday": "Sexta",
"thursday": "Quinta",
"wednesday": "Quanta",
"tuesday": "Terça",
"monday": "Segunda",
"abbreviations": {
"sunday": "Dom",
"saturday": "Sab",
"friday": "Sex",
"thursday": "Qui",
"wednesday": "Qua",
"tuesday": "Ter",
"monday": "Seg"
}
},
"layerSelection": {
"title": "Selecionar camadas",
"zoomInToSeeThisLayer": "Amplie para ver esta camada"
},
"backgroundMap": "Mapa de fundo",
"customThemeIntro": "<h3>Temas personalizados</h3> Esses são temas gerados pelo usuário visitados anteriormente.",
"noTagsSelected": "Nenhuma tag selecionada",
"getStartedNewAccount": " ou <a href=\"https://www.openstreetmap.org/user/new\" target=\"_blank\">crie uma nova conta</a>",
"getStartedLogin": "Entrar com OpenStreetMap para começar",
"goToInbox": "Abrir mensagens",
"fewChangesBefore": "Por favor, responda algumas perguntas de pontos existentes antes de adicionar um novo ponto.",
"readYourMessages": "Por favor, leia todas as suas mensagens do OpenStreetMap antes de adicionar um novo ponto.",
"sharescreen": {
"fsIncludeCurrentLocation": "Incluir localização atual",
"fsIncludeCurrentLayers": "Incluir as opções de camada atuais",
"fsIncludeCurrentBackgroundMap": "Incluir a escolha de fundo atual <b>{name}</b>",
"fsGeolocation": "Ative o botão 'localizar-me geograficamente' (apenas para celular)",
"fsAddNew": "Habilite o botão 'adicionar novo POI'",
"fsLayerControlToggle": "Iniciar com o controle de camada expandido",
"fsLayers": "Ativar o controle de camada",
"fsWelcomeMessage": "Mostra o pop-up da mensagem de boas-vindas e as guias associadas",
"fsSearch": "Ativar a barra de pesquisa",
"fsUserbadge": "Habilite o botão de login",
"editThemeDescription": "Adicione ou altere perguntas a este tema do mapa",
"editThisTheme": "Editar neste tema",
"thanksForSharing": "Obrigado por compartilhar!",
"copiedToClipboard": "Link copiado para a área de transferência",
"addToHomeScreen": "<h3>Adicionar à sua tela inicial</h3>Você pode adicionar facilmente este site à tela inicial do smartphone para uma sensação nativa. Clique no botão 'adicionar à tela inicial' na barra de URL para fazer isso.",
"intro": "<h3>Compartilhe este mapa</h3> Compartilhe este mapa copiando o link abaixo e enviando-o para amigos e familiares:"
}
}, },
"index": { "index": {
"pickTheme": "Escolha um tema abaixo para começar.", "pickTheme": "Escolha um tema abaixo para começar.",
"intro": "MapComplete é um visualizador e editor do OpenStreetMap, que mostra informações sobre um tema específico.", "intro": "MapComplete é um visualizador e editor do OpenStreetMap, que mostra informações sobre um tema específico.",
"title": "Bem-vindo(a) ao MapComplete", "title": "Bem-vindo(a) ao MapComplete",
"#": "Estes textos são mostrados acima dos botões do tema quando nenhum tema é carregado" "#": "Estes textos são mostrados acima dos botões do tema quando nenhum tema é carregado"
},
"reviews": {
"plz_login": "Entrar para deixar um comentário",
"saved": "<span class=\"thanks\">Comentário salvo. Obrigado por compartilhar!</span>",
"saving_review": "Salvando…",
"i_am_affiliated": "<span>Eu sou afiliado a este objeto</span><br><span class=\"subtle\"><br><span class=\"subtle\">Verifique se você é proprietário, criador, funcionário, …</span></span>",
"posting_as": "Postando como",
"no_rating": "Nenhuma classificação dada",
"write_a_comment": "Deixe um comentário…",
"no_reviews_yet": "Não há comentários ainda. Seja o primeiro a escrever um e ajude a abrir os dados e os negócios!",
"name_required": "É necessário um nome para exibir e criar comentários",
"title_singular": "Um comentário",
"title": "{count} comentários"
},
"favourite": {
"reload": "Recarregar dados",
"panelIntro": "<h3>Seu tema pessoal</h3>Ative suas camadas favoritas de todos os temas oficiais"
} }
} }

View file

@ -40,7 +40,7 @@
}, },
"loginToStart": "Войдите, чтобы ответить на этот вопрос", "loginToStart": "Войдите, чтобы ответить на этот вопрос",
"welcomeBack": "Вы вошли, с возвращением!", "welcomeBack": "Вы вошли, с возвращением!",
"loginWithOpenStreetMap": "Войти с OpenStreetMap", "loginWithOpenStreetMap": "Войти с помощью OpenStreetMap",
"opening_hours": { "opening_hours": {
"ph_not_known": " ", "ph_not_known": " ",
"ph_open": "открыта", "ph_open": "открыта",
@ -81,7 +81,7 @@
"customThemeIntro": "<h3>Пользовательские темы</h3>Это ранее просмотренные темы, созданные пользователями.", "customThemeIntro": "<h3>Пользовательские темы</h3>Это ранее просмотренные темы, созданные пользователями.",
"noTagsSelected": "Теги не выбраны", "noTagsSelected": "Теги не выбраны",
"getStartedNewAccount": " или <a href=\"https://www.openstreetmap.org/user/new\" target=\"_blank\">создать новую учетную запись</a>", "getStartedNewAccount": " или <a href=\"https://www.openstreetmap.org/user/new\" target=\"_blank\">создать новую учетную запись</a>",
"getStartedLogin": "Войти с OpenStreetMap, чтобы начать работу", "getStartedLogin": "Войти с помощью OpenStreetMap, чтобы начать работу",
"goToInbox": "Открыть входящие сообщения", "goToInbox": "Открыть входящие сообщения",
"fewChangesBefore": "Пожалуйста, ответьте на несколько вопросов о существующих точках, прежде чем добавить новую точку.", "fewChangesBefore": "Пожалуйста, ответьте на несколько вопросов о существующих точках, прежде чем добавить новую точку.",
"readYourMessages": "Пожалуйста, прочитайте все ваши сообщения на сайте OpenStreetMap перед тем как добавлять новую точку.", "readYourMessages": "Пожалуйста, прочитайте все ваши сообщения на сайте OpenStreetMap перед тем как добавлять новую точку.",

View file

@ -1,2 +0,0 @@
npm run start
cmd /k