From d8d2689fa8b0d94b5b0bb11356f90bdf52759463 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Mon, 28 Mar 2022 01:27:03 +0200 Subject: [PATCH 01/37] Version bump --- Models/Constants.ts | 2 +- assets/themes/climbing/climbing.json | 47 ++++++++++++++-------------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/Models/Constants.ts b/Models/Constants.ts index 7f6124ad34..766f1762b9 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import {Utils} from "../Utils"; export default class Constants { - public static vNumber = "0.17.0"; + public static vNumber = "0.18.0-alpha"; public static ImgurApiKey = '7070e7167f0a25a' public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85" diff --git a/assets/themes/climbing/climbing.json b/assets/themes/climbing/climbing.json index 9a13c7e6c4..550131a869 100644 --- a/assets/themes/climbing/climbing.json +++ b/assets/themes/climbing/climbing.json @@ -224,14 +224,14 @@ "point", "centroid" ], - "label": { - "mappings": [ - { - "if": "name~*", - "then": "
{name}
" + "label": { + "mappings": [ + { + "if": "name~*", + "then": "
{name}
" + } + ] } - ] - } } ] }, @@ -340,14 +340,15 @@ "location": [ "point", "centroid" - ], "label": { - "mappings": [ - { - "if": "name~*", - "then": "
{name}
" + ], + "label": { + "mappings": [ + { + "if": "name~*", + "then": "
{name}
" + } + ] } - ] - } } ] }, @@ -583,15 +584,15 @@ "location": [ "point", "centroid" - ], "label": { - "mappings": [ - { - "if": "name~*", - "then": "
{name}
" + ], + "label": { + "mappings": [ + { + "if": "name~*", + "then": "
{name}
" + } + ] } - ] - } - }, { "color": { @@ -1692,4 +1693,4 @@ } ] } -} +} \ No newline at end of file From c8e013f30eb2df8b5778e30d932f9fa69fa1cf08 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Mon, 28 Mar 2022 21:56:25 +0200 Subject: [PATCH 02/37] Fix 'moveToLocation' for bounded themes, add test --- Logic/Actors/GeoLocationHandler.ts | 77 +++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/Logic/Actors/GeoLocationHandler.ts b/Logic/Actors/GeoLocationHandler.ts index 7d3aca2c31..8eba88e44d 100644 --- a/Logic/Actors/GeoLocationHandler.ts +++ b/Logic/Actors/GeoLocationHandler.ts @@ -5,6 +5,7 @@ import {VariableUiElement} from "../../UI/Base/VariableUIElement"; import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; import {QueryParameters} from "../Web/QueryParameters"; import FeatureSource from "../FeatureSource/FeatureSource"; +import {BBox} from "../BBox"; export interface GeoLocationPointProperties { id: "gps", @@ -20,7 +21,7 @@ export interface GeoLocationPointProperties { export default class GeoLocationHandler extends VariableUiElement { - private readonly currentLocation: FeatureSource + private readonly currentLocation?: FeatureSource /** * Wether or not the geolocation is active, aka the user requested the current location @@ -71,7 +72,7 @@ export default class GeoLocationHandler extends VariableUiElement { constructor( state: { selectedElement: UIEventSource; - currentUserLocation: FeatureSource, + currentUserLocation?: FeatureSource, leafletMap: UIEventSource, layoutToUse: LayoutConfig, featureSwitchGeolocation: UIEventSource @@ -217,14 +218,14 @@ export default class GeoLocationHandler extends VariableUiElement { } } - self.currentLocation.features.setData([{feature, freshness: new Date()}]) + self.currentLocation?.features?.setData([{feature, freshness: new Date()}]) const timeSinceRequest = (new Date().getTime() - (self._lastUserRequest?.getTime() ?? 0)) / 1000; if (timeSinceRequest < 30) { - self.MoveToCurrentLoction(16); + self.MoveToCurrentLocation(16); } else if (self._isLocked.data) { - self.MoveToCurrentLoction(); + self.MoveToCurrentLocation(); } }); @@ -235,9 +236,13 @@ export default class GeoLocationHandler extends VariableUiElement { const self = this; if (self._isActive.data) { - self.MoveToCurrentLoction(16); + self.MoveToCurrentLocation(16); return; } + + if(typeof navigator === "undefined"){ + return + } try { navigator?.permissions @@ -264,7 +269,57 @@ export default class GeoLocationHandler extends VariableUiElement { } } - private MoveToCurrentLoction(targetZoom?: number) { + /** + * Moves to the currently loaded location. + * + * // Should move to any location + * let resultingLocation = undefined + * let resultingzoom = 1 + * const state = { + * selectedElement: new UIEventSource(undefined); + * currentUserLocation: undefined , + * leafletMap: new UIEventSource({getZoom: () => resultingzoom; setView: (loc, zoom) => {resultingLocation = loc; resultingzoom = zoom}), + * layoutToUse: new LayoutConfig({ + * id: 'test', + * title: {"en":"test"} + * description: "A testing theme", + * layers: [] + * }), + * featureSwitchGeolocation : new UIEventSource(true) + * } + * const handler = new GeoLocationHandler(state) + * handler._currentGPSLocation.setData( {latitude : 51.3, longitude: 4.1}) + * handler.MoveToCurrentLocation() + * resultingLocation // => [51.3, 4.1] + * handler._currentGPSLocation.setData( {latitude : 60, longitude: 60) // out of bounds + * handler.MoveToCurrentLocation() + * resultingLocation // => [60, 60] + * + * // should refuse to move if out of bounds + * let resultingLocation = undefined + * let resultingzoom = 1 + * const state = { + * selectedElement: new UIEventSource(undefined); + * currentUserLocation: undefined , + * leafletMap: new UIEventSource({getZoom: () => resultingzoom; setView: (loc, zoom) => {resultingLocation = loc; resultingzoom = zoom}), + * layoutToUse: new LayoutConfig({ + * id: 'test', + * title: {"en":"test"} + * "lockLocation": [ [ 2.1, 50.4], [6.4, 51.54 ]], + * description: "A testing theme", + * layers: [] + * }), + * featureSwitchGeolocation : new UIEventSource(true) + * } + * const handler = new GeoLocationHandler(state) + * handler._currentGPSLocation.setData( {latitude : 51.3, longitude: 4.1}) + * handler.MoveToCurrentLocation() + * resultingLocation // => [51.3, 4.1] + * handler._currentGPSLocation.setData( {latitude : 60, longitude: 60) // out of bounds + * handler.MoveToCurrentLocation() + * resultingLocation // => [51.3, 4.1] + */ + private MoveToCurrentLocation(targetZoom?: number) { const location = this._currentGPSLocation.data; this._lastUserRequest = undefined; @@ -282,11 +337,7 @@ export default class GeoLocationHandler extends VariableUiElement { if (b) { if (b !== true) { // B is an array with our locklocation - inRange = - b[0][0] <= location.latitude && - location.latitude <= b[1][0] && - b[0][1] <= location.longitude && - location.longitude <= b[1][1]; + inRange = new BBox(b).contains([location.longitude, location.latitude]) } } if (!inRange) { @@ -312,7 +363,7 @@ export default class GeoLocationHandler extends VariableUiElement { return ""; } if (this._currentGPSLocation.data !== undefined) { - this.MoveToCurrentLoction(16); + this.MoveToCurrentLocation(16); } if (self._isActive.data) { From 8df032457253026d16d859f237626473a19d6f37 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Mon, 28 Mar 2022 22:20:36 +0200 Subject: [PATCH 03/37] Add website to playground theme --- assets/layers/playground/playground.json | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/layers/playground/playground.json b/assets/layers/playground/playground.json index b8eff0c6e7..e7bc7076e1 100644 --- a/assets/layers/playground/playground.json +++ b/assets/layers/playground/playground.json @@ -346,6 +346,7 @@ } ] }, + "website", { "question": { "nl": "Wie kan men emailen indien er problemen zijn met de speeltuin?", From c47a6d5ea757e8dc56cc8f1f0cc927a08305e71a Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Tue, 29 Mar 2022 00:20:10 +0200 Subject: [PATCH 04/37] Add rewrite of 'special' clauses, various QOLimprovements on import viewer --- Docs/Tools/GenerateSeries.ts | 3 + Models/ThemeConfig/Conversion/Conversion.ts | 27 ++- Models/ThemeConfig/Conversion/PrepareLayer.ts | 168 ++++++++++++++++-- Models/ThemeConfig/Json/LayerConfigJson.ts | 2 +- Models/ThemeConfig/LayerConfig.ts | 4 +- Models/ThemeConfig/PresetConfig.ts | 2 +- UI/Base/Table.ts | 57 +++++- UI/BigComponents/Histogram.ts | 5 +- UI/ImportFlow/ImportViewerGui.ts | 118 ++++++++---- UI/OpeningHours/OpeningHoursVisualization.ts | 2 +- UI/Popup/AutoApplyButton.ts | 14 +- UI/Popup/ImportButton.ts | 122 +++++++------ UI/SpecialVisualizations.ts | 53 ++++-- Utils.ts | 8 +- assets/layers/note/note.json | 2 +- assets/svg/license_info.json | 10 ++ assets/svg/party.svg | 1 + .../toerisme_vlaanderen/license_info.json | 66 +++++++ assets/themes/uk_addresses/uk_addresses.json | 11 +- css/index-tailwind-output.css | 5 +- .../Conversion/PrepareLayer.spec.ts | 53 ++++-- tests/UI/SpecialVisualisations.spec.ts | 19 ++ 22 files changed, 597 insertions(+), 155 deletions(-) create mode 100644 assets/svg/party.svg create mode 100644 tests/UI/SpecialVisualisations.spec.ts diff --git a/Docs/Tools/GenerateSeries.ts b/Docs/Tools/GenerateSeries.ts index 1c0a4d0432..ca68ff1ded 100644 --- a/Docs/Tools/GenerateSeries.ts +++ b/Docs/Tools/GenerateSeries.ts @@ -181,6 +181,9 @@ class ChangesetDataTools { cs.properties.metadata.host = new URL(cs.properties.metadata.host).host } catch (e) { + } + if(cs.properties.metadata["answer"] > 100){ + console.log("Lots of answers for https://osm.org/changeset/"+cs.id) } return cs } diff --git a/Models/ThemeConfig/Conversion/Conversion.ts b/Models/ThemeConfig/Conversion/Conversion.ts index 75f1683f2a..6be0b2756c 100644 --- a/Models/ThemeConfig/Conversion/Conversion.ts +++ b/Models/ThemeConfig/Conversion/Conversion.ts @@ -42,7 +42,7 @@ export abstract class Conversion { public convertAll(jsons: TIn[], context: string): { result: TOut[], errors: string[], warnings: string[], information?: string[] } { if(jsons === undefined || jsons === null){ - throw "convertAll received undefined or null - don't do this (at "+context+")" + throw `Detected a bug in the preprocessor pipeline: ${this.name}.convertAll received undefined or null - don't do this (at ${context})` } const result = [] const errors = [] @@ -72,23 +72,34 @@ export abstract class DesugaringStep extends Conversion { export class OnEvery extends DesugaringStep { private readonly key: string; private readonly step: DesugaringStep; + private _options: { ignoreIfUndefined: boolean }; - constructor(key: string, step: DesugaringStep) { + constructor(key: string, step: DesugaringStep, options?: { + ignoreIfUndefined: false | boolean + }) { super("Applies " + step.name + " onto every object of the list `key`", [key], "OnEvery("+step.name+")"); this.step = step; this.key = key; + this._options = options; } convert(json: T, context: string): { result: T; errors?: string[]; warnings?: string[], information?: string[] } { json = {...json} const step = this.step const key = this.key; - const r = step.convertAll((json[key]), context + "." + key) - json[key] = r.result - return { - ...r, - result: json, - }; + if( this._options?.ignoreIfUndefined && json[key] === undefined){ + return { + result: json, + }; + }else{ + const r = step.convertAll((json[key]), context + "." + key) + json[key] = r.result + return { + ...r, + result: json, + }; + } + } } diff --git a/Models/ThemeConfig/Conversion/PrepareLayer.ts b/Models/ThemeConfig/Conversion/PrepareLayer.ts index 1958535774..f251a539f5 100644 --- a/Models/ThemeConfig/Conversion/PrepareLayer.ts +++ b/Models/ThemeConfig/Conversion/PrepareLayer.ts @@ -1,10 +1,12 @@ -import {Conversion, DesugaringContext, Fuse, OnEvery, OnEveryConcat, SetDefault} from "./Conversion"; +import {Conversion, DesugaringContext, DesugaringStep, Fuse, OnEvery, OnEveryConcat, SetDefault} from "./Conversion"; import {LayerConfigJson} from "../Json/LayerConfigJson"; import {TagRenderingConfigJson} from "../Json/TagRenderingConfigJson"; import {Utils} from "../../../Utils"; +import RewritableConfigJson from "../Json/RewritableConfigJson"; +import SpecialVisualizations from "../../../UI/SpecialVisualizations"; import Translations from "../../../UI/i18n/Translations"; import {Translation} from "../../../UI/i18n/Translation"; -import RewritableConfigJson from "../Json/RewritableConfigJson"; +import * as tagrenderingconfigmeta from "../../../assets/tagrenderingconfigmeta.json" class ExpandTagRendering extends Conversion { private readonly _state: DesugaringContext; @@ -349,28 +351,168 @@ class ExpandRewrite extends Conversion, T[]> { } - -class ExpandRewriteWithFlatten extends Conversion, T[]> { - - private _rewrite = new ExpandRewrite() - +/** + * Converts a 'special' translation into a regular translation which uses parameters + * E.g. + * + * const tr = { + * "special": + * } + */ +export class RewriteSpecial extends DesugaringStep { constructor() { - super("Applies a rewrite, the result is flattened if it is an array", [], "ExpandRewriteWithFlatten"); + super("Converts a 'special' translation into a regular translation which uses parameters", ["special"],"RewriteSpecial"); } - convert(json: RewritableConfigJson | T, context: string): { result: T[]; errors?: string[]; warnings?: string[]; information?: string[] } { - return undefined; + /** + * Does the heavy lifting and conversion + * + * // should not do anything if no 'special'-key is present + * RewriteSpecial.convertIfNeeded({"en": "xyz", "nl": "abc"}, [], "test") // => {"en": "xyz", "nl": "abc"} + * + * // should handle a simple special case + * RewriteSpecial.convertIfNeeded({"special": {"type":"image_carousel"}}, [], "test") // => {'*': "{image_carousel()}"} + * + * // should handle special case with a parameter + * RewriteSpecial.convertIfNeeded({"special": {"type":"image_carousel", "image_key": "some_image_key"}}, [], "test") // => {'*': "{image_carousel(some_image_key)}"} + * + * // should handle special case with a translated parameter + * const spec = {"special": {"type":"image_upload", "label": {"en": "Add a picture to this object", "nl": "Voeg een afbeelding toe"}}} + * const r = RewriteSpecial.convertIfNeeded(spec, [], "test") + * r // => {"en": "{image_upload(,Add a picture to this object)}", "nl": "{image_upload(,Voeg een afbeelding toe)}" } + * + * // should warn for unexpected keys + * const errors = [] + * RewriteSpecial.convertIfNeeded({"special": {type: "image_carousel"}, "en": "xyz"}, errors, "test") // => {'*': "{image_carousel()}"} + * errors // => ["At test: Unexpected key in a special block: en"] + * + * // should give an error on unknown visualisations + * const errors = [] + * RewriteSpecial.convertIfNeeded({"special": {type: "qsdf"}}, errors, "test") // => undefined + * errors.length // => 1 + * errors[0].indexOf("Special visualisation 'qsdf' not found") >= 0 // => true + * + * // should give an error is 'type' is missing + * const errors = [] + * RewriteSpecial.convertIfNeeded({"special": {}}, errors, "test") // => undefined + * errors // => ["A 'special'-block should define 'type' to indicate which visualisation should be used"] + */ + private static convertIfNeeded(input: (object & {special : {type: string}}) | any, errors: string[], context: string): any { + const special = input["special"] + if(special === undefined){ + return input + } + + for (const wrongKey of Object.keys(input).filter(k => k !== "special")) { + errors.push(`At ${context}: Unexpected key in a special block: ${wrongKey}`) + } + + const type = special["type"] + if(type === undefined){ + errors.push("A 'special'-block should define 'type' to indicate which visualisation should be used") + return undefined + } + const vis = SpecialVisualizations.specialVisualizations.find(sp => sp.funcName === type) + if(vis === undefined){ + const options = Utils.sortedByLevenshteinDistance(type, SpecialVisualizations.specialVisualizations, sp => sp.funcName) + errors.push(`Special visualisation '${type}' not found. Did you perhaps mean ${options[0].funcName}, ${options[1].funcName} or ${options[2].funcName}?\n\tFor all known special visualisations, please see https://github.com/pietervdvn/MapComplete/blob/develop/Docs/SpecialRenderings.md`) + return undefined + } + + const argNamesList = vis.args.map(a => a.name) + const argNames = new Set(argNamesList) + // Check for obsolete and misspelled arguments + errors.push(...Object.keys(special) + .filter(k => !argNames.has(k)) + .filter(k => k !== "type") + .map(wrongArg => { + const byDistance = Utils.sortedByLevenshteinDistance(wrongArg, argNamesList, x => x) + return `Unexpected argument with name '${wrongArg}'. Did you mean ${byDistance[0]}?\n\tAll known arguments are ${ argNamesList.join(", ")}` ; + })) + + // Check that all obligated arguments are present. They are obligated if they don't have a preset value + for (const arg of vis.args) { + if (arg.required !== true) { + continue; + } + const param = special[arg.name] + if(param === undefined){ + errors.push(`Obligated parameter '${arg.name}' not found`) + } + } + + const foundLanguages = new Set() + const translatedArgs = argNamesList.map(nm => special[nm]) + .filter(v => v !== undefined) + .filter(v => Translations.isProbablyATranslation(v)) + for (const translatedArg of translatedArgs) { + for (const ln of Object.keys(translatedArg)) { + foundLanguages.add(ln) + } + } + + if(foundLanguages.size === 0){ + const args= argNamesList.map(nm => special[nm] ?? "").join(",") + return {'*': `{${type}(${args})}` + } + } + + const result = {} + const languages = Array.from(foundLanguages) + languages.sort() + for (const ln of languages) { + const args = [] + for (const argName of argNamesList) { + const v = special[argName] ?? "" + if(Translations.isProbablyATranslation(v)){ + args.push(new Translation(v).textFor(ln)) + }else{ + args.push(v) + } + } + result[ln] = `{${type}(${args.join(",")})}` + } + return result } - + /** + * const tr = { + * render: {special: {type: "image_carousel", image_key: "image" }}, + * mappings: [ + * { + * if: "other_image_key", + * then: {special: {type: "image_carousel", image_key: "other_image_key"}} + * } + * ] + * } + * const result = new RewriteSpecial().convert(tr,"test").result + * const expected = {render: {'*': "{image_carousel(image)}"}, mappings: [{if: "other_image_key", then: {'*': "{image_carousel(other_image_key)}"}} ]} + * result // => expected + */ + convert(json: TagRenderingConfigJson, context: string): { result: TagRenderingConfigJson; errors?: string[]; warnings?: string[]; information?: string[] } { + const errors = [] + json = Utils.Clone(json) + const paths : {path: string[], type?: any, typeHint?: string}[] = tagrenderingconfigmeta["default"] ?? tagrenderingconfigmeta + for (const path of paths) { + if(path.typeHint !== "rendered"){ + continue + } + Utils.WalkPath(path.path, json, ((leaf, travelled) => RewriteSpecial.convertIfNeeded(leaf, errors, travelled.join(".")))) + } + + return { + result:json, + errors + }; + } + } export class PrepareLayer extends Fuse { - - constructor(state: DesugaringContext) { super( "Fully prepares and expands a layer for the LayerConfig.", + new OnEvery("tagRenderings", new RewriteSpecial(), {ignoreIfUndefined: true}), new OnEveryConcat("tagRenderings", new ExpandGroupRewrite(state)), new OnEveryConcat("tagRenderings", new ExpandTagRendering(state)), new OnEveryConcat("mapRendering", new ExpandRewrite()), diff --git a/Models/ThemeConfig/Json/LayerConfigJson.ts b/Models/ThemeConfig/Json/LayerConfigJson.ts index 9bc71e38fc..0839d7ec73 100644 --- a/Models/ThemeConfig/Json/LayerConfigJson.ts +++ b/Models/ThemeConfig/Json/LayerConfigJson.ts @@ -234,7 +234,7 @@ export interface LayerConfigJson { /** * The type of background picture */ - preferredBackground: "osmbasedmap" | "photo" | "historicphoto" | "map" | string | string [], + preferredBackground: "osmbasedmap" | "photo" | "historicphoto" | "map" | string | string[], /** * If specified, these layers will be shown to and the new point will be snapped towards it */ diff --git a/Models/ThemeConfig/LayerConfig.ts b/Models/ThemeConfig/LayerConfig.ts index 405cf59be2..8a080f00f5 100644 --- a/Models/ThemeConfig/LayerConfig.ts +++ b/Models/ThemeConfig/LayerConfig.ts @@ -197,14 +197,14 @@ export default class LayerConfig extends WithContextLoader { snapToLayers = pr.preciseInput.snapToLayer } - let preferredBackground: string[] + let preferredBackground: ("map" | "photo" | "osmbasedmap" | "historicphoto" | string)[] if (typeof pr.preciseInput.preferredBackground === "string") { preferredBackground = [pr.preciseInput.preferredBackground] } else { preferredBackground = pr.preciseInput.preferredBackground } preciseInput = { - preferredBackground: preferredBackground, + preferredBackground, snapToLayers, maxSnapDistance: pr.preciseInput.maxSnapDistance ?? 10 } diff --git a/Models/ThemeConfig/PresetConfig.ts b/Models/ThemeConfig/PresetConfig.ts index 4522d90792..a9e68050c0 100644 --- a/Models/ThemeConfig/PresetConfig.ts +++ b/Models/ThemeConfig/PresetConfig.ts @@ -2,7 +2,7 @@ import {Translation} from "../../UI/i18n/Translation"; import {Tag} from "../../Logic/Tags/Tag"; export interface PreciseInput { - preferredBackground?: string[], + preferredBackground?: ("map" | "photo" | "osmbasedmap" | "historicphoto" | string)[], snapToLayers?: string[], maxSnapDistance?: number } diff --git a/UI/Base/Table.ts b/UI/Base/Table.ts index a26f4a025a..9ffa4317ce 100644 --- a/UI/Base/Table.ts +++ b/UI/Base/Table.ts @@ -1,20 +1,26 @@ import BaseUIElement from "../BaseUIElement"; import {Utils} from "../../Utils"; import Translations from "../i18n/Translations"; +import {UIEventSource} from "../../Logic/UIEventSource"; export default class Table extends BaseUIElement { private readonly _header: BaseUIElement[]; private readonly _contents: BaseUIElement[][]; private readonly _contentStyle: string[][]; - + private readonly _sortable: boolean; + constructor(header: (BaseUIElement | string)[], contents: (BaseUIElement | string)[][], - contentStyle?: string[][]) { + options?: { + contentStyle?: string[][], + sortable?: false | boolean + }) { super(); - this._contentStyle = contentStyle ?? [["min-width: 9rem"]]; + this._contentStyle = options?.contentStyle ?? [["min-width: 9rem"]]; this._header = header?.map(Translations.W); this._contents = contents.map(row => row.map(Translations.W)); + this._sortable = options?.sortable ?? false } AsMarkdown(): string { @@ -30,7 +36,25 @@ export default class Table extends BaseUIElement { protected InnerConstructElement(): HTMLElement { const table = document.createElement("table") - const headerElems = Utils.NoNull((this._header ?? []).map(elems => elems.ConstructElement())) + /** + * Sortmode: i: sort column i ascending; + * if i is negative : sort column (-i - 1) descending + */ + const sortmode = new UIEventSource(undefined); + const self = this; + const headerElems = Utils.NoNull((this._header ?? []).map((elem, i) => { + if(self._sortable){ + elem.onClick(() => { + const current = sortmode.data + if(current == i){ + sortmode.setData(- 1 - i ) + }else{ + sortmode.setData(i) + } + }) + } + return elem.ConstructElement(); + })) if (headerElems.length > 0) { const thead = document.createElement("thead") @@ -73,6 +97,31 @@ export default class Table extends BaseUIElement { } table.appendChild(tr) } + + sortmode.addCallback(sortCol => { + if(sortCol === undefined){ + return + } + const descending = sortCol < 0 + const col = descending ? - sortCol - 1: sortCol; + let rows: HTMLTableRowElement[] = Array.from(table.rows) + rows.splice(0,1) // remove header row + rows = rows.sort((a, b) => { + const ac = a.cells[col]?.innerText?.toLowerCase() + const bc = b.cells[col]?.innerText?.toLowerCase() + if(ac === bc){ + return 0 + } + return( ac < bc !== descending) ? -1 : 1; + }) + for (let j = rows.length ; j > 1; j--) { + table.deleteRow(j) + } + for (const row of rows) { + table.appendChild(row) + } + }) + return table; } diff --git a/UI/BigComponents/Histogram.ts b/UI/BigComponents/Histogram.ts index d786fbf5da..ba1387dddf 100644 --- a/UI/BigComponents/Histogram.ts +++ b/UI/BigComponents/Histogram.ts @@ -128,8 +128,9 @@ export default class Histogram extends VariableUiElement { .SetStyle(`background: ${actualAssignColor(key)}; width: ${100 * counts.get(key) / max}%`) ]).SetClass("block w-full") - ]), - keys.map(_ => ["width: 20%"]) + ]),{ + contentStyle:keys.map(_ => ["width: 20%"]) + } ).SetClass("w-full zebra-table"); }, [sortMode])); } diff --git a/UI/ImportFlow/ImportViewerGui.ts b/UI/ImportFlow/ImportViewerGui.ts index f0af1f059d..2c427bd9c5 100644 --- a/UI/ImportFlow/ImportViewerGui.ts +++ b/UI/ImportFlow/ImportViewerGui.ts @@ -139,16 +139,59 @@ class MassAction extends Combine { } +class NoteTable extends Combine { + + constructor(noteStates: NoteState[], state?: UserRelatedState) { + const typicalComment = noteStates[0].props.comments[0].html + + const table = new Table( + ["id", "status", "last comment", "last modified by"], + noteStates.map(ns => { + const link = new Link( + "" + ns.props.id, + "https://openstreetmap.org/note/" + ns.props.id, true + ) + let last_comment = ""; + const last_comment_props = ns.props.comments[ns.props.comments.length - 1] + const before_last_comment = ns.props.comments[ns.props.comments.length - 2] + if (ns.props.comments.length > 1) { + last_comment = last_comment_props.text + if (last_comment === undefined && before_last_comment?.uid === last_comment_props.uid) { + last_comment = before_last_comment.text + } + } + const statusIcon = BatchView.icons[ns.status]().SetClass("h-4 w-4 shrink-0") + return [link, new Combine([statusIcon, ns.status]).SetClass("flex"), last_comment, + new Link(last_comment_props.user, "https://www.openstreetmap.org/user/" + last_comment_props.user, true) + ] + }), + {sortable: true} + ).SetClass("zebra-table link-underline"); + + + super([ + new Title("Mass apply an action on " + noteStates.length + " notes below"), + state !== undefined ? new MassAction(state, noteStates.map(ns => ns.props)).SetClass("block") : undefined, + table, + new Title("Example note", 4), + new FixedUiElement(typicalComment).SetClass("literal-code link-underline"), + + ]) + this.SetClass("flex flex-col") + } + +} + class BatchView extends Toggleable { - private static icons = { + public static icons = { open: Svg.compass_svg, has_comments: Svg.speech_bubble_svg, imported: Svg.addSmall_svg, already_mapped: Svg.checkmark_svg, - invalid: Svg.invalid_svg, - closed: Svg.close_svg, not_found: Svg.not_found_svg, + closed: Svg.close_svg, + invalid: Svg.invalid_svg, } constructor(noteStates: NoteState[], state?: UserRelatedState) { @@ -164,14 +207,44 @@ class BatchView extends Toggleable { statusHist.set(st, c + 1) } - const badges: (BaseUIElement)[] = [new FixedUiElement(dateStr).SetClass("literal-code rounded-full")] - statusHist.forEach((count, status) => { - const icon = BatchView.icons[status]().SetClass("h-6 m-1") - badges.push(new Combine([icon, count + " " + status]) - .SetClass("flex ml-1 mb-1 pl-1 pr-3 items-center rounded-full border border-black")) + const unresolvedTotal = (statusHist.get("open") ?? 0) + (statusHist.get("has_comments") ?? 0) + const badges: (BaseUIElement)[] = [ + new FixedUiElement(dateStr).SetClass("literal-code rounded-full"), + new FixedUiElement(noteStates.length + " total").SetClass("literal-code rounded-full ml-1 border-4 border-gray") + .onClick(() => filterOn.setData(undefined)), + unresolvedTotal === 0 ? + new Combine([Svg.party_svg().SetClass("h-6 m-1"), "All done!"]) + .SetClass("flex ml-1 mb-1 pl-1 pr-3 items-center rounded-full border border-black") : + new FixedUiElement(Math.round(100 - 100 * unresolvedTotal / noteStates.length) + "%").SetClass("literal-code rounded-full ml-1") + ] + + const filterOn = new UIEventSource(undefined) + Object.keys(BatchView.icons).forEach(status => { + const count = statusHist.get(status) + if (count === undefined) { + return undefined + } + + const normal = new Combine([BatchView.icons[status]().SetClass("h-6 m-1"), count + " " + status]) + .SetClass("flex ml-1 mb-1 pl-1 pr-3 items-center rounded-full border border-black") + const selected = new Combine([BatchView.icons[status]().SetClass("h-6 m-1"), count + " " + status]) + .SetClass("flex ml-1 mb-1 pl-1 pr-3 items-center rounded-full border-4 border-black animate-pulse") + + const toggle = new Toggle(selected, normal, filterOn.map(f => f === status, [], (selected, previous) => { + if (selected) { + return status; + } + if (previous === status) { + return undefined + } + return previous + })).ToggleOnClick() + + badges.push(toggle) }) - const typicalComment = noteStates[0].props.comments[0].html + + const fullTable = new NoteTable(noteStates, state); super( @@ -179,27 +252,12 @@ class BatchView extends Toggleable { new Title(theme + ": " + intro, 2), new Combine(badges).SetClass("flex flex-wrap"), ]), - new Combine([ - new Title("Example note", 4), - new FixedUiElement(typicalComment).SetClass("literal-code link-underline"), - new Title("Mass apply an action"), - state !== undefined ? new MassAction(state, noteStates.map(ns => ns.props)).SetClass("block") : undefined, - new Table( - ["id", "status", "last comment"], - noteStates.map(ns => { - const link = new Link( - "" + ns.props.id, - "https://openstreetmap.org/note/" + ns.props.id, true - ) - let last_comment = ""; - if (ns.props.comments.length > 1) { - last_comment = ns.props.comments[ns.props.comments.length - 1].text - } - const statusIcon = BatchView.icons[ns.status]().SetClass("h-4 w-4 shrink-0") - return [link, new Combine([statusIcon, ns.status]).SetClass("flex"), last_comment] - }) - ).SetClass("zebra-table link-underline") - ]).SetClass("flex flex-col"), + new VariableUiElement(filterOn.map(filter => { + if (filter === undefined) { + return fullTable + } + return new NoteTable(noteStates.filter(ns => ns.status === filter), state) + })), { closeOnClick: false }) diff --git a/UI/OpeningHours/OpeningHoursVisualization.ts b/UI/OpeningHours/OpeningHoursVisualization.ts index 41744a4897..b3e94c7ae5 100644 --- a/UI/OpeningHours/OpeningHoursVisualization.ts +++ b/UI/OpeningHours/OpeningHoursVisualization.ts @@ -168,7 +168,7 @@ export default class OpeningHoursVisualization extends Toggle { } return new Table(undefined, [[" ", header], ...weekdays], - [["width: 5%", `position: relative; height: ${headerHeight}`], ...weekdayStyles] + {contentStyle: [["width: 5%", `position: relative; height: ${headerHeight}`], ...weekdayStyles]} ).SetClass("w-full") .SetStyle("border-collapse: collapse; word-break; word-break: normal; word-wrap: normal") diff --git a/UI/Popup/AutoApplyButton.ts b/UI/Popup/AutoApplyButton.ts index 27c1d2a482..0956a56c53 100644 --- a/UI/Popup/AutoApplyButton.ts +++ b/UI/Popup/AutoApplyButton.ts @@ -156,22 +156,26 @@ class ApplyButton extends UIElement { export default class AutoApplyButton implements SpecialVisualization { public readonly docs: string; public readonly funcName: string = "auto_apply"; - public readonly args: { name: string; defaultValue?: string; doc: string }[] = [ + public readonly args: { name: string; defaultValue?: string; doc: string, required?: boolean }[] = [ { name: "target_layer", - doc: "The layer that the target features will reside in" + doc: "The layer that the target features will reside in", + required: true }, { name: "target_feature_ids", - doc: "The key, of which the value contains a list of ids" + doc: "The key, of which the value contains a list of ids", + required: true }, { name: "tag_rendering_id", - doc: "The ID of the tagRendering containing the autoAction. This tagrendering will be calculated. The embedded actions will be executed" + doc: "The ID of the tagRendering containing the autoAction. This tagrendering will be calculated. The embedded actions will be executed", + required: true }, { name: "text", - doc: "The text to show on the button" + doc: "The text to show on the button", + required: true }, { name: "icon", diff --git a/UI/Popup/ImportButton.ts b/UI/Popup/ImportButton.ts index c8a50ba422..4108c4e24c 100644 --- a/UI/Popup/ImportButton.ts +++ b/UI/Popup/ImportButton.ts @@ -42,6 +42,7 @@ import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; import {Changes} from "../../Logic/Osm/Changes"; import {ElementStorage} from "../../Logic/ElementStorage"; import Hash from "../../Logic/Web/Hash"; +import {PreciseInput} from "../../Models/ThemeConfig/PresetConfig"; /** * A helper class for the various import-flows. @@ -54,7 +55,7 @@ abstract class AbstractImportButton implements SpecialVisualizations { public readonly args: { name: string, defaultValue?: string, doc: string }[] private readonly showRemovedTags: boolean; - constructor(funcName: string, docsIntro: string, extraArgs: { name: string, doc: string, defaultValue?: string }[], showRemovedTags = true) { + constructor(funcName: string, docsIntro: string, extraArgs: { name: string, doc: string, defaultValue?: string, required?: boolean }[], showRemovedTags = true) { this.funcName = funcName this.showRemovedTags = showRemovedTags; @@ -73,11 +74,13 @@ ${Utils.special_visualizations_importRequirementDocs} this.args = [ { name: "targetLayer", - doc: "The id of the layer where this point should end up. This is not very strict, it will simply result in checking that this layer is shown preventing possible duplicate elements" + doc: "The id of the layer where this point should end up. This is not very strict, it will simply result in checking that this layer is shown preventing possible duplicate elements", + required: true }, { name: "tags", - doc: "The tags to add onto the new object - see specification above. If this is a key (a single word occuring in the properties of the object), the corresponding value is taken and expanded instead" + doc: "The tags to add onto the new object - see specification above. If this is a key (a single word occuring in the properties of the object), the corresponding value is taken and expanded instead", + required: true }, { name: "text", @@ -394,6 +397,43 @@ export class ImportWayButton extends AbstractImportButton implements AutoAction ) } + private static CreateAction(feature, + args: { max_snap_distance: string; snap_onto_layers: string; icon: string; text: string; tags: string; newTags: UIEventSource; targetLayer: string }, + state: FeaturePipelineState, + mergeConfigs: any[]) { + const coors = feature.geometry.coordinates + if ((feature.geometry.type === "Polygon") && coors.length > 1) { + const outer = coors[0] + const inner = [...coors] + inner.splice(0, 1) + return new CreateMultiPolygonWithPointReuseAction( + args.newTags.data, + outer, + inner, + state, + mergeConfigs, + "import" + ) + } else if (feature.geometry.type === "Polygon") { + const outer = coors[0] + return new CreateWayWithPointReuseAction( + args.newTags.data, + outer, + state, + mergeConfigs + ) + } else if (feature.geometry.type === "LineString") { + return new CreateWayWithPointReuseAction( + args.newTags.data, + coors, + state, + mergeConfigs + ) + } else { + throw "Unsupported type" + } + } + async applyActionOn(state: { layoutToUse: LayoutConfig; changes: Changes, allElements: ElementStorage }, originalFeatureTags: UIEventSource, argument: string[]): Promise { @@ -484,43 +524,6 @@ export class ImportWayButton extends AbstractImportButton implements AutoAction return mergeConfigs; } - - private static CreateAction(feature, - args: { max_snap_distance: string; snap_onto_layers: string; icon: string; text: string; tags: string; newTags: UIEventSource; targetLayer: string }, - state: FeaturePipelineState, - mergeConfigs: any[]) { - const coors = feature.geometry.coordinates - if ((feature.geometry.type === "Polygon" ) && coors.length > 1) { - const outer = coors[0] - const inner = [...coors] - inner.splice(0, 1) - return new CreateMultiPolygonWithPointReuseAction( - args.newTags.data, - outer, - inner, - state, - mergeConfigs, - "import" - ) - } else if(feature.geometry.type === "Polygon"){ - const outer = coors[0] - return new CreateWayWithPointReuseAction( - args.newTags.data, - outer, - state, - mergeConfigs - ) - }else if(feature.geometry.type === "LineString"){ - return new CreateWayWithPointReuseAction( - args.newTags.data, - coors, - state, - mergeConfigs - ) - }else{ - throw "Unsupported type" - } - } } export class ImportPointButton extends AbstractImportButton { @@ -528,18 +531,23 @@ export class ImportPointButton extends AbstractImportButton { constructor() { super("import_button", "This button will copy the point from an external dataset into OpenStreetMap", - [{ - name: "snap_onto_layers", - doc: "If a way of the given layer(s) is closeby, will snap the new point onto this way (similar as preset might snap). To show multiple layers to snap onto, use a `;`-seperated list" - }, + [ + { + name: "snap_onto_layers", + doc: "If a way of the given layer(s) is closeby, will snap the new point onto this way (similar as preset might snap). To show multiple layers to snap onto, use a `;`-seperated list" + }, { name: "max_snap_distance", doc: "The maximum distance that the imported point will be moved to snap onto a way in an already existing layer (in meters). This is previewed to the contributor, similar to the 'add new point'-action of MapComplete", defaultValue: "5" - }, { - name: "note_id", - doc: "If given, this key will be read. The corresponding note on OSM will be closed, stating 'imported'" - }], + }, + { + name: "note_id", + doc: "If given, this key will be read. The corresponding note on OSM will be closed, stating 'imported'" + }, + {name:"location_picker", + defaultValue: "photo", + doc: "Chooses the background for the precise location picker, options are 'map', 'photo' or 'osmbasedmap' or 'none' if the precise input picker should be disabled"}], false ) } @@ -581,7 +589,7 @@ export class ImportPointButton extends AbstractImportButton { newElementAction.newElementId )) Hash.hash.setData(newElementAction.newElementId) - + if (note_id !== undefined) { state.osmConnection.closeNote(note_id, "imported") originalFeatureTags.data["closed_at"] = new Date().toISOString() @@ -589,16 +597,24 @@ export class ImportPointButton extends AbstractImportButton { } } + let preciseInputOption = args["location_picker"] + let preciseInputSpec: PreciseInput = undefined + console.log("Precise input location is ", preciseInputOption) + if(preciseInputOption !== "none") { + preciseInputSpec = { + snapToLayers: args.snap_onto_layers?.split(";"), + maxSnapDistance: Number(args.max_snap_distance), + preferredBackground: args["location_picker"] ?? ["photo", "map"] + } + } + const presetInfo = { tags: args.newTags.data, icon: () => new Img(args.icon), layerToAddTo: state.filteredLayers.data.filter(l => l.layerDef.id === args.targetLayer)[0], name: args.text, title: Translations.WT(args.text), - preciseInput: { - snapToLayers: args.snap_onto_layers?.split(";"), - maxSnapDistance: Number(args.max_snap_distance) - }, + preciseInput: preciseInputSpec, // must be explicitely assigned, if 'undefined' won't work otherwise boundsFactor: 3 } diff --git a/UI/SpecialVisualizations.ts b/UI/SpecialVisualizations.ts index 68f9e75dc2..92ee0dd111 100644 --- a/UI/SpecialVisualizations.ts +++ b/UI/SpecialVisualizations.ts @@ -52,7 +52,7 @@ export interface SpecialVisualization { constr: ((state: FeaturePipelineState, tagSource: UIEventSource, argument: string[], guistate: DefaultGuiState,) => BaseUIElement), docs: string, example?: string, - args: { name: string, defaultValue?: string, doc: string }[], + args: { name: string, defaultValue?: string, doc: string, required?: false | boolean }[], getLayerDependencies?: (argument: string[]) => string[] } @@ -102,6 +102,7 @@ class CloseNoteButton implements SpecialVisualization { { name: "text", doc: "Text to show on this button", + required: true }, { name: "icon", @@ -179,7 +180,7 @@ class CloseNoteButton implements SpecialVisualization { export default class SpecialVisualizations { - public static specialVisualizations = SpecialVisualizations.init() + public static specialVisualizations : SpecialVisualization[] = SpecialVisualizations.init() public static HelpMessage() { @@ -206,9 +207,28 @@ export default class SpecialVisualizations { )); return new Combine([ + new Combine([ + new Title("Special tag renderings", 1), + "In a tagrendering, some special values are substituted by an advanced UI-element. This allows advanced features and visualizations to be reused by custom themes or even to query third-party API's.", "General usage is `{func_name()}`, `{func_name(arg, someotherarg)}` or `{func_name(args):cssStyle}`. Note that you _do not_ need to use quotes around your arguments, the comma is enough to separate them. This also implies you cannot use a comma in your args", + new Title("Using expanded syntax",4), + `Instead of using \`{"render": {"en": "{some_special_visualisation(some_arg, some other really long message, more args)} , "nl": "{some_special_visualisation(some_arg, een boodschap in een andere taal, more args)}}, one can also write`, + new FixedUiElement(JSON.stringify({ + render: { + special:{ + type: "some_special_visualisation", + "argname": "some_arg", + "message":{ + en:"some other really long message", + nl: "een boodschap in een andere taal" + }, + "other_arg_name":"more args" + } + } + })).SetClass("code") + ]).SetClass("flex flex-col"), ...helpTexts ] ).SetClass("flex flex-col"); @@ -227,9 +247,9 @@ export default class SpecialVisualizations { funcName: "image_carousel", docs: "Creates an image carousel for the given sources. An attempt will be made to guess what source is used. Supported: Wikidata identifiers, Wikipedia pages, Wikimedia categories, IMGUR (with attribution, direct links)", args: [{ - name: "image key/prefix (multiple values allowed if comma-seperated)", + name: "image_key", defaultValue: AllImageProviders.defaultKeys.join(","), - doc: "The keys given to the images, e.g. if image is given, the first picture URL will be added as image, the second as image:0, the third as image:1, etc... " + doc: "The keys given to the images, e.g. if image is given, the first picture URL will be added as image, the second as image:0, the third as image:1, etc... Multiple values are allowed if ';'-separated " }], constr: (state, tags, args) => { let imagePrefixes: string[] = undefined; @@ -368,6 +388,7 @@ export default class SpecialVisualizations { { doc: "The side to show, either `left` or `right`", name: "side", + required: true } ], example: "`{sided_minimap(left)}`", @@ -461,12 +482,15 @@ export default class SpecialVisualizations { docs: "Downloads a JSON from the given URL, e.g. '{live(example.org/data.json, shorthand:x.y.z, other:a.b.c, shorthand)}' will download the given file, will create an object {shorthand: json[x][y][z], other: json[a][b][c] out of it and will return 'other' or 'json[a][b][c]. This is made to use in combination with tags, e.g. {live({url}, {url:format}, needed_value)}", example: "{live({url},{url:format},hour)} {live(https://data.mobility.brussels/bike/api/counts/?request=live&featureID=CB2105,hour:data.hour_cnt;day:data.day_cnt;year:data.year_cnt,hour)}", args: [{ - name: "Url", doc: "The URL to load" + name: "Url", + doc: "The URL to load", + required: true }, { name: "Shorthands", doc: "A list of shorthands, of the format 'shorthandname:path.path.path'. separated by ;" }, { - name: "path", doc: "The path (or shorthand) that should be returned" + name: "path", + doc: "The path (or shorthand) that should be returned" }], constr: (state, tagSource: UIEventSource, args) => { const url = args[0]; @@ -483,7 +507,8 @@ export default class SpecialVisualizations { args: [ { name: "key", - doc: "The key to be read and to generate a histogram from" + doc: "The key to be read and to generate a histogram from", + required: true }, { name: "title", @@ -588,7 +613,8 @@ export default class SpecialVisualizations { example: "{canonical(length)} will give 42 metre (in french)", args: [{ name: "key", - doc: "The key of the tag to give the canonical text for" + doc: "The key of the tag to give the canonical text for", + required: true }], constr: (state, tagSource, args) => { const key = args [0] @@ -618,16 +644,19 @@ export default class SpecialVisualizations { {name: "feature_ids", doc: "A JSON-serialized list of IDs of features to apply the tagging on"}, { name: "keys", - doc: "One key (or multiple keys, seperated by ';') of the attribute that should be copied onto the other features." + doc: "One key (or multiple keys, seperated by ';') of the attribute that should be copied onto the other features.", + required: true }, {name: "text", doc: "The text to show on the button"}, { name: "autoapply", - doc: "A boolean indicating wether this tagging should be applied automatically if the relevant tags on this object are changed. A visual element indicating the multi_apply is still shown" + doc: "A boolean indicating wether this tagging should be applied automatically if the relevant tags on this object are changed. A visual element indicating the multi_apply is still shown", + required: true }, { name: "overwrite", - doc: "If set to 'true', the tags on the other objects will always be overwritten. The default behaviour will be to only change the tags on other objects if they are either undefined or had the same value before the change" + doc: "If set to 'true', the tags on the other objects will always be overwritten. The default behaviour will be to only change the tags on other objects if they are either undefined or had the same value before the change", + required: true } ], example: "{multi_apply(_features_with_the_same_name_within_100m, name:etymology:wikidata;name:etymology, Apply etymology information on all nearby objects with the same name)}", @@ -918,7 +947,7 @@ export default class SpecialVisualizations { ] specialVisualizations.push(new AutoApplyButton(specialVisualizations)) - + return specialVisualizations; } diff --git a/Utils.ts b/Utils.ts index 43f891c0ea..0a993b06c4 100644 --- a/Utils.ts +++ b/Utils.ts @@ -407,7 +407,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be * * If a list is encountered, this is tranparently walked recursively on every object. * - * The leaf objects are replaced by the function + * The leaf objects are replaced in the object itself by the specified function */ public static WalkPath(path: string[], object: any, replaceLeaf: ((leaf: any, travelledPath: string[]) => any), travelledPath: string[] = []) { const head = path[0] @@ -793,6 +793,12 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be } return new Date(str) } + + public static sortedByLevenshteinDistance(reference: string, ts: T[], getName: (t:T) => string): T[]{ + const withDistance: [T, number][] = ts.map(t => [t, Utils.levenshteinDistance(getName(t), reference)]) + withDistance.sort(([_, a], [__, b]) => a - b) + return withDistance.map(n => n[0]) + } public static levenshteinDistance(str1: string, str2: string) { const track = Array(str2.length + 1).fill(null).map(() => diff --git a/assets/layers/note/note.json b/assets/layers/note/note.json index c2e978a801..f4342ff90e 100644 --- a/assets/layers/note/note.json +++ b/assets/layers/note/note.json @@ -85,7 +85,7 @@ "iconBadges": [ { "if": "_total_comments>1", - "then": "speech_bubble" + "then": "circle:white;speech_bubble" } ] } diff --git a/assets/svg/license_info.json b/assets/svg/license_info.json index c886034d32..530adea9ad 100644 --- a/assets/svg/license_info.json +++ b/assets/svg/license_info.json @@ -915,6 +915,16 @@ "https://www.OpenStreetMap.org" ] }, + { + "path": "party.svg", + "license": "CC-BY 4.0", + "authors": [ + "Twemoji" + ], + "sources": [ + "https://github.com/twitter/twemoji" + ] + }, { "path": "payment_card.svg", "license": "CC0", diff --git a/assets/svg/party.svg b/assets/svg/party.svg new file mode 100644 index 0000000000..a4b8305af6 --- /dev/null +++ b/assets/svg/party.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/themes/toerisme_vlaanderen/license_info.json b/assets/themes/toerisme_vlaanderen/license_info.json index 0013ceba58..feefa82985 100644 --- a/assets/themes/toerisme_vlaanderen/license_info.json +++ b/assets/themes/toerisme_vlaanderen/license_info.json @@ -144,6 +144,72 @@ "https://mapcomplete.osm.be/toerisme_vlaanderen" ] }, + { + "path": "pin je punt1.jpg", + "license": "CC0", + "authors": [ + "Toerisme Vlaanderen" + ], + "sources": [ + "https://toerismevlaanderen.be/pinjepunt", + "https://mapcomplete.osm.be/toerisme_vlaanderenn" + ] + }, + { + "path": "pin je punt2.jpg", + "license": "CC0", + "authors": [ + "Toerisme Vlaanderen" + ], + "sources": [ + "https://toerismevlaanderen.be/pinjepunt", + "https://mapcomplete.osm.be/toerisme_vlaanderenn" + ] + }, + { + "path": "pin je punt3.jpg", + "license": "CC0", + "authors": [ + "Toerisme Vlaanderen" + ], + "sources": [ + "https://toerismevlaanderen.be/pinjepunt", + "https://mapcomplete.osm.be/toerisme_vlaanderenn" + ] + }, + { + "path": "pin je punt4.jpg", + "license": "CC0", + "authors": [ + "Toerisme Vlaanderen" + ], + "sources": [ + "https://toerismevlaanderen.be/pinjepunt", + "https://mapcomplete.osm.be/toerisme_vlaanderenn" + ] + }, + { + "path": "pin je punt5.jpg", + "license": "CC0", + "authors": [ + "Toerisme Vlaanderen" + ], + "sources": [ + "https://toerismevlaanderen.be/pinjepunt", + "https://mapcomplete.osm.be/toerisme_vlaanderenn" + ] + }, + { + "path": "pin je punt6.jpg", + "license": "CC0", + "authors": [ + "Toerisme Vlaanderen" + ], + "sources": [ + "https://toerismevlaanderen.be/pinjepunt", + "https://mapcomplete.osm.be/toerisme_vlaanderenn" + ] + }, { "path": "playground.svg", "license": "CC0", diff --git a/assets/themes/uk_addresses/uk_addresses.json b/assets/themes/uk_addresses/uk_addresses.json index 75a10030c4..c7d1cc5524 100644 --- a/assets/themes/uk_addresses/uk_addresses.json +++ b/assets/themes/uk_addresses/uk_addresses.json @@ -123,7 +123,16 @@ }, { "id": "uk_addresses_import_button", - "render": "{import_button(address,urpn_count=$urpn_count;ref:GB:uprn=$ref:GB:uprn$, Add this address, ./assets/themes/uk_addresses/housenumber_add.svg)}" + "render":{ + "special": { + "type": "import_button", + "targetLayer": "address", + "tags": "urpn_count=$urpn_count;ref:GB:uprn=$ref:GB:uprn$", + "text": "Add this address", + "icon": "./assets/themes/uk_addresses/housenumber_add.svg", + "location_picker": "none" + } + } } ], "calculatedTags": [ diff --git a/css/index-tailwind-output.css b/css/index-tailwind-output.css index d44c18b2d4..db8ca3cc63 100644 --- a/css/index-tailwind-output.css +++ b/css/index-tailwind-output.css @@ -706,6 +706,7 @@ video { } .sticky { + position: -webkit-sticky; position: sticky; } @@ -1504,10 +1505,6 @@ video { padding: 0.125rem; } -.p-8 { - padding: 2rem; -} - .px-0 { padding-left: 0px; padding-right: 0px; diff --git a/tests/Models/ThemeConfig/Conversion/PrepareLayer.spec.ts b/tests/Models/ThemeConfig/Conversion/PrepareLayer.spec.ts index b87a683cd5..b94e925a1b 100644 --- a/tests/Models/ThemeConfig/Conversion/PrepareLayer.spec.ts +++ b/tests/Models/ThemeConfig/Conversion/PrepareLayer.spec.ts @@ -1,21 +1,15 @@ import {describe} from 'mocha' import {expect} from 'chai' -import {LayoutConfigJson} from "../../../../Models/ThemeConfig/Json/LayoutConfigJson"; import {LayerConfigJson} from "../../../../Models/ThemeConfig/Json/LayerConfigJson"; -import {PrepareTheme} from "../../../../Models/ThemeConfig/Conversion/PrepareTheme"; import {TagRenderingConfigJson} from "../../../../Models/ThemeConfig/Json/TagRenderingConfigJson"; -import LayoutConfig from "../../../../Models/ThemeConfig/LayoutConfig"; -import * as bookcaseLayer from "../../../../assets/generated/layers/public_bookcase.json" -import LayerConfig from "../../../../Models/ThemeConfig/LayerConfig"; -import {ExtractImages} from "../../../../Models/ThemeConfig/Conversion/FixImages"; -import * as cyclofix from "../../../../assets/generated/themes/cyclofix.json" import LineRenderingConfigJson from "../../../../Models/ThemeConfig/Json/LineRenderingConfigJson"; -import {PrepareLayer} from "../../../../Models/ThemeConfig/Conversion/PrepareLayer"; - - +import {PrepareLayer, RewriteSpecial} from "../../../../Models/ThemeConfig/Conversion/PrepareLayer"; +import { + QuestionableTagRenderingConfigJson +} from "../../../../Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson"; describe("PrepareLayer", () => { - + it("should expand mappings in map renderings", () => { const exampleLayer: LayerConfigJson = { id: "testlayer", @@ -66,10 +60,12 @@ describe("PrepareLayer", () => { "if": "parking:condition:left=free", "then": "#299921" }, - {"if": "parking:condition:left=disc", - "then": "#219991"}] + { + "if": "parking:condition:left=disc", + "then": "#219991" + }] }, - "offset": -6 + "offset": -6 }, { "color": { "render": "#888", @@ -77,8 +73,10 @@ describe("PrepareLayer", () => { "if": "parking:condition:right=free", "then": "#299921" }, - {"if": "parking:condition:right=disc", - "then": "#219991"}] + { + "if": "parking:condition:right=disc", + "then": "#219991" + }] }, "offset": 6 }], @@ -91,3 +89,26 @@ describe("PrepareLayer", () => { ) }) +describe('RewriteSpecial', function () { + it("should rewrite the UK import button", () => { + const tr = { + "id": "uk_addresses_import_button", + "render": { + "special": { + "type": "import_button", + "targetLayer": "address", + "tags": "urpn_count=$urpn_count;ref:GB:uprn=$ref:GB:uprn$", + "text": "Add this address", + "icon": "./assets/themes/uk_addresses/housenumber_add.svg", + "location_picker": "none" + } + } + } + const r = new RewriteSpecial().convert(tr, "test").result + expect(r).to.deep.eq({ + "id": "uk_addresses_import_button", + "render": {'*': "{import_button(address,urpn_count=$urpn_count;ref:GB:uprn=$ref:GB:uprn$,Add this address,./assets/themes/uk_addresses/housenumber_add.svg,,,,none)}"} + }) + }) +}); + diff --git a/tests/UI/SpecialVisualisations.spec.ts b/tests/UI/SpecialVisualisations.spec.ts new file mode 100644 index 0000000000..b683393098 --- /dev/null +++ b/tests/UI/SpecialVisualisations.spec.ts @@ -0,0 +1,19 @@ +import {describe} from 'mocha' +import SpecialVisualizations from "../../UI/SpecialVisualizations"; +import {expect} from "chai"; + +describe("SpecialVisualisations", () => { + + describe("predifined special visualisations", () => { + it("should not have an argument called 'type'", () => { + const specials = SpecialVisualizations.specialVisualizations + for (const special of specials) { + expect(special.funcName).not.eq('type', "A special visualisation is not allowed to be named 'type', as this will conflict with the 'special'-blocks") + for (const arg of special.args) { + expect(arg.name).not.eq('type', "An argument is not allowed to be called 'type', as this will conflict with the 'special'-blocks") + } + + } + }) + }) +}) \ No newline at end of file From 3a7e1d4c76a0fb8f13d93c3067f5d9fb226ddf7a Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Tue, 29 Mar 2022 11:31:08 +0200 Subject: [PATCH 05/37] Hide website of playgrounds in toerisme Vlaanderen --- assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json b/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json index 24f0208611..169d814350 100644 --- a/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json +++ b/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json @@ -242,7 +242,8 @@ ] }, "hideTagRenderingsWithLabels": [ - "extra" + "extra", + "website" ] } ], From 787f604df3903494928fb23b4eb339be20c2d763 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Tue, 29 Mar 2022 21:31:59 +0200 Subject: [PATCH 06/37] Add sanity check on filters: every search field must be mentioned in the question now --- Models/ThemeConfig/FilterConfig.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Models/ThemeConfig/FilterConfig.ts b/Models/ThemeConfig/FilterConfig.ts index b9060b3cd6..b26e43deba 100644 --- a/Models/ThemeConfig/FilterConfig.ts +++ b/Models/ThemeConfig/FilterConfig.ts @@ -68,6 +68,15 @@ export default class FilterConfig { } }) + for (const field of fields) { + question.OnEveryLanguage((txt, language) => { + if(txt.indexOf("{"+field.name+"}")<0){ + throw "Error in filter with fields at "+context+".question."+language+": The question text should contain every field, but it doesn't contain `{"+field+"}`: "+txt + } + return txt + }) + } + if(option.default){ if(defaultSelection === undefined){ defaultSelection = i; From 68c3585d725efa85c0583609cb1a46f194db0c00 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Thu, 31 Mar 2022 03:28:18 +0200 Subject: [PATCH 07/37] Add sidewalks map example --- Docs/Misc/SidewalksMapComplete.png | Bin 0 -> 737184 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Docs/Misc/SidewalksMapComplete.png diff --git a/Docs/Misc/SidewalksMapComplete.png b/Docs/Misc/SidewalksMapComplete.png new file mode 100644 index 0000000000000000000000000000000000000000..1373b041c9120d051f31715a20b92be411ca054f GIT binary patch literal 737184 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�<7BhOz+ZRjL57_L_TW=Ljj1td1g88$vSz} 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

Lq&~4Gbn=*xu4wmJJWvjw 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

3m459&?p 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%0AT9~H~lGT{~Jl7AT0%cfNkuOEb)tZYhV@sG0t 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

M(KZm=))k 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 z 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%0AU&bkO^I2Wl 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%0D#MASAZ5n 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 literal 0 HcmV?d00001 From 592bc4ae0b1671a7134cfddd9065d0b6f0d5b4f9 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Thu, 31 Mar 2022 03:30:20 +0200 Subject: [PATCH 08/37] Small refactoring: use checkbox for sharescreen instead of toggles --- UI/BigComponents/ShareScreen.ts | 36 ++++++++++----------------------- UI/Input/Checkboxes.ts | 15 ++++++++++++++ 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/UI/BigComponents/ShareScreen.ts b/UI/BigComponents/ShareScreen.ts index 0f3bd5bae9..a550627792 100644 --- a/UI/BigComponents/ShareScreen.ts +++ b/UI/BigComponents/ShareScreen.ts @@ -12,6 +12,8 @@ import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; import Loc from "../../Models/Loc"; import BaseLayer from "../../Models/BaseLayer"; import FilteredLayer from "../../Models/FilteredLayer"; +import {InputElement} from "../Input/InputElement"; +import CheckBoxes, {CheckBox} from "../Input/Checkboxes"; export default class ShareScreen extends Combine { @@ -19,7 +21,7 @@ export default class ShareScreen extends Combine { const layout = state?.layoutToUse; const tr = Translations.t.general.sharescreen; - const optionCheckboxes: BaseUIElement[] = [] + const optionCheckboxes: InputElement[] = [] const optionParts: (UIEventSource)[] = []; function check() { @@ -30,16 +32,12 @@ export default class ShareScreen extends Combine { return Svg.no_checkmark_svg().SetStyle("width: 1.5em; display: inline-block;"); } - const includeLocation = new Toggle( - new Combine([check(), tr.fsIncludeCurrentLocation.Clone()]), - new Combine([nocheck(), tr.fsIncludeCurrentLocation.Clone()]), - new UIEventSource(true) - ).ToggleOnClick() + const includeLocation = new CheckBox(tr.fsIncludeCurrentLocation, true) optionCheckboxes.push(includeLocation); const currentLocation = state.locationControl; - optionParts.push(includeLocation.isEnabled.map((includeL) => { + optionParts.push(includeLocation.GetValue().map((includeL) => { if (currentLocation === undefined) { return null; } @@ -66,13 +64,9 @@ export default class ShareScreen extends Combine { const currentBackground = new VariableUiElement(currentLayer.map(layer => { return tr.fsIncludeCurrentBackgroundMap.Subs({name: layer?.name ?? ""}); })); - const includeCurrentBackground = new Toggle( - new Combine([check(), currentBackground]), - new Combine([nocheck(), currentBackground]), - new UIEventSource(true) - ).ToggleOnClick() + const includeCurrentBackground = new CheckBox(currentBackground, true) optionCheckboxes.push(includeCurrentBackground); - optionParts.push(includeCurrentBackground.isEnabled.map((includeBG) => { + optionParts.push(includeCurrentBackground.GetValue().map((includeBG) => { if (includeBG) { return "background=" + currentLayer.data.id } else { @@ -81,14 +75,10 @@ export default class ShareScreen extends Combine { }, [currentLayer])); - const includeLayerChoices = new Toggle( - new Combine([check(), tr.fsIncludeCurrentLayers.Clone()]), - new Combine([nocheck(), tr.fsIncludeCurrentLayers.Clone()]), - new UIEventSource(true) - ).ToggleOnClick() + const includeLayerChoices = new CheckBox(tr.fsIncludeCurrentLayers, true) optionCheckboxes.push(includeLayerChoices); - optionParts.push(includeLayerChoices.isEnabled.map((includeLayerSelection) => { + optionParts.push(includeLayerChoices.GetValue().map((includeLayerSelection) => { if (includeLayerSelection) { return Utils.NoNull(state.filteredLayers.data.map(fLayerToParam)).join("&") } else { @@ -110,13 +100,9 @@ export default class ShareScreen extends Combine { for (const swtch of switches) { - const checkbox = new Toggle( - new Combine([check(), Translations.W(swtch.human.Clone())]), - new Combine([nocheck(), Translations.W(swtch.human.Clone())]), - new UIEventSource(!swtch.reverse) - ).ToggleOnClick(); + const checkbox =new CheckBox(Translations.W(swtch.human), !swtch.reverse) optionCheckboxes.push(checkbox); - optionParts.push(checkbox.isEnabled.map((isEn) => { + optionParts.push(checkbox.GetValue().map((isEn) => { if (isEn) { if (swtch.reverse) { return `${swtch.urlName}=true` diff --git a/UI/Input/Checkboxes.ts b/UI/Input/Checkboxes.ts index affad21920..cf849081e7 100644 --- a/UI/Input/Checkboxes.ts +++ b/UI/Input/Checkboxes.ts @@ -2,6 +2,21 @@ import {InputElement} from "./InputElement"; import {UIEventSource} from "../../Logic/UIEventSource"; import {Utils} from "../../Utils"; import BaseUIElement from "../BaseUIElement"; +import InputElementMap from "./InputElementMap"; + +export class CheckBox extends InputElementMap { + constructor(el: BaseUIElement , defaultValue?: boolean) { + super( + new CheckBoxes([el]), + (x0, x1) => x0 === x1, + t => t.length > 0, + x => x ? [0] : [] + ); + if(defaultValue !== undefined){ + this.GetValue().setData(defaultValue) + } + } +} /** * Supports multi-input From 2c7fb556dc8f6e6ba0f42d4e5f7f2ae106a7341e Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 1 Apr 2022 12:51:55 +0200 Subject: [PATCH 09/37] Add translation buttons --- Logic/State/UserRelatedState.ts | 22 +++- Models/ThemeConfig/ExtraLinkConfig.ts | 2 +- Models/ThemeConfig/FilterConfig.ts | 2 +- Models/ThemeConfig/LayerConfig.ts | 11 +- Models/ThemeConfig/LayoutConfig.ts | 16 ++- Models/ThemeConfig/TagRenderingConfig.ts | 25 +++- UI/Base/Link.ts | 1 + UI/Base/LinkToWeblate.ts | 33 +++++ UI/BigComponents/CopyrightPanel.ts | 61 +++++---- UI/BigComponents/FilterView.ts | 4 +- UI/BigComponents/FullWelcomePaneWithTabs.ts | 2 - UI/BigComponents/MoreScreen.ts | 12 +- UI/BigComponents/SimpleAddUI.ts | 9 +- UI/BigComponents/TranslatorsPanel.ts | 124 +++++++++++++++++++ UI/SpecialVisualizations.ts | 2 +- UI/SubstitutedTranslation.ts | 13 +- UI/Wikipedia/WikidataPreviewBox.ts | 8 +- UI/i18n/Locale.ts | 3 +- UI/i18n/Translation.ts | 85 ++++++++----- Utils.ts | 31 +++++ assets/contributors.json | 2 +- assets/layers/bike_shop/bike_shop.json | 15 +-- assets/themes/uk_addresses/uk_addresses.json | 2 +- assets/translators.json | 2 +- css/index-tailwind-output.css | 43 ++++--- index.css | 4 + langs/en.json | 14 +++ langs/layers/en.json | 3 + langs/layers/nl.json | 3 + scripts/generateLayerOverview.ts | 9 +- scripts/generateTranslations.ts | 29 +++-- 31 files changed, 442 insertions(+), 150 deletions(-) create mode 100644 UI/Base/LinkToWeblate.ts create mode 100644 UI/BigComponents/TranslatorsPanel.ts diff --git a/Logic/State/UserRelatedState.ts b/Logic/State/UserRelatedState.ts index 6d6f8ae892..3dafd0c68d 100644 --- a/Logic/State/UserRelatedState.ts +++ b/Logic/State/UserRelatedState.ts @@ -11,7 +11,8 @@ import SelectedElementTagsUpdater from "../Actors/SelectedElementTagsUpdater"; import {Changes} from "../Osm/Changes"; import ChangeToElementsActor from "../Actors/ChangeToElementsActor"; import PendingChangesUploader from "../Actors/PendingChangesUploader"; - +import * as translators from "../../assets/translators.json" + /** * The part of the state which keeps track of user-related stuff, e.g. the OSM-connection, * which layers they enabled, ... @@ -36,6 +37,8 @@ export default class UserRelatedState extends ElementsState { */ public favouriteLayers: UIEventSource; + public readonly isTranslator : UIEventSource; + constructor(layoutToUse: LayoutConfig, options?: { attemptLogin: true | boolean }) { super(layoutToUse); @@ -50,6 +53,21 @@ export default class UserRelatedState extends ElementsState { osmConfiguration: <'osm' | 'osm-test'>this.featureSwitchApiURL.data, attemptLogin: options?.attemptLogin }) + this.isTranslator = this.osmConnection.userDetails.map(ud => { + if(!ud.loggedIn){ + return false; + } + const name= ud.name.toLowerCase().replace(/\s+/g, '') + return translators.contributors.some(c => c.contributor.toLowerCase().replace(/\s+/g, '') === name) + }) + this.isTranslator.addCallbackAndRunD(ud => { + if(ud){ + Locale.showLinkToWeblate.setData(true) + } + }); + + QueryParameters.GetBooleanQueryParameter("fs-translation-mode",false,"If set, will show the translation buttons") + .addCallbackAndRunD(tr => Locale.showLinkToWeblate.setData(Locale.showLinkToWeblate.data || tr)) this.changes = new Changes(this, layoutToUse?.isLeftRightSensitive() ?? false) @@ -57,7 +75,7 @@ export default class UserRelatedState extends ElementsState { new ChangeToElementsActor(this.changes, this.allElements) new PendingChangesUploader(this.changes, this.selectedElement); - + this.mangroveIdentity = new MangroveIdentity( this.osmConnection.GetLongPreference("identity", "mangrove") ); diff --git a/Models/ThemeConfig/ExtraLinkConfig.ts b/Models/ThemeConfig/ExtraLinkConfig.ts index 641029f6fb..9c792ab113 100644 --- a/Models/ThemeConfig/ExtraLinkConfig.ts +++ b/Models/ThemeConfig/ExtraLinkConfig.ts @@ -11,7 +11,7 @@ export default class ExtraLinkConfig { constructor(configJson: ExtraLinkConfigJson, context) { this.icon = configJson.icon - this.text = Translations.T(configJson.text) + this.text = Translations.T(configJson.text, "themes:"+context+".text") this.href = configJson.href this.newTab = configJson.newTab this.requirements = new Set(configJson.requirements) diff --git a/Models/ThemeConfig/FilterConfig.ts b/Models/ThemeConfig/FilterConfig.ts index b26e43deba..a76a67a233 100644 --- a/Models/ThemeConfig/FilterConfig.ts +++ b/Models/ThemeConfig/FilterConfig.ts @@ -38,7 +38,7 @@ export default class FilterConfig { this.id = json.id; let defaultSelection : number = undefined this.options = json.options.map((option, i) => { - const ctx = `${context}.options[${i}]`; + const ctx = `${context}.options.${i}`; const question = Translations.T( option.question, `${ctx}.question` diff --git a/Models/ThemeConfig/LayerConfig.ts b/Models/ThemeConfig/LayerConfig.ts index 8a080f00f5..a74a90c57a 100644 --- a/Models/ThemeConfig/LayerConfig.ts +++ b/Models/ThemeConfig/LayerConfig.ts @@ -72,6 +72,7 @@ export default class LayerConfig extends WithContextLoader { official: boolean = true ) { context = context + "." + json.id; + const translationContext = "layers:"+json.id super(json, context) this.id = json.id; @@ -125,7 +126,7 @@ export default class LayerConfig extends WithContextLoader { this.allowSplit = json.allowSplit ?? false; - this.name = Translations.T(json.name, context + ".name"); + this.name = Translations.T(json.name, translationContext + ".name"); this.units = (json.units ?? []).map(((unitJson, i) => Unit.fromJson(unitJson, `${context}.unit[${i}]`))) if (json.description !== undefined) { @@ -136,7 +137,7 @@ export default class LayerConfig extends WithContextLoader { this.description = Translations.T( json.description, - context + ".description" + translationContext + ".description" ); @@ -211,9 +212,9 @@ export default class LayerConfig extends WithContextLoader { } const config: PresetConfig = { - title: Translations.T(pr.title, `${context}.presets[${i}].title`), + title: Translations.T(pr.title, `${translationContext}.presets.${i}.title`), tags: pr.tags.map((t) => TagUtils.SimpleTag(t)), - description: Translations.T(pr.description, `${context}.presets[${i}].description`), + description: Translations.T(pr.description, `${translationContext}.presets.${i}.description`), preciseInput: preciseInput, exampleImages: pr.exampleImages } @@ -258,7 +259,7 @@ export default class LayerConfig extends WithContextLoader { this.filters = [] } else { this.filters = (json.filter ?? []).map((option, i) => { - return new FilterConfig(option, `${context}.filter-[${i}]`) + return new FilterConfig(option, `layers:${this.id}.filter.${i}`) }); } diff --git a/Models/ThemeConfig/LayoutConfig.ts b/Models/ThemeConfig/LayoutConfig.ts index be970107aa..402f288929 100644 --- a/Models/ThemeConfig/LayoutConfig.ts +++ b/Models/ThemeConfig/LayoutConfig.ts @@ -67,7 +67,11 @@ export default class LayoutConfig { throw "The id of a theme should match [a-z0-9-_]*: " + json.id } } - context = (context ?? "") + "." + this.id; + if(context === undefined){ + context = this.id + }else{ + context = context + "." + this.id; + } this.maintainer = json.maintainer; this.credits = json.credits; this.version = json.version; @@ -99,10 +103,10 @@ export default class LayoutConfig { throw "Got undefined layers for " + json.id + " at " + context } } - this.title = new Translation(json.title, context + ".title"); - this.description = new Translation(json.description, context + ".description"); - this.shortDescription = json.shortDescription === undefined ? this.description.FirstSentence() : new Translation(json.shortDescription, context + ".shortdescription"); - this.descriptionTail = json.descriptionTail === undefined ? undefined : new Translation(json.descriptionTail, context + ".descriptionTail"); + this.title = new Translation(json.title, "themes:"+context + ".title"); + this.description = new Translation(json.description, "themes:"+context + ".description"); + this.shortDescription = json.shortDescription === undefined ? this.description.FirstSentence() : new Translation(json.shortDescription, "themes:"+context + ".shortdescription"); + this.descriptionTail = json.descriptionTail === undefined ? undefined : new Translation(json.descriptionTail, "themes:"+context + ".descriptionTail"); this.icon = json.icon; this.socialImage = json.socialImage ?? LayoutConfig.defaultSocialImage; if (this.socialImage === "") { @@ -125,7 +129,7 @@ export default class LayoutConfig { href: "https://mapcomplete.osm.be/{theme}.html?lat={lat}&lon={lon}&z={zoom}&language={language}", newTab: true, requirements: ["iframe","no-welcome-message"] - }, context) + }, context+".extraLink") this.clustering = { diff --git a/Models/ThemeConfig/TagRenderingConfig.ts b/Models/ThemeConfig/TagRenderingConfig.ts index 967b0cd0e9..b1fcc78aa3 100644 --- a/Models/ThemeConfig/TagRenderingConfig.ts +++ b/Models/ThemeConfig/TagRenderingConfig.ts @@ -54,7 +54,6 @@ export default class TagRenderingConfig { if (json === undefined) { throw "Initing a TagRenderingConfig with undefined in " + context; } - if (json === "questions") { // Very special value this.render = null; @@ -70,9 +69,23 @@ export default class TagRenderingConfig { json = "" + json } + let translationKey = context; + if(json["id"] !== undefined){ + const layerId = context.split(".")[0] + if(json["source"]){ + let src = json["source"]+":" + if(json["source"] === "shared-questions"){ + src += "shared_questions." + } + translationKey = `${src}${json["id"] ?? ""}` + }else{ + translationKey = `layers:${layerId}.tagRenderings.${json["id"] ?? ""}` + } + } + if (typeof json === "string") { - this.render = Translations.T(json, context + ".render"); + this.render = Translations.T(json, translationKey + ".render"); this.multiAnswer = false; return; } @@ -86,8 +99,8 @@ export default class TagRenderingConfig { this.group = json.group ?? ""; this.labels = json.labels ?? [] - this.render = Translations.T(json.render, context + ".render"); - this.question = Translations.T(json.question, context + ".question"); + this.render = Translations.T(json.render, translationKey + ".render"); + this.question = Translations.T(json.question, translationKey + ".question"); this.condition = TagUtils.Tag(json.condition ?? {"and": []}, `${context}.condition`); if (json.freeform) { @@ -101,7 +114,7 @@ export default class TagRenderingConfig { const typeDescription = Translations.t.validation[type]?.description placeholder = Translations.T(json.freeform.key+" ("+type+")") if(typeDescription !== undefined){ - placeholder = placeholder.Fuse(typeDescription, type) + placeholder = placeholder.Subs({[type]: typeDescription}) } } @@ -155,7 +168,7 @@ export default class TagRenderingConfig { this.mappings = json.mappings.map((mapping, i) => { - const ctx = `${context}.mapping[${i}]` + const ctx = `${translationKey}.mappings.${i}` if (mapping.then === undefined) { throw `${ctx}: Invalid mapping: if without body` } diff --git a/UI/Base/Link.ts b/UI/Base/Link.ts index d0c40faa42..d336793126 100644 --- a/UI/Base/Link.ts +++ b/UI/Base/Link.ts @@ -16,6 +16,7 @@ export default class Link extends BaseUIElement { if (this._embeddedShow === undefined) { throw "Error: got a link where embeddedShow is undefined" } + this.onClick(() => {}) } diff --git a/UI/Base/LinkToWeblate.ts b/UI/Base/LinkToWeblate.ts new file mode 100644 index 0000000000..e2914ebd68 --- /dev/null +++ b/UI/Base/LinkToWeblate.ts @@ -0,0 +1,33 @@ +import {VariableUiElement} from "./VariableUIElement"; +import Locale from "../i18n/Locale"; +import Link from "./Link"; +import Svg from "../../Svg"; + +export default class LinkToWeblate extends VariableUiElement { + constructor(context: string, availableTranslations: object) { + super( Locale.language.map(ln => { + if (Locale.showLinkToWeblate.data === false) { + return undefined; + } + if(availableTranslations["*"] !== undefined){ + return undefined + } + const icon = Svg.translate_svg() + .SetClass("rounded-full border border-gray-400 inline-block w-4 h-4 m-1 weblate-link self-center") + if(availableTranslations[ln] === undefined){ + icon.SetClass("bg-red-400") + } + return new Link(icon, + LinkToWeblate.hrefToWeblate(ln, context), true) + } ,[Locale.showLinkToWeblate])); + this.SetClass("enable-links hidden-on-mobile") + } + + public static hrefToWeblate(language: string, contextKey: string): string{ + const [category, ...rest] = contextKey.split(":") + const key = rest.join(":") + + const baseUrl = "https://hosted.weblate.org/translate/mapcomplete/" + return baseUrl + category + "/" + language + "/?offset=1&q=context%3A%3D%22" + key + "%22" + } +} \ No newline at end of file diff --git a/UI/BigComponents/CopyrightPanel.ts b/UI/BigComponents/CopyrightPanel.ts index 73475b6478..c1cadcf8b4 100644 --- a/UI/BigComponents/CopyrightPanel.ts +++ b/UI/BigComponents/CopyrightPanel.ts @@ -23,6 +23,7 @@ import Constants from "../../Models/Constants"; import ContributorCount from "../../Logic/ContributorCount"; import Img from "../Base/Img"; import {Translation} from "../i18n/Translation"; +import TranslatorsPanel from "./TranslatorsPanel"; export class OpenIdEditor extends VariableUiElement { constructor(state: { locationControl: UIEventSource }, iconStyle?: string, objectId?: string) { @@ -110,7 +111,8 @@ export default class CopyrightPanel extends Combine { featurePipeline: FeaturePipeline, currentBounds: UIEventSource, locationControl: UIEventSource, - osmConnection: OsmConnection + osmConnection: OsmConnection, + isTranslator: UIEventSource }) { const t = Translations.t.general.attribution @@ -131,25 +133,21 @@ export default class CopyrightPanel extends Combine { }), new OpenIdEditor(state, iconStyle), new OpenMapillary(state, iconStyle), - new OpenJosm(state, iconStyle) + new OpenJosm(state, iconStyle), + new TranslatorsPanel(state, iconStyle) + ] const iconAttributions = layoutToUse.usedImages.map(CopyrightPanel.IconAttribution) let maintainer: BaseUIElement = undefined if (layoutToUse.maintainer !== undefined && layoutToUse.maintainer !== "" && layoutToUse.maintainer.toLowerCase() !== "mapcomplete") { - maintainer = Translations.t.general.attribution.themeBy.Subs({author: layoutToUse.maintainer}) + maintainer = t.themeBy.Subs({author: layoutToUse.maintainer}) } const contributions = new ContributorCount(state).Contributors - super([ - Translations.t.general.attribution.attributionContent, - new FixedUiElement("MapComplete " + Constants.vNumber).SetClass("font-bold"), - maintainer, - new Combine(actionButtons).SetClass("block w-full"), - new FixedUiElement(layoutToUse.credits), - new VariableUiElement(contributions.map(contributions => { + const dataContributors = new VariableUiElement(contributions.map(contributions => { if (contributions === undefined) { return "" } @@ -170,20 +168,29 @@ export default class CopyrightPanel extends Combine { const contribs = links.join(", ") if (hiddenCount <= 0) { - return Translations.t.general.attribution.mapContributionsBy.Subs({ + return t.mapContributionsBy.Subs({ contributors: contribs }) } else { - return Translations.t.general.attribution.mapContributionsByAndHidden.Subs({ + return t.mapContributionsByAndHidden.Subs({ contributors: contribs, hiddenCount: hiddenCount }); } - })), - CopyrightPanel.CodeContributors(contributors, Translations.t.general.attribution.codeContributionsBy), - CopyrightPanel.CodeContributors(translators, Translations.t.general.attribution.translatedBy), + })) + + super([ + new Title(t.attributionTitle), + t.attributionContent, + maintainer, + new FixedUiElement(layoutToUse.credits), + dataContributors, + CopyrightPanel.CodeContributors(contributors, t.codeContributionsBy), + CopyrightPanel.CodeContributors(translators, t.translatedBy), + new FixedUiElement("MapComplete " + Constants.vNumber).SetClass("font-bold"), + new Combine(actionButtons).SetClass("block w-full"), new Title(t.iconAttribution.title, 3), ...iconAttributions ].map(e => e?.SetClass("mt-4"))); @@ -213,9 +220,9 @@ export default class CopyrightPanel extends Combine { private static IconAttribution(iconPath: string): BaseUIElement { if (iconPath.startsWith("http")) { - try{ + try { iconPath = "." + new URL(iconPath).pathname; - }catch(e){ + } catch (e) { console.warn(e) } } @@ -234,16 +241,16 @@ export default class CopyrightPanel extends Combine { new Img(iconPath).SetClass("w-12 min-h-12 mr-2 mb-2"), new Combine([ new FixedUiElement(license.authors.join("; ")).SetClass("font-bold"), - license.license, - new Combine([ ...sources.map(lnk => { - let sourceLinkContent = lnk; - try { - sourceLinkContent = new URL(lnk).hostname - } catch { - console.error("Not a valid URL:", lnk) - } - return new Link(sourceLinkContent, lnk, true).SetClass("mr-2 mb-2"); - })]).SetClass("flex flex-wrap") + license.license, + new Combine([...sources.map(lnk => { + let sourceLinkContent = lnk; + try { + sourceLinkContent = new URL(lnk).hostname + } catch { + console.error("Not a valid URL:", lnk) + } + return new Link(sourceLinkContent, lnk, true).SetClass("mr-2 mb-2"); + })]).SetClass("flex flex-wrap") ]).SetClass("flex flex-col").SetStyle("width: calc(100% - 50px - 0.5em); min-width: 12rem;") ]).SetClass("flex flex-wrap border-b border-gray-300 m-2 border-box") } diff --git a/UI/BigComponents/FilterView.ts b/UI/BigComponents/FilterView.ts index 9c83a98895..e707211a09 100644 --- a/UI/BigComponents/FilterView.ts +++ b/UI/BigComponents/FilterView.ts @@ -101,9 +101,7 @@ export default class FilterView extends VariableUiElement { iconStyle ); - const name: Translation = Translations.WT( - filteredLayer.layerDef.name - ); + const name: Translation = filteredLayer.layerDef.name.Clone() const styledNameChecked = name.Clone().SetStyle("font-size:large").SetClass("ml-3"); diff --git a/UI/BigComponents/FullWelcomePaneWithTabs.ts b/UI/BigComponents/FullWelcomePaneWithTabs.ts index b9e149800f..7daa95088b 100644 --- a/UI/BigComponents/FullWelcomePaneWithTabs.ts +++ b/UI/BigComponents/FullWelcomePaneWithTabs.ts @@ -83,9 +83,7 @@ export default class FullWelcomePaneWithTabs extends ScrollableFullScreen { new Combine( [ Translations.t.general.openStreetMapIntro.SetClass("link-underline"), - Translations.t.general.attribution.attributionTitle, new CopyrightPanel(state) - ] ) } diff --git a/UI/BigComponents/MoreScreen.ts b/UI/BigComponents/MoreScreen.ts index 1d3820cbe7..4fa8d418a3 100644 --- a/UI/BigComponents/MoreScreen.ts +++ b/UI/BigComponents/MoreScreen.ts @@ -9,7 +9,7 @@ import BaseUIElement from "../BaseUIElement"; import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; import {UIEventSource} from "../../Logic/UIEventSource"; import Loc from "../../Models/Loc"; -import UserDetails, {OsmConnection} from "../../Logic/Osm/OsmConnection"; +import {OsmConnection} from "../../Logic/Osm/OsmConnection"; import UserRelatedState from "../../Logic/State/UserRelatedState"; import Toggle from "../Input/Toggle"; import {Utils} from "../../Utils"; @@ -53,7 +53,8 @@ export default class MoreScreen extends Combine { icon: string, title: any, shortDescription: any, - definition?: any + definition?: any, + mustHaveLanguage?: boolean }, isCustom: boolean = false ): BaseUIElement { @@ -109,7 +110,7 @@ export default class MoreScreen extends Combine { return new SubtleButton(layout.icon, new Combine([ `

`, - new Translation(layout.title), + new Translation(layout.title, !isCustom && !layout.mustHaveLanguage ? "themes:"+layout.id+".title" : undefined), `
`, `
`, new Translation(layout.shortDescription)?.SetClass("subtle") ?? "", @@ -142,9 +143,10 @@ export default class MoreScreen extends Combine { icon: string, title: any, shortDescription: any, - definition?: any + definition?: any, + isOfficial: boolean } = JSON.parse(str) - + value.isOfficial = false return MoreScreen.createLinkButton(state, value, true) } catch (e) { console.debug("Could not parse unofficial theme information for " + id, "The json is: ", str, e) diff --git a/UI/BigComponents/SimpleAddUI.ts b/UI/BigComponents/SimpleAddUI.ts index 87e8730efd..2e8371a0a9 100644 --- a/UI/BigComponents/SimpleAddUI.ts +++ b/UI/BigComponents/SimpleAddUI.ts @@ -117,7 +117,7 @@ export default class SimpleAddUI extends Toggle { selectedPreset.setData(undefined) } - const message = Translations.t.general.add.addNew.Subs({category: preset.name}); + const message = Translations.t.general.add.addNew.Subs({category: preset.name}, preset.name["context"]); return new ConfirmLocationOfPoint(state, filterViewIsOpened, preset, message, state.LastClickLocation.data, @@ -184,12 +184,13 @@ export default class SimpleAddUI extends Toggle { private static CreatePresetSelectButton(preset: PresetInfo) { + const title = Translations.t.general.add.addNew.Subs({ + category: preset.name + }, preset.name["context"]) return new SubtleButton( preset.icon(), new Combine([ - Translations.t.general.add.addNew.Subs({ - category: preset.name - }).SetClass("font-bold"), + title.SetClass("font-bold"), Translations.WT(preset.description)?.FirstSentence() ]).SetClass("flex flex-col") ) diff --git a/UI/BigComponents/TranslatorsPanel.ts b/UI/BigComponents/TranslatorsPanel.ts new file mode 100644 index 0000000000..87f6118fa5 --- /dev/null +++ b/UI/BigComponents/TranslatorsPanel.ts @@ -0,0 +1,124 @@ +import Toggle from "../Input/Toggle"; +import Lazy from "../Base/Lazy"; +import {Utils} from "../../Utils"; +import Translations from "../i18n/Translations"; +import Combine from "../Base/Combine"; +import Locale from "../i18n/Locale"; +import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; +import {Translation} from "../i18n/Translation"; +import {VariableUiElement} from "../Base/VariableUIElement"; +import Link from "../Base/Link"; +import LinkToWeblate from "../Base/LinkToWeblate"; +import Toggleable from "../Base/Toggleable"; +import Title from "../Base/Title"; +import {UIEventSource} from "../../Logic/UIEventSource"; +import {SubtleButton} from "../Base/SubtleButton"; +import Svg from "../../Svg"; + + +class TranslatorsPanelContent extends Combine { + constructor(layout: LayoutConfig, isTranslator: UIEventSource) { + const t = Translations.t.translations + const completeness = new Map() + let total = 0 + const untranslated = new Map() + Utils.WalkObject(layout, (o, path) => { + const translation = o; + for (const lang of translation.SupportedLanguages()) { + completeness.set(lang, 1 + (completeness.get(lang) ?? 0)) + } + layout.title.SupportedLanguages().forEach(ln => { + const trans = translation.translations + if (trans["*"] !== undefined) { + return; + } + if (trans[ln] === undefined) { + if (!untranslated.has(ln)) { + untranslated.set(ln, []) + } + untranslated.get(ln).push(translation.context) + } + }) + if(translation.translations["*"] === undefined){ + total++ + } + }, o => { + if (o === undefined || o === null) { + return false; + } + return o instanceof Translation; + }) + + + const seed = t.completeness + for (const ln of Array.from(completeness.keys())) { + if(ln === "*"){ + continue + } + if (seed.translations[ln] === undefined) { + seed.translations[ln] = seed.translations["en"] + } + } + + const completenessTr = {} + const completenessPercentage = {} + seed.SupportedLanguages().forEach(ln => { + completenessTr[ln] = ""+(completeness.get(ln) ?? 0) + completenessPercentage[ln] = ""+Math.round(100 * (completeness.get(ln) ?? 0) / total) + }) + + // "translationCompleteness": "Translations for {theme} in {language} are at {percentage}: {translated} out of {total}", + const translated = seed.Subs({total, theme: layout.title, + percentage: new Translation(completenessPercentage), + translated: new Translation(completenessTr) + }) + + const missingTranslationsFor = (ln: string) => Utils.NoNull(untranslated.get(ln) ?? []) + .filter(ctx => ctx.indexOf(':') > 0) + .map(ctx => ctx.replace(/note_import_[a-zA-Z0-9_]*/, "note_import")) + .map(context => new Link(context, LinkToWeblate.hrefToWeblate(ln, context), true)) + + const disable = new SubtleButton(undefined, t.deactivate) + .onClick(() => { + Locale.showLinkToWeblate.setData(false) + }) + + super([ + new Title( + Translations.t.translations.activateButton, + ), + new Toggle(t.isTranslator.SetClass("thanks block"), undefined, isTranslator), + t.help, + translated, + disable, + new VariableUiElement(Locale.language.map(ln => { + + const missing = missingTranslationsFor(ln) + if (missing.length === 0) { + return undefined + } + return new Toggleable( + new Title(Translations.t.translations.missing.Subs({count: missing.length})), + new Combine(missing).SetClass("flex flex-col") + ) + })) + ]) + + } +} + +export default class TranslatorsPanel extends Toggle { + + + constructor(state: { layoutToUse: LayoutConfig, isTranslator: UIEventSource }, iconStyle?: string) { + const t = Translations.t.translations + super( + new Lazy(() => new TranslatorsPanelContent(state.layoutToUse, state.isTranslator) + ).SetClass("flex flex-col"), + new SubtleButton(Svg.translate_ui().SetStyle(iconStyle), t.activateButton).onClick(() => Locale.showLinkToWeblate.setData(true)), + Locale.showLinkToWeblate + ) + this.SetClass("hidden-on-mobile") + + } +} diff --git a/UI/SpecialVisualizations.ts b/UI/SpecialVisualizations.ts index 92ee0dd111..046bd28f60 100644 --- a/UI/SpecialVisualizations.ts +++ b/UI/SpecialVisualizations.ts @@ -842,7 +842,7 @@ export default class SpecialVisualizations { return new LoginToggle( new Combine([ - new Title("Add a comment"), + new Title(t.addAComment), textField, new Combine([ stateButtons.SetClass("sm:mr-2"), diff --git a/UI/SubstitutedTranslation.ts b/UI/SubstitutedTranslation.ts index 59d7ae50ba..bccb6e4e2c 100644 --- a/UI/SubstitutedTranslation.ts +++ b/UI/SubstitutedTranslation.ts @@ -9,6 +9,7 @@ import Combine from "./Base/Combine"; import BaseUIElement from "./BaseUIElement"; import {DefaultGuiState} from "./DefaultGuiState"; import FeaturePipelineState from "../Logic/State/FeaturePipelineState"; +import LinkToWeblate from "./Base/LinkToWeblate"; export class SubstitutedTranslation extends VariableUiElement { @@ -34,6 +35,8 @@ export class SubstitutedTranslation extends VariableUiElement { ) }) + const linkToWeblate = new LinkToWeblate(translation.context, translation.translations) + super( Locale.language.map(language => { let txt = translation?.textFor(language); @@ -44,7 +47,7 @@ export class SubstitutedTranslation extends VariableUiElement { txt = txt.replace(new RegExp(`{${key}}`, "g"), `{${key}()}`) }) - return new Combine(SubstitutedTranslation.ExtractSpecialComponents(txt, extraMappings).map( + const allElements = SubstitutedTranslation.ExtractSpecialComponents(txt, extraMappings).map( proto => { if (proto.fixed !== undefined) { return new VariableUiElement(tagsSource.map(tags => Utils.SubstituteKeys(proto.fixed, tags))); @@ -56,8 +59,12 @@ export class SubstitutedTranslation extends VariableUiElement { console.error("SPECIALRENDERING FAILED for", tagsSource.data?.id, e) return new FixedUiElement(`Could not generate special rendering for ${viz.func.funcName}(${viz.args.join(", ")}) ${e}`).SetStyle("alert") } - } - )) + }); + allElements.push(linkToWeblate) + + return new Combine( + allElements + ) }) ) diff --git a/UI/Wikipedia/WikidataPreviewBox.ts b/UI/Wikipedia/WikidataPreviewBox.ts index 7a94c4e02a..a5f125e5cc 100644 --- a/UI/Wikipedia/WikidataPreviewBox.ts +++ b/UI/Wikipedia/WikidataPreviewBox.ts @@ -39,16 +39,12 @@ export default class WikidataPreviewBox extends VariableUiElement { { property: "P569", requires: WikidataPreviewBox.isHuman, - display: new Translation({ - "*": "Born: {value}" - }) + display: Translations.t.general.wikipedia.previewbox.born }, { property: "P570", requires: WikidataPreviewBox.isHuman, - display: new Translation({ - "*": "Died: {value}" - }) + display:Translations.t.general.wikipedia.previewbox.died } ] diff --git a/UI/i18n/Locale.ts b/UI/i18n/Locale.ts index 7c71fcbe12..47e99c110a 100644 --- a/UI/i18n/Locale.ts +++ b/UI/i18n/Locale.ts @@ -7,7 +7,8 @@ import {QueryParameters} from "../../Logic/Web/QueryParameters"; export default class Locale { public static language: UIEventSource = Locale.setup(); - + public static showLinkToWeblate: UIEventSource = new UIEventSource(false); + private static setup() { const source = LocalStorageSource.Get('language', "en"); if (!Utils.runningFromConsole) { diff --git a/UI/i18n/Translation.ts b/UI/i18n/Translation.ts index 7c70277094..8e3af95f02 100644 --- a/UI/i18n/Translation.ts +++ b/UI/i18n/Translation.ts @@ -1,15 +1,21 @@ import Locale from "./Locale"; import {Utils} from "../../Utils"; import BaseUIElement from "../BaseUIElement"; +import Link from "../Base/Link"; +import Svg from "../../Svg"; +import {VariableUiElement} from "../Base/VariableUIElement"; +import LinkToWeblate from "../Base/LinkToWeblate"; export class Translation extends BaseUIElement { public static forcedLanguage = undefined; public readonly translations: object + context?: string; constructor(translations: object, context?: string) { super() + this.context = context; if (translations === undefined) { console.error("Translation without content at "+context) throw `Translation without content (${context})` @@ -101,13 +107,35 @@ export class Translation extends BaseUIElement { InnerConstructElement(): HTMLElement { const el = document.createElement("span") const self = this + + Locale.language.addCallbackAndRun(_ => { if (self.isDestroyed) { return true } el.innerHTML = this.txt }) - return el; + + if (self.translations["*"] !== undefined || self.context === undefined || self.context?.indexOf(":") < 0) { + return el; + } + + const linkToWeblate = new LinkToWeblate(self.context, self.translations) + + const wrapper = document.createElement("span") + wrapper.appendChild(el) + wrapper.classList.add("flex") + Locale.showLinkToWeblate.addCallbackAndRun(doShow => { + + if (!doShow) { + return; + } + wrapper.appendChild(linkToWeblate.ConstructElement()) + return true; + }) + + + return wrapper ; } public SupportedLanguages(): string[] { @@ -131,11 +159,25 @@ export class Translation extends BaseUIElement { return this.SupportedLanguages().map(lng => this.translations[lng]); } - public Subs(text: any): Translation { - return this.OnEveryLanguage((template, lang) => Utils.SubstituteKeys(template, text, lang)) + /** + * Substitutes text in a translation. + * If a translation is passed, it'll be fused + * + * // Should replace simple keys + * new Translation({"en": "Some text {key}"}).Subs({key: "xyz"}).textFor("en") // => "Some text xyz" + * + * // Should fuse translations + * const subpart = new Translation({"en": "subpart","nl":"onderdeel"}) + * const tr = new Translation({"en": "Full sentence with {part}", nl: "Volledige zin met {part}"}) + * const subbed = tr.Subs({part: subpart}) + * subbed.textFor("en") // => "Full sentence with subpart" + * subbed.textFor("nl") // => "Volledige zin met onderdeel" + */ + public Subs(text: any, context?: string): Translation { + return this.OnEveryLanguage((template, lang) => Utils.SubstituteKeys(template, text, lang), context) } - public OnEveryLanguage(f: (s: string, language: string) => string): Translation { + public OnEveryLanguage(f: (s: string, language: string) => string, context?: string): Translation { const newTranslations = {}; for (const lang in this.translations) { if (!this.translations.hasOwnProperty(lang)) { @@ -143,37 +185,10 @@ export class Translation extends BaseUIElement { } newTranslations[lang] = f(this.translations[lang], lang); } - return new Translation(newTranslations); + return new Translation(newTranslations, context ?? this.context); } - - /** - * - * Given a translation such as `{en: "How much of bicycle_types are rented here}` (which is this translation) - * and a translation object `{ en: "electrical bikes" }`, plus the translation specification `bicycle_types`, will return - * a new translation: - * `{en: "How much electrical bikes are rented here?"}` - * - * @param translationObject - * @param stringToReplace - * @constructor - */ - public Fuse(translationObject: Translation, stringToReplace: string): Translation{ - const translations = this.translations - const newTranslations = {} - for (const lang in translations) { - const target = translationObject.textFor(lang) - if(target === undefined){ - continue - } - if(typeof target !== "string"){ - throw "Invalid object in Translation.fuse: translationObject['"+lang+"'] is not a string, it is: "+JSON.stringify(target) - } - newTranslations[lang] = this.translations[lang].replaceAll(stringToReplace, target) - } - return new Translation(newTranslations) - } - + /** * Replaces the given string with the given text in the language. * Other substitutions are left in place @@ -190,7 +205,7 @@ export class Translation extends BaseUIElement { } public Clone() { - return new Translation(this.translations) + return new Translation(this.translations, this.context) } FirstSentence() { @@ -256,4 +271,6 @@ export class Translation extends BaseUIElement { AsMarkdown(): string { return this.txt } + + } \ No newline at end of file diff --git a/Utils.ts b/Utils.ts index 0a993b06c4..1aa02822b3 100644 --- a/Utils.ts +++ b/Utils.ts @@ -513,6 +513,37 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be return cp } + /** + * Walks an object recursively. Will hang on objects with loops + */ + static WalkObject(json: any, collect: (v: number | string | boolean | undefined, path: string[]) => any, isLeaf: (object) => boolean = undefined, path = []) { + if (json === undefined) { + return; + } + const jtp = typeof json + if (isLeaf !== undefined) { + if (jtp !== "object") { + return + } + + if (isLeaf(json)) { + return collect(json, path) + } + } else if (jtp === "boolean" || jtp === "string" || jtp === "number") { + return collect(json,path) + } + if (Array.isArray(json)) { + return json.map((sub,i) => { + return Utils.WalkObject(sub, collect, isLeaf,[...path, i]); + }) + } + + for (const key in json) { + Utils.WalkObject(json[key], collect, isLeaf, [...path,key]) + } + } + + static getOrSetDefault(dict: Map, k: K, v: () => V) { let found = dict.get(k); if (found !== undefined) { diff --git a/assets/contributors.json b/assets/contributors.json index dc33c379b7..743b68e76d 100644 --- a/assets/contributors.json +++ b/assets/contributors.json @@ -1 +1 @@ -{"contributors":[{"commits":3145,"contributor":"Pieter Vander Vennet"},{"commits":64,"contributor":"Robin van der Linde"},{"commits":38,"contributor":"Tobias"},{"commits":33,"contributor":"Christian Neumann"},{"commits":31,"contributor":"Win Olario"},{"commits":31,"contributor":"Pieter Fiers"},{"commits":26,"contributor":"karelleketers"},{"commits":24,"contributor":"Ward"},{"commits":20,"contributor":"Joost"},{"commits":19,"contributor":"Sebastian Kürten"},{"commits":18,"contributor":"Arno Deceuninck"},{"commits":17,"contributor":"pgm-chardelv1"},{"commits":16,"contributor":"Hosted Weblate"},{"commits":15,"contributor":"ToastHawaii"},{"commits":13,"contributor":"riQQ"},{"commits":13,"contributor":"Nicole"},{"commits":12,"contributor":"Tobias Jordans"},{"commits":12,"contributor":"Bavo Vanderghote"},{"commits":10,"contributor":"LiamSimons"},{"commits":8,"contributor":"dependabot[bot]"},{"commits":8,"contributor":"Midgard"},{"commits":7,"contributor":"RobJN"},{"commits":7,"contributor":"Mateusz Konieczny"},{"commits":7,"contributor":"Flo Edelmann"},{"commits":7,"contributor":"Binnette"},{"commits":7,"contributor":"yopaseopor"},{"commits":6,"contributor":"pelderson"},{"commits":5,"contributor":"David Haberthür"},{"commits":4,"contributor":"Ward Beyens"},{"commits":3,"contributor":"Léo Villeveygoux"},{"commits":2,"contributor":"arrival-spring"},{"commits":2,"contributor":"Strubbl"},{"commits":2,"contributor":"RayBB"},{"commits":2,"contributor":"Charlotte Delvaux"},{"commits":2,"contributor":"Supaplex"},{"commits":2,"contributor":"pbarban"},{"commits":2,"contributor":"graveelius"},{"commits":2,"contributor":"Stanislas Gueniffey"},{"commits":1,"contributor":"Jiří Podhorecký"},{"commits":1,"contributor":"Mark Rogerson"},{"commits":1,"contributor":"nicole_s"},{"commits":1,"contributor":"SC"},{"commits":1,"contributor":"Raphael Das Gupta"},{"commits":1,"contributor":"Nikolay Korotkiy"},{"commits":1,"contributor":"Seppe Santens"},{"commits":1,"contributor":"root"},{"commits":1,"contributor":"Allan Nordhøy"},{"commits":1,"contributor":"快乐的老鼠宝宝"},{"commits":1,"contributor":"Sebastian"},{"commits":1,"contributor":"Hiroshi Miura"},{"commits":1,"contributor":"riiga"},{"commits":1,"contributor":"Vinicius"},{"commits":1,"contributor":"Alexey Shabanov"},{"commits":1,"contributor":"Polgár Sándor"},{"commits":1,"contributor":"SiegbjornSitumeang"},{"commits":1,"contributor":"Marco"},{"commits":1,"contributor":"mozita"},{"commits":1,"contributor":"Schouppe Joost"},{"commits":1,"contributor":"Thibault Molleman"},{"commits":1,"contributor":"Noémie"},{"commits":1,"contributor":"Tomas Fiers"},{"commits":1,"contributor":"tbowdecl97"}]} \ No newline at end of file +{"contributors":[{"commits":3421,"contributor":"Pieter Vander Vennet"},{"commits":86,"contributor":"Robin van der Linde"},{"commits":39,"contributor":"Tobias"},{"commits":33,"contributor":"Christian Neumann"},{"commits":31,"contributor":"Win Olario"},{"commits":31,"contributor":"Pieter Fiers"},{"commits":26,"contributor":"karelleketers"},{"commits":24,"contributor":"Ward"},{"commits":20,"contributor":"Joost"},{"commits":19,"contributor":"Sebastian Kürten"},{"commits":18,"contributor":"riQQ"},{"commits":18,"contributor":"Arno Deceuninck"},{"commits":17,"contributor":"pgm-chardelv1"},{"commits":16,"contributor":"Hosted Weblate"},{"commits":15,"contributor":"ToastHawaii"},{"commits":13,"contributor":"Nicole"},{"commits":12,"contributor":"Tobias Jordans"},{"commits":12,"contributor":"Bavo Vanderghote"},{"commits":10,"contributor":"LiamSimons"},{"commits":8,"contributor":"dependabot[bot]"},{"commits":8,"contributor":"Midgard"},{"commits":7,"contributor":"RobJN"},{"commits":7,"contributor":"Mateusz Konieczny"},{"commits":7,"contributor":"Flo Edelmann"},{"commits":7,"contributor":"Binnette"},{"commits":7,"contributor":"yopaseopor"},{"commits":6,"contributor":"pelderson"},{"commits":5,"contributor":"David Haberthür"},{"commits":4,"contributor":"Ward Beyens"},{"commits":3,"contributor":"Weblate (bot)"},{"commits":3,"contributor":"Léo Villeveygoux"},{"commits":2,"contributor":"Codain"},{"commits":2,"contributor":"arrival-spring"},{"commits":2,"contributor":"Strubbl"},{"commits":2,"contributor":"RayBB"},{"commits":2,"contributor":"Charlotte Delvaux"},{"commits":2,"contributor":"Supaplex"},{"commits":2,"contributor":"pbarban"},{"commits":2,"contributor":"graveelius"},{"commits":2,"contributor":"Stanislas Gueniffey"},{"commits":1,"contributor":"Štefan Baebler"},{"commits":1,"contributor":"Jiří Podhorecký"},{"commits":1,"contributor":"Mark Rogerson"},{"commits":1,"contributor":"nicole_s"},{"commits":1,"contributor":"SC"},{"commits":1,"contributor":"Raphael Das Gupta"},{"commits":1,"contributor":"Nikolay Korotkiy"},{"commits":1,"contributor":"Seppe Santens"},{"commits":1,"contributor":"root"},{"commits":1,"contributor":"Allan Nordhøy"},{"commits":1,"contributor":"快乐的老鼠宝宝"},{"commits":1,"contributor":"Sebastian"},{"commits":1,"contributor":"Hiroshi Miura"},{"commits":1,"contributor":"riiga"},{"commits":1,"contributor":"Vinicius"},{"commits":1,"contributor":"Alexey Shabanov"},{"commits":1,"contributor":"Polgár Sándor"},{"commits":1,"contributor":"SiegbjornSitumeang"},{"commits":1,"contributor":"Marco"},{"commits":1,"contributor":"mozita"},{"commits":1,"contributor":"Schouppe Joost"},{"commits":1,"contributor":"Thibault Molleman"},{"commits":1,"contributor":"Noémie"},{"commits":1,"contributor":"Tomas Fiers"},{"commits":1,"contributor":"tbowdecl97"}]} \ No newline at end of file diff --git a/assets/layers/bike_shop/bike_shop.json b/assets/layers/bike_shop/bike_shop.json index b77f8df949..32b242157c 100644 --- a/assets/layers/bike_shop/bike_shop.json +++ b/assets/layers/bike_shop/bike_shop.json @@ -298,18 +298,13 @@ }, "id": "bike_shop-email" }, - { - "render": "{opening_hours_table(opening_hours)}", - "question": "When is this shop opened?", - "freeform": { - "key": "opening_hours", - "type": "opening_hours" - }, - "id": "bike_shop-opening_hours" - }, + "opening_hours", "description", { - "render": "Enkel voor {access}", + "render": { + "en": "Only accessible to {access}", + "nl": "Enkel voor {access}" + }, "freeform": { "key": "access" }, diff --git a/assets/themes/uk_addresses/uk_addresses.json b/assets/themes/uk_addresses/uk_addresses.json index c7d1cc5524..80bccb856b 100644 --- a/assets/themes/uk_addresses/uk_addresses.json +++ b/assets/themes/uk_addresses/uk_addresses.json @@ -123,7 +123,7 @@ }, { "id": "uk_addresses_import_button", - "render":{ + "render": { "special": { "type": "import_button", "targetLayer": "address", diff --git a/assets/translators.json b/assets/translators.json index b2d361f78f..7713d90b98 100644 --- a/assets/translators.json +++ b/assets/translators.json @@ -1 +1 @@ -{"contributors":[{"commits":60,"contributor":"danieldegroot2"},{"commits":41,"contributor":"kjon"},{"commits":29,"contributor":"Artem"},{"commits":23,"contributor":"Pieter Vander Vennet"},{"commits":22,"contributor":"Supaplex"},{"commits":22,"contributor":"Marco"},{"commits":22,"contributor":"Allan Nordhøy"},{"commits":21,"contributor":"Babos Gábor"},{"commits":21,"contributor":"Anonymous"},{"commits":15,"contributor":"WaldiS"},{"commits":14,"contributor":"J. Lavoie"},{"commits":13,"contributor":"SC"},{"commits":10,"contributor":"Reza Almanda"},{"commits":9,"contributor":"Jacque Fresco"},{"commits":8,"contributor":"LeJun"},{"commits":8,"contributor":"Irina"},{"commits":6,"contributor":"Nikolay Korotkiy"},{"commits":6,"contributor":"William Weber Berrutti"},{"commits":6,"contributor":"lvgx"},{"commits":5,"contributor":"Piotr"},{"commits":5,"contributor":"Robin van der Linde"},{"commits":5,"contributor":"seppesantens"},{"commits":5,"contributor":"Vinicius"},{"commits":5,"contributor":"Alexey Shabanov"},{"commits":4,"contributor":"Jeff Huang"},{"commits":4,"contributor":"Joost"},{"commits":4,"contributor":"Adolfo Jayme Barrientos"},{"commits":4,"contributor":"Polgár Sándor"},{"commits":4,"contributor":"David Haberthür"},{"commits":4,"contributor":"phlostically"},{"commits":4,"contributor":"Jan Zabel"},{"commits":4,"contributor":"Fabio Bettani"},{"commits":3,"contributor":"Sasha"},{"commits":3,"contributor":"Jose Luis Infante"},{"commits":3,"contributor":"Francois"},{"commits":3,"contributor":"Eduardo Addad de Oliveira"},{"commits":3,"contributor":"Wiktor Przybylski"},{"commits":3,"contributor":"Erik Palm"},{"commits":3,"contributor":"vankos"},{"commits":3,"contributor":"JCGF-OSM"},{"commits":3,"contributor":"Hiroshi Miura"},{"commits":3,"contributor":"SiegbjornSitumeang"},{"commits":2,"contributor":"わたなべけんご"},{"commits":2,"contributor":"Mateusz Konieczny"},{"commits":2,"contributor":"Kristoffer Grundström"},{"commits":2,"contributor":"el_libre como el chaval"},{"commits":2,"contributor":"Sebastian Kürten"},{"commits":2,"contributor":"Damian Tokarski"},{"commits":2,"contributor":"mic140"},{"commits":2,"contributor":"Heiko"},{"commits":2,"contributor":"Leo Alcaraz"},{"commits":1,"contributor":"sparky-oxford"},{"commits":1,"contributor":"jcn706"},{"commits":1,"contributor":"whatismoss"},{"commits":1,"contributor":"LePirlouit"},{"commits":1,"contributor":"SoftwareByRedline"},{"commits":1,"contributor":"plic ploc"},{"commits":1,"contributor":"Janina Ellinghaus"},{"commits":1,"contributor":"ssantos"},{"commits":1,"contributor":"Andre Fajar N"},{"commits":1,"contributor":"Ahen Purwakarta"},{"commits":1,"contributor":"Luna Jernberg"},{"commits":1,"contributor":"Rodrigo Tavares"},{"commits":1,"contributor":"liimee"},{"commits":1,"contributor":"Michał Targoński"},{"commits":1,"contributor":"Sean Young"},{"commits":1,"contributor":"Damian Pułka"},{"commits":1,"contributor":"Iváns"},{"commits":1,"contributor":"快乐的老鼠宝宝"},{"commits":1,"contributor":"Eric Armijo"},{"commits":1,"contributor":"Beardhatcode"},{"commits":1,"contributor":"riiga"},{"commits":1,"contributor":"Carlos Ramos Carreño"}]} \ No newline at end of file +{"contributors":[{"commits":60,"contributor":"danieldegroot2"},{"commits":43,"contributor":"kjon"},{"commits":29,"contributor":"Artem"},{"commits":26,"contributor":"Pieter Vander Vennet"},{"commits":25,"contributor":"Babos Gábor"},{"commits":22,"contributor":"Supaplex"},{"commits":22,"contributor":"Marco"},{"commits":22,"contributor":"Allan Nordhøy"},{"commits":21,"contributor":"Anonymous"},{"commits":15,"contributor":"WaldiS"},{"commits":14,"contributor":"Reza Almanda"},{"commits":14,"contributor":"J. Lavoie"},{"commits":13,"contributor":"SC"},{"commits":10,"contributor":"Robin van der Linde"},{"commits":9,"contributor":"Jacque Fresco"},{"commits":8,"contributor":"Joost"},{"commits":8,"contributor":"LeJun"},{"commits":8,"contributor":"Irina"},{"commits":6,"contributor":"Štefan Baebler"},{"commits":6,"contributor":"seppesantens"},{"commits":6,"contributor":"Nikolay Korotkiy"},{"commits":6,"contributor":"William Weber Berrutti"},{"commits":6,"contributor":"lvgx"},{"commits":5,"contributor":"Romain de Bossoreille"},{"commits":5,"contributor":"Piotr"},{"commits":5,"contributor":"Vinicius"},{"commits":5,"contributor":"Alexey Shabanov"},{"commits":4,"contributor":"Jeff Huang"},{"commits":4,"contributor":"Adolfo Jayme Barrientos"},{"commits":4,"contributor":"Polgár Sándor"},{"commits":4,"contributor":"David Haberthür"},{"commits":4,"contributor":"phlostically"},{"commits":4,"contributor":"Jan Zabel"},{"commits":4,"contributor":"Fabio Bettani"},{"commits":3,"contributor":"Sasha"},{"commits":3,"contributor":"Jose Luis Infante"},{"commits":3,"contributor":"Francois"},{"commits":3,"contributor":"Eduardo Addad de Oliveira"},{"commits":3,"contributor":"Wiktor Przybylski"},{"commits":3,"contributor":"Erik Palm"},{"commits":3,"contributor":"vankos"},{"commits":3,"contributor":"JCGF-OSM"},{"commits":3,"contributor":"Hiroshi Miura"},{"commits":3,"contributor":"SiegbjornSitumeang"},{"commits":2,"contributor":"MeblIkea"},{"commits":2,"contributor":"快乐的老鼠宝宝"},{"commits":2,"contributor":"わたなべけんご"},{"commits":2,"contributor":"Mateusz Konieczny"},{"commits":2,"contributor":"Kristoffer Grundström"},{"commits":2,"contributor":"el_libre como el chaval"},{"commits":2,"contributor":"Sebastian Kürten"},{"commits":2,"contributor":"Damian Tokarski"},{"commits":2,"contributor":"mic140"},{"commits":2,"contributor":"Heiko"},{"commits":2,"contributor":"Leo Alcaraz"},{"commits":1,"contributor":"Falk Rund"},{"commits":1,"contributor":"pdassori"},{"commits":1,"contributor":"sparky-oxford"},{"commits":1,"contributor":"jcn706"},{"commits":1,"contributor":"whatismoss"},{"commits":1,"contributor":"LePirlouit"},{"commits":1,"contributor":"SoftwareByRedline"},{"commits":1,"contributor":"plic ploc"},{"commits":1,"contributor":"Janina Ellinghaus"},{"commits":1,"contributor":"ssantos"},{"commits":1,"contributor":"Andre Fajar N"},{"commits":1,"contributor":"Ahen Purwakarta"},{"commits":1,"contributor":"Luna Jernberg"},{"commits":1,"contributor":"Rodrigo Tavares"},{"commits":1,"contributor":"liimee"},{"commits":1,"contributor":"Michał Targoński"},{"commits":1,"contributor":"Sean Young"},{"commits":1,"contributor":"Damian Pułka"},{"commits":1,"contributor":"Iváns"},{"commits":1,"contributor":"Eric Armijo"},{"commits":1,"contributor":"Beardhatcode"},{"commits":1,"contributor":"riiga"},{"commits":1,"contributor":"Carlos Ramos Carreño"}]} \ No newline at end of file diff --git a/css/index-tailwind-output.css b/css/index-tailwind-output.css index db8ca3cc63..b0527f3239 100644 --- a/css/index-tailwind-output.css +++ b/css/index-tailwind-output.css @@ -1040,6 +1040,10 @@ video { height: 50%; } +.h-4 { + height: 1rem; +} + .h-screen { height: 100vh; } @@ -1060,10 +1064,6 @@ video { height: 4rem; } -.h-4 { - height: 1rem; -} - .h-0 { height: 0px; } @@ -1132,6 +1132,10 @@ video { width: 0px; } +.w-4 { + width: 1rem; +} + .w-screen { width: 100vw; } @@ -1140,10 +1144,6 @@ video { width: 2.75rem; } -.w-4 { - width: 1rem; -} - .w-16 { width: 4rem; } @@ -1412,6 +1412,11 @@ video { border-color: rgba(0, 0, 0, var(--tw-border-opacity)); } +.border-gray-400 { + --tw-border-opacity: 1; + border-color: rgba(156, 163, 175, var(--tw-border-opacity)); +} + .border-gray-300 { --tw-border-opacity: 1; border-color: rgba(209, 213, 219, var(--tw-border-opacity)); @@ -1422,11 +1427,6 @@ video { border-color: rgba(252, 165, 165, var(--tw-border-opacity)); } -.border-gray-400 { - --tw-border-opacity: 1; - border-color: rgba(156, 163, 175, var(--tw-border-opacity)); -} - .border-gray-200 { --tw-border-opacity: 1; border-color: rgba(229, 231, 235, var(--tw-border-opacity)); @@ -1441,6 +1441,11 @@ video { background-color: rgba(255, 255, 255, var(--tw-bg-opacity)); } +.bg-red-400 { + --tw-bg-opacity: 1; + background-color: rgba(248, 113, 113, var(--tw-bg-opacity)); +} + .bg-gray-400 { --tw-bg-opacity: 1; background-color: rgba(156, 163, 175, var(--tw-bg-opacity)); @@ -1518,6 +1523,10 @@ video { padding-left: 1rem; } +.pl-1 { + padding-left: 0.25rem; +} + .pl-2 { padding-left: 0.5rem; } @@ -1534,10 +1543,6 @@ video { padding-bottom: 0.25rem; } -.pl-1 { - padding-left: 0.25rem; -} - .pr-1 { padding-right: 0.25rem; } @@ -1908,6 +1913,10 @@ svg, img { display: none; } +.weblate-link { + /* Weblate-links are the little translation icon next to translatable sentences. Due to their special nature, they are exempt from some rules */ +} + .mapcontrol svg path { fill: var(--subtle-detail-color-contrast) !important; } diff --git a/index.css b/index.css index 921261d458..77c7b01600 100644 --- a/index.css +++ b/index.css @@ -151,6 +151,10 @@ svg, img { display: none; } +.weblate-link { + /* Weblate-links are the little translation icon next to translatable sentences. Due to their special nature, they are exempt from some rules */ +} + .mapcontrol svg path { fill: var(--subtle-detail-color-contrast) !important; } diff --git a/langs/en.json b/langs/en.json index d99a40519a..64792e2712 100644 --- a/langs/en.json +++ b/langs/en.json @@ -246,6 +246,10 @@ "loading": "Loading Wikipedia...", "noResults": "Nothing found for {search}", "noWikipediaPage": "This Wikidata item has no corresponding Wikipedia page yet.", + "previewbox": { + "born": "Born: {value}", + "died": "Died: {value}" + }, "searchWikidata": "Search on Wikidata", "wikipediaboxTitle": "Wikipedia" } @@ -359,6 +363,7 @@ "autoApply": "When changing the attributes {attr_names}, these attributes will automatically be changed on {count} other objects too" }, "notes": { + "addAComment": "Add a comment", "addComment": "Add comment", "addCommentAndClose": "Add comment and close", "addCommentPlaceholder": "Add a comment...", @@ -525,6 +530,15 @@ "split": "Split", "splitTitle": "Choose on the map where to split this road" }, + "translations": { + "activateButton": "Help to translate MapComplete", + "completeness": "Translations for {theme} in {language} are at {percentage}%: {translated} strings out of {total} are translated", + "deactivate": "Disable translation buttons", + "help": "Click the 'translate'-icon next to a string to enter or update a piece of text. You need a Weblate-account for this. Create one with your OSM-username to automatically unlock translation mode.", + "isTranslator": "Translation mode is active as your username matches the name of a previous translator", + "missing": "{count} untranslated strings", + "notImmediate": "Translations are not updated directly. This typically takes a few days" + }, "validation": { "color": { "description": "A color or hexcode" diff --git a/langs/layers/en.json b/langs/layers/en.json index 81b2589b96..98da61451c 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -1062,6 +1062,9 @@ }, "question": "Are there tools here to repair your own bike?" }, + "bike_shop-access": { + "render": "Only accessible to {access}" + }, "bike_shop-email": { "question": "What is the email address of {name}?" }, diff --git a/langs/layers/nl.json b/langs/layers/nl.json index 892b8d487c..894bf5b824 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -1062,6 +1062,9 @@ }, "question": "Biedt deze winkel gereedschap aan om je fiets zelf te herstellen?" }, + "bike_shop-access": { + "render": "Enkel voor {access}" + }, "bike_shop-email": { "question": "Wat is het email-adres van {name}?" }, diff --git a/scripts/generateLayerOverview.ts b/scripts/generateLayerOverview.ts index 5c8b4836b0..d9faf2d9ab 100644 --- a/scripts/generateLayerOverview.ts +++ b/scripts/generateLayerOverview.ts @@ -19,7 +19,7 @@ import {DesugaringContext} from "../Models/ThemeConfig/Conversion/Conversion"; class LayerOverviewUtils { - writeSmallOverview(themes: { id: string, title: any, shortDescription: any, icon: string, hideFromOverview: boolean }[]) { + writeSmallOverview(themes: { id: string, title: any, shortDescription: any, icon: string, hideFromOverview: boolean, mustHaveLanguage: boolean }[]) { const perId = new Map(); for (const theme of themes) { const data = { @@ -27,7 +27,8 @@ class LayerOverviewUtils { title: theme.title, shortDescription: theme.shortDescription, icon: theme.icon, - hideFromOverview: theme.hideFromOverview + hideFromOverview: theme.hideFromOverview, + mustHaveLanguage: theme.mustHaveLanguage } perId.set(theme.id, data); } @@ -73,6 +74,7 @@ class LayerOverviewUtils { continue } questions[key].id = key; + questions[key]["source"] = "shared-questions" dict.set(key, questions[key]) } for (const key in icons["default"]) { @@ -218,7 +220,8 @@ class LayerOverviewUtils { return { ...t, hideFromOverview: t.hideFromOverview ?? false, - shortDescription: t.shortDescription ?? new Translation(t.description).FirstSentence().translations + shortDescription: t.shortDescription ?? new Translation(t.description).FirstSentence().translations, + mustHaveLanguage: t.mustHaveLanguage?.length > 0 } })); return fixed; diff --git a/scripts/generateTranslations.ts b/scripts/generateTranslations.ts index a458af85ca..29b7501674 100644 --- a/scripts/generateTranslations.ts +++ b/scripts/generateTranslations.ts @@ -244,11 +244,11 @@ function isTranslation(tr: any): boolean { } /** - * Converts a translation object into something that can be added to the 'generated translations' - * @param obj - * @param depth + * Converts a translation object into something that can be added to the 'generated translations'. + * + * To debug the 'compiledTranslations', add a languageWhiteList to only generate a single language */ -function transformTranslation(obj: any, depth = 1) { +function transformTranslation(obj: any, path: string[] = [], languageWhitelist : string[] = undefined) { if (isTranslation(obj)) { return `new Translation( ${JSON.stringify(obj)} )` @@ -259,15 +259,24 @@ function transformTranslation(obj: any, depth = 1) { if (key === "#") { continue; } + if (key.match("^[a-zA-Z0-9_]*$") === null) { throw "Invalid character in key: " + key } - const value = obj[key] + let value = obj[key] if (isTranslation(value)) { - values += (Utils.Times((_) => " ", depth)) + "get " + key + "() { return new Translation(" + JSON.stringify(value) + ") }" + ",\n" + if(languageWhitelist !== undefined){ + const nv = {} + for (const ln of languageWhitelist) { + nv[ln] = value[ln] + } + value = nv; + } + values += `${Utils.Times((_) => " ", path.length + 1)}get ${key}() { return new Translation(${JSON.stringify(value)}, "core:${path.join(".")}.${key}") }, +` } else { - values += (Utils.Times((_) => " ", depth)) + key + ": " + transformTranslation(value, depth + 1) + ",\n" + values += (Utils.Times((_) => " ", path.length + 1)) + key + ": " + transformTranslation(value, [...path, key], languageWhitelist) + ",\n" } } return `{${values}}`; @@ -305,11 +314,11 @@ function formatFile(path) { */ function genTranslations() { const translations = JSON.parse(fs.readFileSync("./assets/generated/translations.json", "utf-8")) - const transformed = transformTranslation(translations); + const transformed = transformTranslation(translations); let module = `import {Translation} from "../../UI/i18n/Translation"\n\nexport default class CompiledTranslations {\n\n`; module += " public static t = " + transformed; - module += "}" + module += "\n }" fs.writeFileSync("./assets/generated/CompiledTranslations.ts", module); @@ -541,7 +550,7 @@ for (const path of allTranslationFiles) { } -// SOme validation +// Some validation TranslationPart.fromDirectory("./langs").validateStrict("./langs") TranslationPart.fromDirectory("./langs/layers").validateStrict("layers") TranslationPart.fromDirectory("./langs/themes").validateStrict("themes") From e22ce4d5b1f2d9b5fa54671a9fa33e2763591791 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 1 Apr 2022 21:17:27 +0200 Subject: [PATCH 10/37] Add some statistics on translations in script --- UI/BigComponents/TranslatorsPanel.ts | 160 +++++++++++++++------------ Utils.ts | 8 ++ scripts/generateTranslations.ts | 40 ++++++- 3 files changed, 135 insertions(+), 73 deletions(-) diff --git a/UI/BigComponents/TranslatorsPanel.ts b/UI/BigComponents/TranslatorsPanel.ts index 87f6118fa5..6d2c67f8a3 100644 --- a/UI/BigComponents/TranslatorsPanel.ts +++ b/UI/BigComponents/TranslatorsPanel.ts @@ -19,11 +19,97 @@ import Svg from "../../Svg"; class TranslatorsPanelContent extends Combine { constructor(layout: LayoutConfig, isTranslator: UIEventSource) { const t = Translations.t.translations - const completeness = new Map() + + const {completeness, untranslated, total} = TranslatorsPanel.MissingTranslationsFor(layout) + + const seed = t.completeness + for (const ln of Array.from(completeness.keys())) { + if(ln === "*"){ + continue + } + if (seed.translations[ln] === undefined) { + seed.translations[ln] = seed.translations["en"] + } + } + + const completenessTr = {} + const completenessPercentage = {} + seed.SupportedLanguages().forEach(ln => { + completenessTr[ln] = ""+(completeness.get(ln) ?? 0) + completenessPercentage[ln] = ""+Math.round(100 * (completeness.get(ln) ?? 0) / total) + }) + + const missingTranslationsFor = (ln: string) => Utils.NoNull(untranslated.get(ln) ?? []) + .map(ctx => ctx.replace(/note_import_[a-zA-Z0-9_]*/, "note_import")) + .map(context => new Link(context, LinkToWeblate.hrefToWeblate(ln, context), true)) + + + // "translationCompleteness": "Translations for {theme} in {language} are at {percentage}: {translated} out of {total}", + const translated = seed.Subs({total, theme: layout.title, + percentage: new Translation(completenessPercentage), + translated: new Translation(completenessTr) + }) + + super([ + new Title( + Translations.t.translations.activateButton, + ), + new Toggle(t.isTranslator.SetClass("thanks block"), undefined, isTranslator), + t.help, + translated, + /*Disable button:*/ + new SubtleButton(undefined, t.deactivate) + .onClick(() => { + Locale.showLinkToWeblate.setData(false) + }), + + new VariableUiElement(Locale.language.map(ln => { + + const missing = missingTranslationsFor(ln) + if (missing.length === 0) { + return undefined + } + return new Toggleable( + new Title(Translations.t.translations.missing.Subs({count: missing.length})), + new Combine(missing).SetClass("flex flex-col") + ) + })) + ]) + + } + +} + +export default class TranslatorsPanel extends Toggle { + + + constructor(state: { layoutToUse: LayoutConfig, isTranslator: UIEventSource }, iconStyle?: string) { + const t = Translations.t.translations + super( + new Lazy(() => new TranslatorsPanelContent(state.layoutToUse, state.isTranslator) + ).SetClass("flex flex-col"), + new SubtleButton(Svg.translate_ui().SetStyle(iconStyle), t.activateButton).onClick(() => Locale.showLinkToWeblate.setData(true)), + Locale.showLinkToWeblate + ) + this.SetClass("hidden-on-mobile") + + } + + + public static MissingTranslationsFor(layout: LayoutConfig) : {completeness: Map, untranslated: Map, total: number} { let total = 0 + const completeness = new Map() const untranslated = new Map() Utils.WalkObject(layout, (o, path) => { const translation = o; + if(translation.translations["*"] !== undefined){ + return + } + if(translation.context === undefined || translation.context.indexOf(":") < 0){ + // no source given - lets ignore + return + } + for (const lang of translation.SupportedLanguages()) { completeness.set(lang, 1 + (completeness.get(lang) ?? 0)) } @@ -49,76 +135,6 @@ class TranslatorsPanelContent extends Combine { return o instanceof Translation; }) - - const seed = t.completeness - for (const ln of Array.from(completeness.keys())) { - if(ln === "*"){ - continue - } - if (seed.translations[ln] === undefined) { - seed.translations[ln] = seed.translations["en"] - } - } - - const completenessTr = {} - const completenessPercentage = {} - seed.SupportedLanguages().forEach(ln => { - completenessTr[ln] = ""+(completeness.get(ln) ?? 0) - completenessPercentage[ln] = ""+Math.round(100 * (completeness.get(ln) ?? 0) / total) - }) - - // "translationCompleteness": "Translations for {theme} in {language} are at {percentage}: {translated} out of {total}", - const translated = seed.Subs({total, theme: layout.title, - percentage: new Translation(completenessPercentage), - translated: new Translation(completenessTr) - }) - - const missingTranslationsFor = (ln: string) => Utils.NoNull(untranslated.get(ln) ?? []) - .filter(ctx => ctx.indexOf(':') > 0) - .map(ctx => ctx.replace(/note_import_[a-zA-Z0-9_]*/, "note_import")) - .map(context => new Link(context, LinkToWeblate.hrefToWeblate(ln, context), true)) - - const disable = new SubtleButton(undefined, t.deactivate) - .onClick(() => { - Locale.showLinkToWeblate.setData(false) - }) - - super([ - new Title( - Translations.t.translations.activateButton, - ), - new Toggle(t.isTranslator.SetClass("thanks block"), undefined, isTranslator), - t.help, - translated, - disable, - new VariableUiElement(Locale.language.map(ln => { - - const missing = missingTranslationsFor(ln) - if (missing.length === 0) { - return undefined - } - return new Toggleable( - new Title(Translations.t.translations.missing.Subs({count: missing.length})), - new Combine(missing).SetClass("flex flex-col") - ) - })) - ]) - - } -} - -export default class TranslatorsPanel extends Toggle { - - - constructor(state: { layoutToUse: LayoutConfig, isTranslator: UIEventSource }, iconStyle?: string) { - const t = Translations.t.translations - super( - new Lazy(() => new TranslatorsPanelContent(state.layoutToUse, state.isTranslator) - ).SetClass("flex flex-col"), - new SubtleButton(Svg.translate_ui().SetStyle(iconStyle), t.activateButton).onClick(() => Locale.showLinkToWeblate.setData(true)), - Locale.showLinkToWeblate - ) - this.SetClass("hidden-on-mobile") - + return {completeness, untranslated, total} } } diff --git a/Utils.ts b/Utils.ts index 1aa02822b3..6d011ba6e1 100644 --- a/Utils.ts +++ b/Utils.ts @@ -183,6 +183,14 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be } return str.substr(0, l - 3) + "..."; } + + public static FixedLength(str: string, l: number) { + str = Utils.EllipsesAfter(str, l) + while(str.length < l){ + str = " "+str + } + return str; + } public static Dedup(arr: string[]): string[] { if (arr === undefined) { diff --git a/scripts/generateTranslations.ts b/scripts/generateTranslations.ts index 8ee1fe36b8..cc10944eb8 100644 --- a/scripts/generateTranslations.ts +++ b/scripts/generateTranslations.ts @@ -2,6 +2,8 @@ import * as fs from "fs"; import {readFileSync, writeFileSync} from "fs"; import {Utils} from "../Utils"; import ScriptUtils from "./ScriptUtils"; +import {AllKnownLayouts} from "../Customizations/AllKnownLayouts"; +import TranslatorsPanel from "../UI/BigComponents/TranslatorsPanel"; const knownLanguages = ["en", "nl", "de", "fr", "es", "gl", "ca"]; @@ -534,7 +536,7 @@ const l1 = generateTranslationsObjectFrom(ScriptUtils.getLayerFiles(), "layers") const l2 = generateTranslationsObjectFrom(ScriptUtils.getThemeFiles().filter(th => th.parsed.mustHaveLanguage === undefined), "themes") const l3 = generateTranslationsObjectFrom([{path: questionsPath, parsed: questionsParsed}], "shared-questions") -const usedLanguages = Utils.Dedup(l1.concat(l2).concat(l3)).filter(v => v !== "*") +const usedLanguages: string[] = Utils.Dedup(l1.concat(l2).concat(l3)).filter(v => v !== "*") usedLanguages.sort() fs.writeFileSync("./assets/generated/used_languages.json", JSON.stringify({languages: usedLanguages})) @@ -555,3 +557,39 @@ TranslationPart.fromDirectory("./langs").validateStrict("./langs") TranslationPart.fromDirectory("./langs/layers").validateStrict("layers") TranslationPart.fromDirectory("./langs/themes").validateStrict("themes") TranslationPart.fromDirectory("./langs/shared-questions").validateStrict("shared-questions") + + +// Some statistics +console.log(Utils.FixedLength("",12)+" "+usedLanguages.map(l => Utils.FixedLength(l, 6)).join("")) +const all = new Map() + +usedLanguages.forEach(ln => all.set(ln, [])) + +for (const layoutId of Array.from(AllKnownLayouts.allKnownLayouts.keys())) { + const layout = AllKnownLayouts.allKnownLayouts.get(layoutId) + + const {completeness, total} = TranslatorsPanel.MissingTranslationsFor(layout) + process.stdout.write(Utils.FixedLength(layout.id, 12)+" ") + for (const language of usedLanguages) { + const compl = completeness.get(language) + all.get(language).push((compl ?? 0) / total) + if(compl === undefined){ + process.stdout.write(" ") + continue + } + const percentage = Math.round(100 * compl / total) + process.stdout.write(Utils.FixedLength(percentage+"%", 6)) + } + process.stdout.write("\n") +} + +process.stdout.write(Utils.FixedLength("average", 12)+" ") +for (const language of usedLanguages) { + const ratios = all.get(language) + let sum = 0 + ratios.forEach(x => sum += x) + const percentage = Math.round(100 * (sum / ratios.length)) + process.stdout.write(Utils.FixedLength(percentage+"% ", 6)) +} +process.stdout.write("\n") +console.log(Utils.FixedLength("",12)+" "+usedLanguages.map(l => Utils.FixedLength(l, 6)).join("")) From 86d9047e5e5e8d2e3ea1894c75913f42c6c2d297 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 1 Apr 2022 21:35:10 +0200 Subject: [PATCH 11/37] Fix build --- scripts/generateTranslations.ts | 35 ------------------------- scripts/translationStatistics.ts | 44 ++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 35 deletions(-) create mode 100644 scripts/translationStatistics.ts diff --git a/scripts/generateTranslations.ts b/scripts/generateTranslations.ts index cc10944eb8..71dae3c505 100644 --- a/scripts/generateTranslations.ts +++ b/scripts/generateTranslations.ts @@ -558,38 +558,3 @@ TranslationPart.fromDirectory("./langs/layers").validateStrict("layers") TranslationPart.fromDirectory("./langs/themes").validateStrict("themes") TranslationPart.fromDirectory("./langs/shared-questions").validateStrict("shared-questions") - -// Some statistics -console.log(Utils.FixedLength("",12)+" "+usedLanguages.map(l => Utils.FixedLength(l, 6)).join("")) -const all = new Map() - -usedLanguages.forEach(ln => all.set(ln, [])) - -for (const layoutId of Array.from(AllKnownLayouts.allKnownLayouts.keys())) { - const layout = AllKnownLayouts.allKnownLayouts.get(layoutId) - - const {completeness, total} = TranslatorsPanel.MissingTranslationsFor(layout) - process.stdout.write(Utils.FixedLength(layout.id, 12)+" ") - for (const language of usedLanguages) { - const compl = completeness.get(language) - all.get(language).push((compl ?? 0) / total) - if(compl === undefined){ - process.stdout.write(" ") - continue - } - const percentage = Math.round(100 * compl / total) - process.stdout.write(Utils.FixedLength(percentage+"%", 6)) - } - process.stdout.write("\n") -} - -process.stdout.write(Utils.FixedLength("average", 12)+" ") -for (const language of usedLanguages) { - const ratios = all.get(language) - let sum = 0 - ratios.forEach(x => sum += x) - const percentage = Math.round(100 * (sum / ratios.length)) - process.stdout.write(Utils.FixedLength(percentage+"% ", 6)) -} -process.stdout.write("\n") -console.log(Utils.FixedLength("",12)+" "+usedLanguages.map(l => Utils.FixedLength(l, 6)).join("")) diff --git a/scripts/translationStatistics.ts b/scripts/translationStatistics.ts new file mode 100644 index 0000000000..12a81b9381 --- /dev/null +++ b/scripts/translationStatistics.ts @@ -0,0 +1,44 @@ +import {Utils} from "../Utils"; +import {AllKnownLayouts} from "../Customizations/AllKnownLayouts"; +import TranslatorsPanel from "../UI/BigComponents/TranslatorsPanel"; +import * as languages from "../assets/generated/used_languages.json" +{ + const usedLanguages = languages.languages + + // Some statistics + console.log(Utils.FixedLength("", 12) + " " + usedLanguages.map(l => Utils.FixedLength(l, 6)).join("")) + const all = new Map() + + usedLanguages.forEach(ln => all.set(ln, [])) + + for (const layoutId of Array.from(AllKnownLayouts.allKnownLayouts.keys())) { + const layout = AllKnownLayouts.allKnownLayouts.get(layoutId) + if(layout.hideFromOverview){ + continue + } + const {completeness, total} = TranslatorsPanel.MissingTranslationsFor(layout) + process.stdout.write(Utils.FixedLength(layout.id, 12) + " ") + for (const language of usedLanguages) { + const compl = completeness.get(language) + all.get(language).push((compl ?? 0) / total) + if (compl === undefined) { + process.stdout.write(" ") + continue + } + const percentage = Math.round(100 * compl / total) + process.stdout.write(Utils.FixedLength(percentage + "%", 6)) + } + process.stdout.write("\n") + } + + process.stdout.write(Utils.FixedLength("average", 12) + " ") + for (const language of usedLanguages) { + const ratios = all.get(language) + let sum = 0 + ratios.forEach(x => sum += x) + const percentage = Math.round(100 * (sum / ratios.length)) + process.stdout.write(Utils.FixedLength(percentage + "%", 6)) + } + process.stdout.write("\n") + console.log(Utils.FixedLength("", 12) + " " + usedLanguages.map(l => Utils.FixedLength(l, 6)).join("")) +} \ No newline at end of file From a037d0457761cffefa2b94def3c160850ce38d0d Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 3 Apr 2022 03:00:45 +0200 Subject: [PATCH 12/37] Enable all languages in translators mode --- Logic/State/UserRelatedState.ts | 7 +++---- UI/LanguagePicker.ts | 17 ++++++++++++++--- UI/i18n/Locale.ts | 9 ++++++++- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/Logic/State/UserRelatedState.ts b/Logic/State/UserRelatedState.ts index 3dafd0c68d..d18f536187 100644 --- a/Logic/State/UserRelatedState.ts +++ b/Logic/State/UserRelatedState.ts @@ -66,10 +66,6 @@ export default class UserRelatedState extends ElementsState { } }); - QueryParameters.GetBooleanQueryParameter("fs-translation-mode",false,"If set, will show the translation buttons") - .addCallbackAndRunD(tr => Locale.showLinkToWeblate.setData(Locale.showLinkToWeblate.data || tr)) - - this.changes = new Changes(this, layoutToUse?.isLeftRightSensitive() ?? false) @@ -126,6 +122,9 @@ export default class UserRelatedState extends ElementsState { if (layoutToUse === undefined) { return; } + if(Locale.showLinkToWeblate.data){ + return true; // Disable auto switching as we are in translators mode + } if (this.layoutToUse.language.indexOf(currentLanguage) < 0) { console.log( "Resetting language to", diff --git a/UI/LanguagePicker.ts b/UI/LanguagePicker.ts index 2945887c6d..3d1437e557 100644 --- a/UI/LanguagePicker.ts +++ b/UI/LanguagePicker.ts @@ -4,22 +4,33 @@ import BaseUIElement from "./BaseUIElement"; import * as native from "../assets/language_native.json" import * as language_translations from "../assets/language_translations.json" import {Translation} from "./i18n/Translation"; +import * as used_languages from "../assets/generated/used_languages.json" +import Lazy from "./Base/Lazy"; +import Toggle from "./Input/Toggle"; export default class LanguagePicker { public static CreateLanguagePicker( languages: string[], - label: string | BaseUIElement = "") { + label: string | BaseUIElement = "") : BaseUIElement{ if (languages === undefined || languages.length <= 1) { return undefined; } - return new DropDown(label, languages.map(lang => { + const allLanguages : string[] = used_languages.languages; + + const normalPicker = LanguagePicker.dropdownFor(languages, label); + const fullPicker = new Lazy(() => LanguagePicker.dropdownFor(allLanguages, label)) + return new Toggle(fullPicker, normalPicker, Locale.showLinkToWeblate) + } + + private static dropdownFor(languages: string[], label: string | BaseUIElement): BaseUIElement { + return new DropDown(label, languages.map(lang => { return {value: lang, shown: LanguagePicker.hybrid(lang) } } - ), Locale.language); + ), Locale.language) } private static hybrid(lang: string): Translation { diff --git a/UI/i18n/Locale.ts b/UI/i18n/Locale.ts index 47e99c110a..21f9505014 100644 --- a/UI/i18n/Locale.ts +++ b/UI/i18n/Locale.ts @@ -6,8 +6,8 @@ import {QueryParameters} from "../../Logic/Web/QueryParameters"; export default class Locale { + public static showLinkToWeblate: UIEventSource = new UIEventSource(false); public static language: UIEventSource = Locale.setup(); - public static showLinkToWeblate: UIEventSource = new UIEventSource(false); private static setup() { const source = LocalStorageSource.Get('language', "en"); @@ -20,6 +20,13 @@ export default class Locale { QueryParameters.GetQueryParameter("language", undefined, "The language to display mapcomplete in. Will be ignored in case a logged-in-user did set their language before. If the specified language does not exist, it will default to the first language in the theme."), true ) + QueryParameters.GetBooleanQueryParameter("fs-translation-mode",false,"If set, will show the translation buttons") + .addCallbackAndRunD(tr => { + console.log("Query parameter for translation mode is", tr) + Locale.showLinkToWeblate.setData(Locale.showLinkToWeblate.data || tr); + }) + + } return source; } From 7d255f88e6ec30b1127505e001129f64bfeaf126 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 3 Apr 2022 03:44:24 +0200 Subject: [PATCH 13/37] Update docs --- Docs/TagInfo/mapcomplete_entrances.json | 8 +-- Docs/TagInfo/mapcomplete_hailhydrant.json | 86 +++++++++++------------ Docs/TagInfo/mapcomplete_personal.json | 16 +++-- Docs/TagInfo/mapcomplete_playgrounds.json | 8 +++ 4 files changed, 67 insertions(+), 51 deletions(-) diff --git a/Docs/TagInfo/mapcomplete_entrances.json b/Docs/TagInfo/mapcomplete_entrances.json index d9962fafd3..c133427845 100644 --- a/Docs/TagInfo/mapcomplete_entrances.json +++ b/Docs/TagInfo/mapcomplete_entrances.json @@ -12,22 +12,22 @@ "tags": [ { "key": "highway", - "description": "The MapComplete theme Entrances has a layer Pedestrain paths showing features with this tag", + "description": "The MapComplete theme Entrances has a layer Pedestrian paths showing features with this tag", "value": "footway" }, { "key": "highway", - "description": "The MapComplete theme Entrances has a layer Pedestrain paths showing features with this tag", + "description": "The MapComplete theme Entrances has a layer Pedestrian paths showing features with this tag", "value": "path" }, { "key": "highway", - "description": "The MapComplete theme Entrances has a layer Pedestrain paths showing features with this tag", + "description": "The MapComplete theme Entrances has a layer Pedestrian paths showing features with this tag", "value": "corridor" }, { "key": "highway", - "description": "The MapComplete theme Entrances has a layer Pedestrain paths showing features with this tag", + "description": "The MapComplete theme Entrances has a layer Pedestrian paths showing features with this tag", "value": "steps" }, { diff --git a/Docs/TagInfo/mapcomplete_hailhydrant.json b/Docs/TagInfo/mapcomplete_hailhydrant.json index 65f073a2fd..8aedd27ba4 100644 --- a/Docs/TagInfo/mapcomplete_hailhydrant.json +++ b/Docs/TagInfo/mapcomplete_hailhydrant.json @@ -1,7 +1,7 @@ { "data_format": 1, "project": { - "name": "MapComplete Hydrants, Extinguishers, Fire stations, and Ambulance stations.", + "name": "MapComplete Hydrants, Extinguishers, Fire stations, and Ambulance stations", "description": "Map to show hydrants, extinguishers, fire stations, and ambulance stations.", "project_url": "https://mapcomplete.osm.be/hailhydrant", "doc_url": "https://github.com/pietervdvn/MapComplete/tree/master/assets/themes/", @@ -12,80 +12,80 @@ "tags": [ { "key": "emergency", - "description": "The MapComplete theme Hydrants, Extinguishers, Fire stations, and Ambulance stations. has a layer Map of hydrants showing features with this tag", + "description": "The MapComplete theme Hydrants, Extinguishers, Fire stations, and Ambulance stations has a layer Map of hydrants showing features with this tag", "value": "fire_hydrant" }, { "key": "colour", - "description": "Layer 'Map of hydrants' shows and asks freeform values for key 'colour' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')" + "description": "Layer 'Map of hydrants' shows and asks freeform values for key 'colour' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')" }, { "key": "colour", - "description": "Layer 'Map of hydrants' shows with a fixed text, namely 'The hydrant color is unknown.' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.') Picking this answer will delete the key colour.", + "description": "Layer 'Map of hydrants' shows with a fixed text, namely 'The hydrant color is unknown.' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations') Picking this answer will delete the key colour.", "value": "" }, { "key": "colour", - "description": "Layer 'Map of hydrants' shows colour=yellow with a fixed text, namely 'The hydrant color is yellow.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of hydrants' shows colour=yellow with a fixed text, namely 'The hydrant color is yellow.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "yellow" }, { "key": "colour", - "description": "Layer 'Map of hydrants' shows colour=red with a fixed text, namely 'The hydrant color is red.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of hydrants' shows colour=red with a fixed text, namely 'The hydrant color is red.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "red" }, { "key": "fire_hydrant:type", - "description": "Layer 'Map of hydrants' shows and asks freeform values for key 'fire_hydrant:type' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')" + "description": "Layer 'Map of hydrants' shows and asks freeform values for key 'fire_hydrant:type' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')" }, { "key": "fire_hydrant:type", - "description": "Layer 'Map of hydrants' shows with a fixed text, namely 'The hydrant type is unknown.' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.') Picking this answer will delete the key fire_hydrant:type.", + "description": "Layer 'Map of hydrants' shows with a fixed text, namely 'The hydrant type is unknown.' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations') Picking this answer will delete the key fire_hydrant:type.", "value": "" }, { "key": "fire_hydrant:type", - "description": "Layer 'Map of hydrants' shows fire_hydrant:type=pillar with a fixed text, namely 'Pillar type.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of hydrants' shows fire_hydrant:type=pillar with a fixed text, namely 'Pillar type.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "pillar" }, { "key": "fire_hydrant:type", - "description": "Layer 'Map of hydrants' shows fire_hydrant:type=pipe with a fixed text, namely 'Pipe type.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of hydrants' shows fire_hydrant:type=pipe with a fixed text, namely 'Pipe type.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "pipe" }, { "key": "fire_hydrant:type", - "description": "Layer 'Map of hydrants' shows fire_hydrant:type=wall with a fixed text, namely 'Wall type.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of hydrants' shows fire_hydrant:type=wall with a fixed text, namely 'Wall type.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "wall" }, { "key": "fire_hydrant:type", - "description": "Layer 'Map of hydrants' shows fire_hydrant:type=underground with a fixed text, namely 'Underground type.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of hydrants' shows fire_hydrant:type=underground with a fixed text, namely 'Underground type.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "underground" }, { "key": "emergency", - "description": "Layer 'Map of hydrants' shows emergency=fire_hydrant with a fixed text, namely 'The hydrant is (fully or partially) working' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of hydrants' shows emergency=fire_hydrant with a fixed text, namely 'The hydrant is (fully or partially) working' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "fire_hydrant" }, { "key": "disused:emergency", - "description": "Layer 'Map of hydrants' shows disused:emergency=fire_hydrant with a fixed text, namely 'The hydrant is unavailable' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of hydrants' shows disused:emergency=fire_hydrant with a fixed text, namely 'The hydrant is unavailable' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "fire_hydrant" }, { "key": "emergency", - "description": "Layer 'Map of hydrants' shows disused:emergency=fire_hydrant with a fixed text, namely 'The hydrant is unavailable' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.') Picking this answer will delete the key emergency.", + "description": "Layer 'Map of hydrants' shows disused:emergency=fire_hydrant with a fixed text, namely 'The hydrant is unavailable' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations') Picking this answer will delete the key emergency.", "value": "" }, { "key": "removed:emergency", - "description": "Layer 'Map of hydrants' shows removed:emergency=fire_hydrant with a fixed text, namely 'The hydrant has been removed' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of hydrants' shows removed:emergency=fire_hydrant with a fixed text, namely 'The hydrant has been removed' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "fire_hydrant" }, { "key": "emergency", - "description": "Layer 'Map of hydrants' shows removed:emergency=fire_hydrant with a fixed text, namely 'The hydrant has been removed' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.') Picking this answer will delete the key emergency.", + "description": "Layer 'Map of hydrants' shows removed:emergency=fire_hydrant with a fixed text, namely 'The hydrant has been removed' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations') Picking this answer will delete the key emergency.", "value": "" }, { @@ -106,21 +106,21 @@ }, { "key": "emergency", - "description": "The MapComplete theme Hydrants, Extinguishers, Fire stations, and Ambulance stations. has a layer Map of fire extinguishers. showing features with this tag", + "description": "The MapComplete theme Hydrants, Extinguishers, Fire stations, and Ambulance stations has a layer Map of fire extinguishers. showing features with this tag", "value": "fire_extinguisher" }, { "key": "location", - "description": "Layer 'Map of fire extinguishers.' shows and asks freeform values for key 'location' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')" + "description": "Layer 'Map of fire extinguishers.' shows and asks freeform values for key 'location' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')" }, { "key": "location", - "description": "Layer 'Map of fire extinguishers.' shows location=indoor with a fixed text, namely 'Found indoors.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of fire extinguishers.' shows location=indoor with a fixed text, namely 'Found indoors.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "indoor" }, { "key": "location", - "description": "Layer 'Map of fire extinguishers.' shows location=outdoor with a fixed text, namely 'Found outdoors.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of fire extinguishers.' shows location=outdoor with a fixed text, namely 'Found outdoors.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "outdoor" }, { @@ -141,57 +141,57 @@ }, { "key": "amenity", - "description": "The MapComplete theme Hydrants, Extinguishers, Fire stations, and Ambulance stations. has a layer Map of fire stations showing features with this tag", + "description": "The MapComplete theme Hydrants, Extinguishers, Fire stations, and Ambulance stations has a layer Map of fire stations showing features with this tag", "value": "fire_station" }, { "key": "name", - "description": "Layer 'Map of fire stations' shows and asks freeform values for key 'name' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')" + "description": "Layer 'Map of fire stations' shows and asks freeform values for key 'name' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')" }, { "key": "addr:street", - "description": "Layer 'Map of fire stations' shows and asks freeform values for key 'addr:street' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')" + "description": "Layer 'Map of fire stations' shows and asks freeform values for key 'addr:street' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')" }, { "key": "addr:place", - "description": "Layer 'Map of fire stations' shows and asks freeform values for key 'addr:place' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')" + "description": "Layer 'Map of fire stations' shows and asks freeform values for key 'addr:place' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')" }, { "key": "operator", - "description": "Layer 'Map of fire stations' shows and asks freeform values for key 'operator' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')" + "description": "Layer 'Map of fire stations' shows and asks freeform values for key 'operator' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')" }, { "key": "operator", - "description": "Layer 'Map of fire stations' shows operator=Bureau of Fire Protection&operator:type=government with a fixed text, namely 'Bureau of Fire Protection' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of fire stations' shows operator=Bureau of Fire Protection&operator:type=government with a fixed text, namely 'Bureau of Fire Protection' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "Bureau of Fire Protection" }, { "key": "operator:type", - "description": "Layer 'Map of fire stations' shows operator=Bureau of Fire Protection&operator:type=government with a fixed text, namely 'Bureau of Fire Protection' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of fire stations' shows operator=Bureau of Fire Protection&operator:type=government with a fixed text, namely 'Bureau of Fire Protection' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "government" }, { "key": "operator:type", - "description": "Layer 'Map of fire stations' shows and asks freeform values for key 'operator:type' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')" + "description": "Layer 'Map of fire stations' shows and asks freeform values for key 'operator:type' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')" }, { "key": "operator:type", - "description": "Layer 'Map of fire stations' shows operator:type=government with a fixed text, namely 'The station is operated by the government.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of fire stations' shows operator:type=government with a fixed text, namely 'The station is operated by the government.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "government" }, { "key": "operator:type", - "description": "Layer 'Map of fire stations' shows operator:type=community with a fixed text, namely 'The station is operated by a community-based, or informal organization.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of fire stations' shows operator:type=community with a fixed text, namely 'The station is operated by a community-based, or informal organization.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "community" }, { "key": "operator:type", - "description": "Layer 'Map of fire stations' shows operator:type=ngo with a fixed text, namely 'The station is operated by a formal group of volunteers.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of fire stations' shows operator:type=ngo with a fixed text, namely 'The station is operated by a formal group of volunteers.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "ngo" }, { "key": "operator:type", - "description": "Layer 'Map of fire stations' shows operator:type=private with a fixed text, namely 'The station is privately operated.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of fire stations' shows operator:type=private with a fixed text, namely 'The station is privately operated.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "private" }, { @@ -212,47 +212,47 @@ }, { "key": "emergency", - "description": "The MapComplete theme Hydrants, Extinguishers, Fire stations, and Ambulance stations. has a layer Map of ambulance stations showing features with this tag", + "description": "The MapComplete theme Hydrants, Extinguishers, Fire stations, and Ambulance stations has a layer Map of ambulance stations showing features with this tag", "value": "ambulance_station" }, { "key": "name", - "description": "Layer 'Map of ambulance stations' shows and asks freeform values for key 'name' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')" + "description": "Layer 'Map of ambulance stations' shows and asks freeform values for key 'name' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')" }, { "key": "addr:street", - "description": "Layer 'Map of ambulance stations' shows and asks freeform values for key 'addr:street' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')" + "description": "Layer 'Map of ambulance stations' shows and asks freeform values for key 'addr:street' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')" }, { "key": "addr:place", - "description": "Layer 'Map of ambulance stations' shows and asks freeform values for key 'addr:place' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')" + "description": "Layer 'Map of ambulance stations' shows and asks freeform values for key 'addr:place' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')" }, { "key": "operator", - "description": "Layer 'Map of ambulance stations' shows and asks freeform values for key 'operator' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')" + "description": "Layer 'Map of ambulance stations' shows and asks freeform values for key 'operator' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')" }, { "key": "operator:type", - "description": "Layer 'Map of ambulance stations' shows and asks freeform values for key 'operator:type' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')" + "description": "Layer 'Map of ambulance stations' shows and asks freeform values for key 'operator:type' (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')" }, { "key": "operator:type", - "description": "Layer 'Map of ambulance stations' shows operator:type=government with a fixed text, namely 'The station is operated by the government.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of ambulance stations' shows operator:type=government with a fixed text, namely 'The station is operated by the government.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "government" }, { "key": "operator:type", - "description": "Layer 'Map of ambulance stations' shows operator:type=community with a fixed text, namely 'The station is operated by a community-based, or informal organization.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of ambulance stations' shows operator:type=community with a fixed text, namely 'The station is operated by a community-based, or informal organization.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "community" }, { "key": "operator:type", - "description": "Layer 'Map of ambulance stations' shows operator:type=ngo with a fixed text, namely 'The station is operated by a formal group of volunteers.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of ambulance stations' shows operator:type=ngo with a fixed text, namely 'The station is operated by a formal group of volunteers.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "ngo" }, { "key": "operator:type", - "description": "Layer 'Map of ambulance stations' shows operator:type=private with a fixed text, namely 'The station is privately operated.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations.')", + "description": "Layer 'Map of ambulance stations' shows operator:type=private with a fixed text, namely 'The station is privately operated.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hydrants, Extinguishers, Fire stations, and Ambulance stations')", "value": "private" }, { diff --git a/Docs/TagInfo/mapcomplete_personal.json b/Docs/TagInfo/mapcomplete_personal.json index 8dbda3dd80..91d6a0cbd9 100644 --- a/Docs/TagInfo/mapcomplete_personal.json +++ b/Docs/TagInfo/mapcomplete_personal.json @@ -5391,22 +5391,22 @@ }, { "key": "highway", - "description": "The MapComplete theme Personal theme has a layer Pedestrain paths showing features with this tag", + "description": "The MapComplete theme Personal theme has a layer Pedestrian paths showing features with this tag", "value": "footway" }, { "key": "highway", - "description": "The MapComplete theme Personal theme has a layer Pedestrain paths showing features with this tag", + "description": "The MapComplete theme Personal theme has a layer Pedestrian paths showing features with this tag", "value": "path" }, { "key": "highway", - "description": "The MapComplete theme Personal theme has a layer Pedestrain paths showing features with this tag", + "description": "The MapComplete theme Personal theme has a layer Pedestrian paths showing features with this tag", "value": "corridor" }, { "key": "highway", - "description": "The MapComplete theme Personal theme has a layer Pedestrain paths showing features with this tag", + "description": "The MapComplete theme Personal theme has a layer Pedestrian paths showing features with this tag", "value": "steps" }, { @@ -5608,6 +5608,14 @@ "description": "Layer 'Playgrounds' shows access=private with a fixed text, namely 'Not accessible' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Personal theme')", "value": "private" }, + { + "key": "website", + "description": "Layer 'Playgrounds' shows and asks freeform values for key 'website' (in the MapComplete.osm.be theme 'Personal theme')" + }, + { + "key": "contact:website", + "description": "Layer 'Playgrounds' shows contact:website~^..*$ with a fixed text, namely '{contact:website}' (in the MapComplete.osm.be theme 'Personal theme')" + }, { "key": "email", "description": "Layer 'Playgrounds' shows and asks freeform values for key 'email' (in the MapComplete.osm.be theme 'Personal theme')" diff --git a/Docs/TagInfo/mapcomplete_playgrounds.json b/Docs/TagInfo/mapcomplete_playgrounds.json index e36d61e10b..a36e73f08c 100644 --- a/Docs/TagInfo/mapcomplete_playgrounds.json +++ b/Docs/TagInfo/mapcomplete_playgrounds.json @@ -122,6 +122,14 @@ "description": "Layer 'Playgrounds' shows access=private with a fixed text, namely 'Not accessible' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Playgrounds')", "value": "private" }, + { + "key": "website", + "description": "Layer 'Playgrounds' shows and asks freeform values for key 'website' (in the MapComplete.osm.be theme 'Playgrounds')" + }, + { + "key": "contact:website", + "description": "Layer 'Playgrounds' shows contact:website~^..*$ with a fixed text, namely '{contact:website}' (in the MapComplete.osm.be theme 'Playgrounds')" + }, { "key": "email", "description": "Layer 'Playgrounds' shows and asks freeform values for key 'email' (in the MapComplete.osm.be theme 'Playgrounds')" From 3edca23b904b76616088bf8706458a8c2ae9a942 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 3 Apr 2022 03:49:09 +0200 Subject: [PATCH 14/37] Regen docs --- Docs/BuiltinIndex.md | 2 ++ Docs/Layers/bicycle_rental.md | 28 ++++++++++++++-------------- Docs/Layers/bike_shop.md | 10 +++++----- Docs/Layers/playground.md | 18 ++++++++++++++++++ Docs/Layers/village_green.md | 2 +- Docs/SpecialRenderings.md | 24 ++++++++++++++++++------ Docs/URL_Parameters.md | 16 ++++++++++++++++ UI/i18n/Locale.ts | 21 ++++++++++----------- 8 files changed, 84 insertions(+), 37 deletions(-) diff --git a/Docs/BuiltinIndex.md b/Docs/BuiltinIndex.md index 45660d4cbc..fce8d62d3f 100644 --- a/Docs/BuiltinIndex.md +++ b/Docs/BuiltinIndex.md @@ -110,6 +110,7 @@ - food - nature_reserve - observation_tower + - playground - recycling @@ -155,6 +156,7 @@ - bicycle_library - bicycle_rental + - bike_shop - bike_themed_object - cafe_pub - food diff --git a/Docs/Layers/bicycle_rental.md b/Docs/Layers/bicycle_rental.md index a4da7fd789..a1dad60365 100644 --- a/Docs/Layers/bicycle_rental.md +++ b/Docs/Layers/bicycle_rental.md @@ -257,10 +257,10 @@ This is rendered with `{rental} is rented here` -The question is **How much [object Object] can be rented here? ** +The question is **How much city bikes can be rented here? ** This rendering asks information about the property [capacity:city_bike](https://wiki.openstreetmap.org/wiki/Key:capacity:city_bike) -This is rendered with `{capacity:city_bike} [object Object] can be rented here` +This is rendered with `{capacity:city_bike} city bikes can be rented here` @@ -278,10 +278,10 @@ _This tagrendering has no question and is thus read-only_ -The question is **How much [object Object] can be rented here? ** +The question is **How much electrical bikes can be rented here? ** This rendering asks information about the property [capacity:ebike](https://wiki.openstreetmap.org/wiki/Key:capacity:ebike) -This is rendered with `{capacity:ebike} [object Object] can be rented here` +This is rendered with `{capacity:ebike} electrical bikes can be rented here` @@ -299,10 +299,10 @@ _This tagrendering has no question and is thus read-only_ -The question is **How much [object Object] can be rented here? ** +The question is **How much bikes for children can be rented here? ** This rendering asks information about the property [capacity:kid_bike](https://wiki.openstreetmap.org/wiki/Key:capacity:kid_bike) -This is rendered with `{capacity:kid_bike} [object Object] can be rented here` +This is rendered with `{capacity:kid_bike} bikes for children can be rented here` @@ -320,10 +320,10 @@ _This tagrendering has no question and is thus read-only_ -The question is **How much [object Object] can be rented here? ** +The question is **How much BMX bikes can be rented here? ** This rendering asks information about the property [capacity:bmx](https://wiki.openstreetmap.org/wiki/Key:capacity:bmx) -This is rendered with `{capacity:bmx} [object Object] can be rented here` +This is rendered with `{capacity:bmx} BMX bikes can be rented here` @@ -341,10 +341,10 @@ _This tagrendering has no question and is thus read-only_ -The question is **How much [object Object] can be rented here? ** +The question is **How much mountainbike can be rented here? ** This rendering asks information about the property [capacity:mtb](https://wiki.openstreetmap.org/wiki/Key:capacity:mtb) -This is rendered with `{capacity:mtb} [object Object] can be rented here` +This is rendered with `{capacity:mtb} mountainbike can be rented here` @@ -362,10 +362,10 @@ _This tagrendering has no question and is thus read-only_ -The question is **How much [object Object] can be rented here? ** +The question is **How much bicycle panniers can be rented here? ** This rendering asks information about the property [capacity:bicycle_pannier](https://wiki.openstreetmap.org/wiki/Key:capacity:bicycle_pannier) -This is rendered with `{capacity:bicycle_pannier} [object Object] can be rented here` +This is rendered with `{capacity:bicycle_pannier} bicycle panniers can be rented here` @@ -383,10 +383,10 @@ _This tagrendering has no question and is thus read-only_ -The question is **How much [object Object] can be rented here? ** +The question is **How much tandem can be rented here? ** This rendering asks information about the property [capacity:tandem_bicycle](https://wiki.openstreetmap.org/wiki/Key:capacity:tandem_bicycle) -This is rendered with `{capacity:tandem_bicycle} [object Object] can be rented here` +This is rendered with `{capacity:tandem_bicycle} tandem can be rented here` diff --git a/Docs/Layers/bike_shop.md b/Docs/Layers/bike_shop.md index db81de920a..4cbae7ee15 100644 --- a/Docs/Layers/bike_shop.md +++ b/Docs/Layers/bike_shop.md @@ -24,7 +24,7 @@ A shop specifically selling bicycles or related items + [bike_shop-website](#bike_shop-website) + [bike_shop-phone](#bike_shop-phone) + [bike_shop-email](#bike_shop-email) - + [bike_shop-opening_hours](#bike_shop-opening_hours) + + [opening_hours](#opening_hours) + [description](#description) + [bike_shop-access](#bike_shop-access) + [bike_repair_sells-bikes](#bike_repair_sells-bikes) @@ -169,14 +169,14 @@ This is rendered with `{email}` -### bike_shop-opening_hours +### opening_hours -The question is **When is this shop opened?** +The question is **What are the opening hours of {title()}?** This rendering asks information about the property [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) -This is rendered with `{opening_hours_table(opening_hours)}` +This is rendered with `

Opening hours

{opening_hours_table(opening_hours)}` @@ -198,7 +198,7 @@ This is rendered with `{description}` _This tagrendering has no question and is thus read-only_ This rendering asks information about the property [access](https://wiki.openstreetmap.org/wiki/Key:access) -This is rendered with `Enkel voor {access}` +This is rendered with `Only accessible to {access}` diff --git a/Docs/Layers/playground.md b/Docs/Layers/playground.md index fe3c54bc02..d12249fbb3 100644 --- a/Docs/Layers/playground.md +++ b/Docs/Layers/playground.md @@ -25,6 +25,7 @@ Playgrounds + [playground-max_age](#playground-max_age) + [playground-operator](#playground-operator) + [playground-access](#playground-access) + + [website](#website) + [playground-email](#playground-email) + [playground-phone](#playground-phone) + [Playground-wheelchair](#playground-wheelchair) @@ -88,6 +89,7 @@ attribute | type | values which are supported by this layer [](https://taginfo.openstreetmap.org/keys/min_age#values) [min_age](https://wiki.openstreetmap.org/wiki/Key:min_age) | [pnat](../SpecialInputElements.md#pnat) | [](https://taginfo.openstreetmap.org/keys/max_age#values) [max_age](https://wiki.openstreetmap.org/wiki/Key:max_age) | [pnat](../SpecialInputElements.md#pnat) | [](https://taginfo.openstreetmap.org/keys/operator#values) [operator](https://wiki.openstreetmap.org/wiki/Key:operator) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/website#values) [website](https://wiki.openstreetmap.org/wiki/Key:website) | [url](../SpecialInputElements.md#url) | [](https://taginfo.openstreetmap.org/keys/email#values) [email](https://wiki.openstreetmap.org/wiki/Key:email) | [email](../SpecialInputElements.md#email) | [](https://taginfo.openstreetmap.org/keys/phone#values) [phone](https://wiki.openstreetmap.org/wiki/Key:phone) | [phone](../SpecialInputElements.md#phone) | [](https://taginfo.openstreetmap.org/keys/wheelchair#values) [wheelchair](https://wiki.openstreetmap.org/wiki/Key:wheelchair) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:wheelchair%3Dyes) [limited](https://wiki.openstreetmap.org/wiki/Tag:wheelchair%3Dlimited) [no](https://wiki.openstreetmap.org/wiki/Tag:wheelchair%3Dno) @@ -197,6 +199,22 @@ The question is **Is this playground accessible to the general public?** +### website + + + +The question is **What is the website of {title()}?** + +This rendering asks information about the property [website](https://wiki.openstreetmap.org/wiki/Key:website) +This is rendered with `{website}` + + + + - **{contact:website}** corresponds with contact:website~^..*$_This option cannot be chosen as answer_ + + + + ### playground-email diff --git a/Docs/Layers/village_green.md b/Docs/Layers/village_green.md index 0eadc8fbc5..626b753d6c 100644 --- a/Docs/Layers/village_green.md +++ b/Docs/Layers/village_green.md @@ -7,7 +7,7 @@ -A layer showing village-green (which are communal green areas, but not quite parks" +A layer showing village-green (which are communal green areas, but not quite parks) diff --git a/Docs/SpecialRenderings.md b/Docs/SpecialRenderings.md index 8ad63a77a7..b268df9983 100644 --- a/Docs/SpecialRenderings.md +++ b/Docs/SpecialRenderings.md @@ -5,9 +5,24 @@ +In a tagrendering, some special values are substituted by an advanced UI-element. This allows advanced features and visualizations to be reused by custom themes or even to query third-party API's. + +General usage is `{func_name()}`, `{func_name(arg, someotherarg)}` or `{func_name(args):cssStyle}`. Note that you _do not_ need to use quotes around your arguments, the comma is enough to separate them. This also implies you cannot use a comma in your args + + + +#### Using expanded syntax + + + +Instead of using `{"render": {"en": "{some_special_visualisation(some_arg, some other really long message, more args)} , "nl": "{some_special_visualisation(some_arg, een boodschap in een andere taal, more args)}}, one can also write + +{"render":{"special":{"type":"some_special_visualisation","argname":"some_arg","message":{"en":"some other really long message","nl":"een boodschap in een andere taal"},"other_arg_name":"more args"}}} + ## Table of contents 1. [Special tag renderings](#special-tag-renderings) + * [Using expanded syntax](#using-expanded-syntax) + [all_tags](#all_tags) * [Example usage of all_tags](#example-usage-of-all_tags) + [image_carousel](#image_carousel) @@ -65,10 +80,6 @@ -In a tagrendering, some special values are substituted by an advanced UI-element. This allows advanced features and visualizations to be reused by custom themes or even to query third-party API's. - -General usage is `{func_name()}`, `{func_name(arg, someotherarg)}` or `{func_name(args):cssStyle}`. Note that you _do not_ need to use quotes around your arguments, the comma is enough to separate them. This also implies you cannot use a comma in your args - ### all_tags @@ -87,7 +98,7 @@ General usage is `{func_name()}`, `{func_name(arg, someotherarg)}` or `{func_nam name | default | description ------ | --------- | ------------- -image key/prefix (multiple values allowed if comma-seperated) | image,mapillary,image,wikidata,wikimedia_commons,image,image | The keys given to the images, e.g. if image is given, the first picture URL will be added as image, the second as image:0, the third as image:1, etc... +image_key | image,mapillary,image,wikidata,wikimedia_commons,image,image | The keys given to the images, e.g. if image is given, the first picture URL will be added as image, the second as image:0, the third as image:1, etc... Multiple values are allowed if ';'-separated #### Example usage of image_carousel @@ -312,11 +323,12 @@ icon | ./assets/svg/addSmall.svg | A nice icon to show in the button snap_onto_layers | _undefined_ | If a way of the given layer(s) is closeby, will snap the new point onto this way (similar as preset might snap). To show multiple layers to snap onto, use a `;`-seperated list max_snap_distance | 5 | The maximum distance that the imported point will be moved to snap onto a way in an already existing layer (in meters). This is previewed to the contributor, similar to the 'add new point'-action of MapComplete note_id | _undefined_ | If given, this key will be read. The corresponding note on OSM will be closed, stating 'imported' +location_picker | photo | Chooses the background for the precise location picker, options are 'map', 'photo' or 'osmbasedmap' or 'none' if the precise input picker should be disabled #### Example usage of import_button - `{import_button(,,Import this data into OpenStreetMap,./assets/svg/addSmall.svg,,5,)}` + `{import_button(,,Import this data into OpenStreetMap,./assets/svg/addSmall.svg,,5,,photo)}` diff --git a/Docs/URL_Parameters.md b/Docs/URL_Parameters.md index c1eb483760..de23e49552 100644 --- a/Docs/URL_Parameters.md +++ b/Docs/URL_Parameters.md @@ -9,6 +9,8 @@ 1. [URL-parameters and URL-hash](#url-parameters-and-url-hash) - [What is a URL parameter?](#what-is-a-url-parameter) + - [language](#language) + - [fs-translation-mode](#fs-translation-mode) - [fs-userbadge](#fs-userbadge) - [fs-search](#fs-search) - [fs-background](#fs-background) @@ -60,6 +62,20 @@ Finally, the URL-hash is the part after the `#`. It is `node/1234` in this case. + language +---------- + + The language to display mapcomplete in. Will be ignored in case a logged-in-user did set their language before. If the specified language does not exist, it will default to the first language in the theme. No default value set + + + + fs-translation-mode +--------------------- + + If set, will show a translation button next to every string. The default value is _false_ + + + fs-userbadge -------------- diff --git a/UI/i18n/Locale.ts b/UI/i18n/Locale.ts index 21f9505014..9fda1d07b1 100644 --- a/UI/i18n/Locale.ts +++ b/UI/i18n/Locale.ts @@ -16,18 +16,17 @@ export default class Locale { window.setLanguage = function (language: string) { source.setData(language) } - source.syncWith( - QueryParameters.GetQueryParameter("language", undefined, "The language to display mapcomplete in. Will be ignored in case a logged-in-user did set their language before. If the specified language does not exist, it will default to the first language in the theme."), - true - ) - QueryParameters.GetBooleanQueryParameter("fs-translation-mode",false,"If set, will show the translation buttons") - .addCallbackAndRunD(tr => { - console.log("Query parameter for translation mode is", tr) - Locale.showLinkToWeblate.setData(Locale.showLinkToWeblate.data || tr); - }) - - } + source.syncWith( + QueryParameters.GetQueryParameter("language", undefined, "The language to display mapcomplete in. Will be ignored in case a logged-in-user did set their language before. If the specified language does not exist, it will default to the first language in the theme."), + true + ) + QueryParameters.GetBooleanQueryParameter("fs-translation-mode",false,"If set, will show a translation button next to every string.") + .addCallbackAndRunD(tr => { + Locale.showLinkToWeblate.setData(Locale.showLinkToWeblate.data || tr); + }) + + return source; } } From e62f71a51d66b72d3ef0b000c8da2bb1dfb1c8a9 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 3 Apr 2022 23:42:35 +0200 Subject: [PATCH 15/37] Fix rendering bug --- UI/Base/LinkToWeblate.ts | 6 ++++++ UI/BigComponents/TranslatorsPanel.ts | 1 + 2 files changed, 7 insertions(+) diff --git a/UI/Base/LinkToWeblate.ts b/UI/Base/LinkToWeblate.ts index e2914ebd68..d088658aba 100644 --- a/UI/Base/LinkToWeblate.ts +++ b/UI/Base/LinkToWeblate.ts @@ -12,6 +12,9 @@ export default class LinkToWeblate extends VariableUiElement { if(availableTranslations["*"] !== undefined){ return undefined } + if(context === undefined || context.indexOf(":") < 0){ + return undefined + } const icon = Svg.translate_svg() .SetClass("rounded-full border border-gray-400 inline-block w-4 h-4 m-1 weblate-link self-center") if(availableTranslations[ln] === undefined){ @@ -24,6 +27,9 @@ export default class LinkToWeblate extends VariableUiElement { } public static hrefToWeblate(language: string, contextKey: string): string{ + if(contextKey === undefined || contextKey.indexOf(":") < 0){ + return undefined + } const [category, ...rest] = contextKey.split(":") const key = rest.join(":") diff --git a/UI/BigComponents/TranslatorsPanel.ts b/UI/BigComponents/TranslatorsPanel.ts index 6d2c67f8a3..a036a1d546 100644 --- a/UI/BigComponents/TranslatorsPanel.ts +++ b/UI/BigComponents/TranslatorsPanel.ts @@ -40,6 +40,7 @@ class TranslatorsPanelContent extends Combine { }) const missingTranslationsFor = (ln: string) => Utils.NoNull(untranslated.get(ln) ?? []) + .filter(ctx => ctx.indexOf(":") >= 0) .map(ctx => ctx.replace(/note_import_[a-zA-Z0-9_]*/, "note_import")) .map(context => new Link(context, LinkToWeblate.hrefToWeblate(ln, context), true)) From 70e74144edfe95e4937c631cb6d8063b1ac87dbc Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Mon, 4 Apr 2022 02:18:31 +0200 Subject: [PATCH 16/37] Add translation button to inline renderings --- UI/Input/InputElementWrapper.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/UI/Input/InputElementWrapper.ts b/UI/Input/InputElementWrapper.ts index a671a00270..9006956c52 100644 --- a/UI/Input/InputElementWrapper.ts +++ b/UI/Input/InputElementWrapper.ts @@ -17,11 +17,8 @@ export default class InputElementWrapper extends InputElement { mapping.set(key, inputElement) // Bit of a hack: the SubstitutedTranslation expects a special rendering, but those are formatted '{key()}' instead of '{key}', so we substitute it first - const newTranslations = {} - for (const lang in translation.translations) { - newTranslations[lang] = translation.translations[lang].replace("{" + key + "}", "{" + key + "()}") - } - this._renderElement = new SubstitutedTranslation(new Translation(newTranslations), tags, state, mapping) + translation = translation.OnEveryLanguage((txt) => txt.replace("{" + key + "}", "{" + key + "()}")) + this._renderElement = new SubstitutedTranslation(translation, tags, state, mapping) } GetValue(): UIEventSource { From 74f00b333b73e9cd944d5b40a26e0f4af1772078 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Mon, 4 Apr 2022 04:54:06 +0200 Subject: [PATCH 17/37] Regen docs --- Docs/Schemas/AndOrTagConfigJsonJSC.ts | 68 +- Docs/Schemas/DeleteConfigJsonJSC.ts | 166 +- Docs/Schemas/ExtraLinkConfigJsonJSC.ts | 118 +- Docs/Schemas/FilterConfigJsonJSC.ts | 166 +- Docs/Schemas/LayerConfigJsonJSC.ts | 2194 ++++++------- Docs/Schemas/LayoutConfigJsonJSC.ts | 2890 ++++++++--------- Docs/Schemas/LineRenderingConfigJsonJSC.ts | 488 +-- Docs/Schemas/MoveConfigJsonJSC.ts | 154 +- Docs/Schemas/PointRenderingConfigJsonJSC.ts | 500 +-- .../QuestionableTagRenderingConfigJsonJSC.ts | 646 ++-- Docs/Schemas/RewritableConfigJsonJSC.ts | 396 +-- Docs/Schemas/TagRenderingConfigJsonJSC.ts | 246 +- Docs/Schemas/TilesourceConfigJsonJSC.ts | 1500 ++++----- Docs/Schemas/UnitConfigJsonJSC.ts | 180 +- 14 files changed, 4856 insertions(+), 4856 deletions(-) diff --git a/Docs/Schemas/AndOrTagConfigJsonJSC.ts b/Docs/Schemas/AndOrTagConfigJsonJSC.ts index 6600f85021..3da8b5b091 100644 --- a/Docs/Schemas/AndOrTagConfigJsonJSC.ts +++ b/Docs/Schemas/AndOrTagConfigJsonJSC.ts @@ -1,37 +1,37 @@ export default { - "$ref": "#/definitions/AndOrTagConfigJson", - "definitions": { - "AndOrTagConfigJson": { - "type": "object", - "properties": { - "and": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } - }, - "or": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } + "$ref": "#/definitions/AndOrTagConfigJson", + "definitions": { + "AndOrTagConfigJson": { + "type": "object", + "properties": { + "and": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "or": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + } + } } - } - } - }, - "$schema": "http://json-schema.org/draft-07/schema#" + }, + "$schema": "http://json-schema.org/draft-07/schema#" } \ No newline at end of file diff --git a/Docs/Schemas/DeleteConfigJsonJSC.ts b/Docs/Schemas/DeleteConfigJsonJSC.ts index bdc96c0c48..eb67718d7b 100644 --- a/Docs/Schemas/DeleteConfigJsonJSC.ts +++ b/Docs/Schemas/DeleteConfigJsonJSC.ts @@ -1,91 +1,91 @@ export default { - "type": "object", - "properties": { - "extraDeleteReasons": { - "description": "*\nBy default, three reasons to delete a point are shown:\n\n- The point does not exist anymore\n- The point was a testing point\n- THe point could not be found\n\nHowever, for some layers, there might be different or more specific reasons for deletion which can be user friendly to set, e.g.:\n\n- the shop has closed\n- the climbing route has been closed of for nature conservation reasons\n- ...\n\nThese reasons can be stated here and will be shown in the list of options the user can choose from", - "type": "array", - "items": { - "type": "object", - "properties": { - "explanation": { - "description": "The text that will be shown to the user - translatable" - }, - "changesetMessage": { - "description": "The text that will be uploaded into the changeset or will be used in the fixme in case of a soft deletion\nShould be a few words, in english", - "type": "string" - } + "type": "object", + "properties": { + "extraDeleteReasons": { + "description": "*\nBy default, three reasons to delete a point are shown:\n\n- The point does not exist anymore\n- The point was a testing point\n- THe point could not be found\n\nHowever, for some layers, there might be different or more specific reasons for deletion which can be user friendly to set, e.g.:\n\n- the shop has closed\n- the climbing route has been closed of for nature conservation reasons\n- ...\n\nThese reasons can be stated here and will be shown in the list of options the user can choose from", + "type": "array", + "items": { + "type": "object", + "properties": { + "explanation": { + "description": "The text that will be shown to the user - translatable" + }, + "changesetMessage": { + "description": "The text that will be uploaded into the changeset or will be used in the fixme in case of a soft deletion\nShould be a few words, in english", + "type": "string" + } + }, + "required": [ + "changesetMessage", + "explanation" + ] + } }, - "required": [ - "changesetMessage", - "explanation" - ] - } - }, - "nonDeleteMappings": { - "description": "In some cases, a (starting) contributor might wish to delete a feature even though deletion is not appropriate.\n(The most relevant case are small paths running over private property. These should be marked as 'private' instead of deleted, as the community might trace the path again from aerial imagery, gettting us back to the original situation).\n\nBy adding a 'nonDeleteMapping', an option can be added into the list which will retag the feature.\nIt is important that the feature will be retagged in such a way that it won't be picked up by the layer anymore!", - "type": "array", - "items": { - "type": "object", - "properties": { - "if": { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - "then": {} + "nonDeleteMappings": { + "description": "In some cases, a (starting) contributor might wish to delete a feature even though deletion is not appropriate.\n(The most relevant case are small paths running over private property. These should be marked as 'private' instead of deleted, as the community might trace the path again from aerial imagery, gettting us back to the original situation).\n\nBy adding a 'nonDeleteMapping', an option can be added into the list which will retag the feature.\nIt is important that the feature will be retagged in such a way that it won't be picked up by the layer anymore!", + "type": "array", + "items": { + "type": "object", + "properties": { + "if": { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + "then": {} + }, + "required": [ + "if", + "then" + ] + } }, - "required": [ - "if", - "then" - ] - } - }, - "softDeletionTags": { - "description": "In some cases, the contributor is not allowed to delete the current feature (e.g. because it isn't a point, the point is referenced by a relation or the user isn't experienced enough).\nTo still offer the user a 'delete'-option, the feature is retagged with these tags. This is a soft deletion, as the point isn't actually removed from OSM but rather marked as 'disused'\nIt is important that the feature will be retagged in such a way that it won't be picked up by the layer anymore!\n\nExample (note that \"amenity=\" erases the 'amenity'-key alltogether):\n```\n{\n \"and\": [\"disussed:amenity=public_bookcase\", \"amenity=\"]\n}\n```\n\nor (notice the use of the ':='-tag to copy the old value of 'shop=*' into 'disused:shop='):\n```\n{\n \"and\": [\"disused:shop:={shop}\", \"shop=\"]\n}\n```", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "neededChangesets": { - "description": "*\nBy default, the contributor needs 20 previous changesets to delete points edited by others.\nFor some small features (e.g. bicycle racks) this is too much and this requirement can be lowered or dropped, which can be done here.", - "type": "number" - } - }, - "definitions": { - "AndOrTagConfigJson": { - "type": "object", - "properties": { - "and": { - "type": "array", - "items": { + "softDeletionTags": { + "description": "In some cases, the contributor is not allowed to delete the current feature (e.g. because it isn't a point, the point is referenced by a relation or the user isn't experienced enough).\nTo still offer the user a 'delete'-option, the feature is retagged with these tags. This is a soft deletion, as the point isn't actually removed from OSM but rather marked as 'disused'\nIt is important that the feature will be retagged in such a way that it won't be picked up by the layer anymore!\n\nExample (note that \"amenity=\" erases the 'amenity'-key alltogether):\n```\n{\n \"and\": [\"disussed:amenity=public_bookcase\", \"amenity=\"]\n}\n```\n\nor (notice the use of the ':='-tag to copy the old value of 'shop=*' into 'disused:shop='):\n```\n{\n \"and\": [\"disused:shop:={shop}\", \"shop=\"]\n}\n```", "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } ] - } }, - "or": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } + "neededChangesets": { + "description": "*\nBy default, the contributor needs 20 previous changesets to delete points edited by others.\nFor some small features (e.g. bicycle racks) this is too much and this requirement can be lowered or dropped, which can be done here.", + "type": "number" } - } - } - }, - "$schema": "http://json-schema.org/draft-07/schema#" + }, + "definitions": { + "AndOrTagConfigJson": { + "type": "object", + "properties": { + "and": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "or": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + } + } + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" } \ No newline at end of file diff --git a/Docs/Schemas/ExtraLinkConfigJsonJSC.ts b/Docs/Schemas/ExtraLinkConfigJsonJSC.ts index b3175e1c4a..1c751bf9ad 100644 --- a/Docs/Schemas/ExtraLinkConfigJsonJSC.ts +++ b/Docs/Schemas/ExtraLinkConfigJsonJSC.ts @@ -1,64 +1,64 @@ export default { - "type": "object", - "properties": { - "icon": { - "type": "string" - }, - "text": {}, - "href": { - "type": "string" - }, - "newTab": { - "type": "boolean" - }, - "requirements": { - "type": "array", - "items": { - "enum": [ - "iframe", - "no-iframe", - "no-welcome-message", - "welcome-message" - ], - "type": "string" - } - } - }, - "required": [ - "href" - ], - "definitions": { - "AndOrTagConfigJson": { - "type": "object", - "properties": { - "and": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } + "type": "object", + "properties": { + "icon": { + "type": "string" }, - "or": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { + "text": {}, + "href": { + "type": "string" + }, + "newTab": { + "type": "boolean" + }, + "requirements": { + "type": "array", + "items": { + "enum": [ + "iframe", + "no-iframe", + "no-welcome-message", + "welcome-message" + ], "type": "string" - } - ] - } + } } - } - } - }, - "$schema": "http://json-schema.org/draft-07/schema#" + }, + "required": [ + "href" + ], + "definitions": { + "AndOrTagConfigJson": { + "type": "object", + "properties": { + "and": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "or": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + } + } + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" } \ No newline at end of file diff --git a/Docs/Schemas/FilterConfigJsonJSC.ts b/Docs/Schemas/FilterConfigJsonJSC.ts index fc54409ec8..d8c787f83f 100644 --- a/Docs/Schemas/FilterConfigJsonJSC.ts +++ b/Docs/Schemas/FilterConfigJsonJSC.ts @@ -1,90 +1,90 @@ export default { - "type": "object", - "properties": { - "id": { - "description": "An id/name for this filter, used to set the URL parameters", - "type": "string" - }, - "options": { - "description": "The options for a filter\nIf there are multiple options these will be a list of radio buttons\nIf there is only one option this will be a checkbox\nFiltering is done based on the given osmTags that are compared to the objects in that layer.", - "type": "array", - "items": { - "type": "object", - "properties": { - "question": {}, - "osmTags": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "default": { - "type": "boolean" - }, - "fields": { + "type": "object", + "properties": { + "id": { + "description": "An id/name for this filter, used to set the URL parameters", + "type": "string" + }, + "options": { + "description": "The options for a filter\nIf there are multiple options these will be a list of radio buttons\nIf there is only one option this will be a checkbox\nFiltering is done based on the given osmTags that are compared to the objects in that layer.", "type": "array", "items": { - "type": "object", - "properties": { - "name": { - "type": "string" + "type": "object", + "properties": { + "question": {}, + "osmTags": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "default": { + "type": "boolean" + }, + "fields": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "name" + ] + } + } }, - "type": { - "type": "string" - } - }, - "required": [ - "name" - ] + "required": [ + "question" + ] } - } - }, - "required": [ - "question" - ] - } - } - }, - "required": [ - "id", - "options" - ], - "definitions": { - "AndOrTagConfigJson": { - "type": "object", - "properties": { - "and": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } - }, - "or": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } } - } - } - }, - "$schema": "http://json-schema.org/draft-07/schema#" + }, + "required": [ + "id", + "options" + ], + "definitions": { + "AndOrTagConfigJson": { + "type": "object", + "properties": { + "and": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "or": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + } + } + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" } \ No newline at end of file diff --git a/Docs/Schemas/LayerConfigJsonJSC.ts b/Docs/Schemas/LayerConfigJsonJSC.ts index 86bccc5dbf..1153ffb2d3 100644 --- a/Docs/Schemas/LayerConfigJsonJSC.ts +++ b/Docs/Schemas/LayerConfigJsonJSC.ts @@ -1,1125 +1,1125 @@ export default { - "description": "Configuration for a single layer", - "type": "object", - "properties": { - "id": { - "description": "The id of this layer.\nThis should be a simple, lowercase, human readable string that is used to identify the layer.", - "type": "string" - }, - "name": { - "description": "The name of this layer\nUsed in the layer control panel and the 'Personal theme'.\n\nIf not given, will be hidden (and thus not toggable) in the layer control" - }, - "description": { - "description": "A description for this layer.\nShown in the layer selections and in the personel theme" - }, - "source": { - "description": "This determines where the data for the layer is fetched: from OSM or from an external geojson dataset.\n\nIf no 'geojson' is defined, data will be fetched from overpass and the OSM-API.\n\nEvery source _must_ define which tags _must_ be present in order to be picked up.", - "anyOf": [ - { - "allOf": [ - { - "type": "object", - "properties": { - "osmTags": { - "description": "Every source must set which tags have to be present in order to load the given layer.", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "maxCacheAge": { - "description": "The maximum amount of seconds that a tile is allowed to linger in the cache", - "type": "number" - } - }, - "required": [ - "osmTags" - ] - }, - { - "type": "object", - "properties": { - "overpassScript": { - "type": "string" - } - } - } - ] - }, - { - "allOf": [ - { - "type": "object", - "properties": { - "osmTags": { - "description": "Every source must set which tags have to be present in order to load the given layer.", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "maxCacheAge": { - "description": "The maximum amount of seconds that a tile is allowed to linger in the cache", - "type": "number" - } - }, - "required": [ - "osmTags" - ] - }, - { - "type": "object", - "properties": { - "geoJson": { - "description": "The actual source of the data to load, if loaded via geojson.\n\n# A single geojson-file\nsource: {geoJson: \"https://my.source.net/some-geo-data.geojson\"}\n fetches a geojson from a third party source\n\n# A tiled geojson source\nsource: {geoJson: \"https://my.source.net/some-tile-geojson-{layer}-{z}-{x}-{y}.geojson\", geoJsonZoomLevel: 14}\n to use a tiled geojson source. The web server must offer multiple geojsons. {z}, {x} and {y} are substituted by the location; {layer} is substituted with the id of the loaded layer\n\nSome API's use a BBOX instead of a tile, this can be used by specifying {y_min}, {y_max}, {x_min} and {x_max}", - "type": "string" - }, - "geoJsonZoomLevel": { - "description": "To load a tiled geojson layer, set the zoomlevel of the tiles", - "type": "number" - }, - "isOsmCache": { - "description": "Indicates that the upstream geojson data is OSM-derived.\nUseful for e.g. merging or for scripts generating this cache", - "type": "boolean" - }, - "mercatorCrs": { - "description": "Some API's use a mercator-projection (EPSG:900913) instead of WGS84. Set the flag `mercatorCrs: true` in the source for this", - "type": "boolean" - }, - "idKey": { - "description": "Some API's have an id-field, but give it a different name.\nSetting this key will rename this field into 'id'", - "type": "string" - } - }, - "required": [ - "geoJson" - ] - } - ] - } - ] - }, - "calculatedTags": { - "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\n \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\n\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\n\nIf a tag has to be evaluated strictly, use ':=' instead:\n\n[\n\"_some_key:=some_javascript_expression\"\n]", - "type": "array", - "items": { - "type": "string" - } - }, - "doNotDownload": { - "description": "If set, this layer will not query overpass; but it'll still match the tags above which are by chance returned by other layers.\nWorks well together with 'passAllFeatures', to add decoration", - "type": "boolean" - }, - "isShown": { - "description": "This tag rendering should either be 'yes' or 'no'. If 'no' is returned, then the feature will be hidden from view.\nThis is useful to hide certain features from view.\n\nImportant: hiding features does not work dynamically, but is only calculated when the data is first renders.\nThis implies that it is not possible to hide a feature after a tagging change\n\nThe default value is 'yes'", - "$ref": "#/definitions/TagRenderingConfigJson" - }, - "forceLoad": { - "description": "Advanced option - might be set by the theme compiler\n\nIf true, this data will _always_ be loaded, even if the theme is disabled", - "type": "boolean" - }, - "minzoom": { - "description": "The minimum needed zoomlevel required before loading of the data start\nDefault: 0", - "type": "number" - }, - "shownByDefault": { - "description": "Indicates if this layer is shown by default;\ncan be used to hide a layer from start, or to load the layer but only to show it where appropriate (e.g. for snapping to it)", - "type": "boolean" - }, - "minzoomVisible": { - "description": "The zoom level at which point the data is hidden again\nDefault: 100 (thus: always visible", - "type": "number" - }, - "title": { - "description": "The title shown in a popup for elements of this layer.", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "titleIcons": { - "description": "Small icons shown next to the title.\nIf not specified, the OsmLink and wikipedia links will be used by default.\nUse an empty array to hide them.\nNote that \"defaults\" will insert all the default titleIcons (which are added automatically)\n\nType: icon[]", - "anyOf": [ - { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - } - }, - { - "type": "array", - "items": [ - { - "type": "string", - "enum": [ - "defaults" - ] - } - ], - "minItems": 1, - "maxItems": 1 - } - ] - }, - "mapRendering": { - "description": "Visualisation of the items on the map", - "anyOf": [ - { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/default_4" - }, - { - "$ref": "#/definitions/default_5" - } - ] - } - }, - { - "type": "null" - } - ] - }, - "passAllFeatures": { - "description": "If set, this layer will pass all the features it receives onto the next layer.\nThis is ideal for decoration, e.g. directionss on cameras", - "type": "boolean" - }, - "presets": { - "description": "Presets for this layer.\nA preset shows up when clicking the map on a without data (or when right-clicking/long-pressing);\nit will prompt the user to add a new point.\n\nThe most important aspect are the tags, which define which tags the new point will have;\nThe title is shown in the dialog, along with the first sentence of the description.\n\nUpon confirmation, the full description is shown beneath the buttons - perfect to add pictures and examples.\n\nNote: the icon of the preset is determined automatically based on the tags and the icon above. Don't worry about that!\nNB: if no presets are defined, the popup to add new points doesn't show up at all", - "type": "array", - "items": { - "type": "object", - "properties": { - "title": { - "description": "The title - shown on the 'add-new'-button." - }, - "tags": { - "description": "The tags to add. It determines the icon too", - "type": "array", - "items": { - "type": "string" - } - }, - "description": { - "description": "The _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)" - }, - "exampleImages": { - "description": "Example images, which show real-life pictures of what such a feature might look like\n\nType: image", - "type": "array", - "items": { - "type": "string" - } - }, - "preciseInput": { - "description": "If set, the user will prompted to confirm the location before actually adding the data.\nThis will be with a 'drag crosshair'-method.\n\nIf 'preferredBackgroundCategory' is set, the element will attempt to pick a background layer of that category.", - "anyOf": [ - { - "type": "object", - "properties": { - "preferredBackground": { - "description": "The type of background picture", - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "string" - } - ] - }, - "snapToLayer": { - "description": "If specified, these layers will be shown to and the new point will be snapped towards it", - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "string" - } - ] - }, - "maxSnapDistance": { - "description": "If specified, a new point will only be snapped if it is within this range.\nDistance in meter\n\nDefault: 10", - "type": "number" - } - }, - "required": [ - "preferredBackground" - ] - }, - { - "enum": [ - true - ], - "type": "boolean" - } - ] - } - }, - "required": [ - "tags", - "title" - ] - } - }, - "tagRenderings": { - "description": "All the tag renderings.\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together", - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/QuestionableTagRenderingConfigJson" - }, - { - "type": "object", - "properties": { - "builtin": { - "type": "string" - }, - "override": {} - }, - "required": [ - "builtin", - "override" - ] - }, - { - "$ref": "#/definitions/default<(string|QuestionableTagRenderingConfigJson|{builtin:string;override:any;})[]>" - }, - { - "type": "string" - } - ] - } - }, - "filter": { - "description": "All the extra questions for filtering", - "anyOf": [ - { - "type": "array", - "items": { - "$ref": "#/definitions/default_1" - } - }, - { - "type": "object", - "properties": { - "sameAs": { - "type": "string" - } - }, - "required": [ - "sameAs" - ] - } - ] - }, - "deletion": { - "description": "This block defines under what circumstances the delete dialog is shown for objects of this layer.\nIf set, a dialog is shown to the user to (soft) delete the point.\nThe dialog is built to be user friendly and to prevent mistakes.\nIf deletion is not possible, the dialog will hide itself and show the reason of non-deletability instead.\n\nTo configure, the following values are possible:\n\n- false: never ever show the delete button\n- true: show the default delete button\n- undefined: use the mapcomplete default to show deletion or not. Currently, this is the same as 'false' but this will change in the future\n- or: a hash with options (see below)\n\n The delete dialog\n =================\n\n\n\n#### Hard deletion if enough experience\n\nA feature can only be deleted from OpenStreetMap by mapcomplete if:\n\n- It is a node\n- No ways or relations use the node\n- The logged-in user has enough experience OR the user is the only one to have edited the point previously\n- The logged-in user has no unread messages (or has a ton of experience)\n- The user did not select one of the 'non-delete-options' (see below)\n\nIn all other cases, a 'soft deletion' is used.\n\n#### Soft deletion\n\nA 'soft deletion' is when the point isn't deleted from OSM but retagged so that it'll won't how up in the mapcomplete theme anymore.\nThis makes it look like it was deleted, without doing damage. A fixme will be added to the point.\n\nNote that a soft deletion is _only_ possible if these tags are provided by the theme creator, as they'll be different for every theme\n\n#### No-delete options\n\nIn some cases, the contributor might want to delete something for the wrong reason (e.g. someone who wants to have a path removed \"because the path is on their private property\").\nHowever, the path exists in reality and should thus be on OSM - otherwise the next contributor will pass by and notice \"hey, there is a path missing here! Let me redraw it in OSM!)\n\nThe correct approach is to retag the feature in such a way that it is semantically correct *and* that it doesn't show up on the theme anymore.\nA no-delete option is offered as 'reason to delete it', but secretly retags.", - "anyOf": [ - { - "$ref": "#/definitions/DeleteConfigJson" - }, - { - "type": "boolean" - } - ] - }, - "allowMove": { - "description": "Indicates if a point can be moved and configures the modalities.\n\nA feature can be moved by MapComplete if:\n\n- It is a point\n- The point is _not_ part of a way or a a relation.\n\nOff by default. Can be enabled by setting this flag or by configuring.", - "anyOf": [ - { - "$ref": "#/definitions/default_3" - }, - { - "type": "boolean" - } - ] - }, - "allowSplit": { - "description": "IF set, a 'split this road' button is shown", - "type": "boolean" - }, - "units": { - "description": "In some cases, a value is represented in a certain unit (such as meters for heigt/distance/..., km/h for speed, ...)\n\nSometimes, multiple denominations are possible (e.g. km/h vs mile/h; megawatt vs kilowatt vs gigawatt for power generators, ...)\n\nThis brings in some troubles, as there are multiple ways to write it (no denomitation, 'm' vs 'meter' 'metre', ...)\n\nNot only do we want to write consistent data to OSM, we also want to present this consistently to the user.\nThis is handled by defining units.\n\n# Rendering\n\nTo render a value with long (human) denomination, use {canonical(key)}\n\n# Usage\n\nFirst of all, you define which keys have units applied, for example:\n\n```\nunits: [\n appliesTo: [\"maxspeed\", \"maxspeed:hgv\", \"maxspeed:bus\"]\n applicableUnits: [\n ...\n ]\n]\n```\n\nApplicableUnits defines which is the canonical extension, how it is presented to the user, ...:\n\n```\napplicableUnits: [\n{\n canonicalDenomination: \"km/h\",\n alternativeDenomination: [\"km/u\", \"kmh\", \"kph\"]\n default: true,\n human: {\n en: \"kilometer/hour\",\n nl: \"kilometer/uur\"\n },\n humanShort: {\n en: \"km/h\",\n nl: \"km/u\"\n }\n},\n{\n canoncialDenomination: \"mph\",\n ... similar for miles an hour ...\n}\n]\n```\n\n\nIf this is defined, then every key which the denominations apply to (`maxspeed`, `maxspeed:hgv` and `maxspeed:bus`) will be rewritten at the metatagging stage:\nevery value will be parsed and the canonical extension will be added add presented to the other parts of the code.\n\nAlso, if a freeform text field is used, an extra dropdown with applicable denominations will be given", - "type": "array", - "items": { - "$ref": "#/definitions/default_2" - } - }, - "syncSelection": { - "description": "If set, synchronizes wether or not this layer is selected.\n\nno: Do not sync at all, always revert to default\nlocal: keep selection on local storage\ntheme-only: sync via OSM, but this layer will only be toggled in this theme\nglobal: all layers with this ID will be synced accross all themes", - "enum": [ - "global", - "local", - "no", - "theme-only" - ], - "type": "string" - } - }, - "required": [ - "id", - "mapRendering", - "source" - ], - "definitions": { - "AndOrTagConfigJson": { - "type": "object", - "properties": { - "and": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } - }, - "or": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } - } - } - }, - "ApplicableUnitJson": { - "type": "object", - "properties": { - "canonicalDenomination": { - "description": "The canonical value which will be added to the text.\ne.g. \"m\" for meters\nIf the user inputs '42', the canonical value will be added and it'll become '42m'", - "type": "string" - }, - "canonicalDenominationSingular": { - "description": "The canonical denomination in the case that the unit is precisely '1'", - "type": "string" - }, - "alternativeDenomination": { - "description": "A list of alternative values which can occur in the OSM database - used for parsing.", - "type": "array", - "items": { - "type": "string" - } - }, - "human": { - "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"meter\",\n \"fr\": \"metre\"\n}" - }, - "humanSingular": { - "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"minute\",\n \"nl\": \"minuut\"x²\n}" - }, - "prefix": { - "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", - "type": "boolean" - }, - "default": { - "description": "The default interpretation - only one can be set.\nIf none is set, the first unit will be considered the default interpretation of a value without a unit", - "type": "boolean" - } - }, - "required": [ - "canonicalDenomination" - ] - }, - "TagRenderingConfigJson": { - "description": "A TagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nFor an _editable_ tagRenerdering, use 'QuestionableTagRenderingConfigJson' instead, which extends this one", - "type": "object", - "properties": { + "description": "Configuration for a single layer", + "type": "object", + "properties": { "id": { - "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", - "type": "string" - }, - "group": { - "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", - "type": "string" - }, - "labels": { - "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", - "type": "array", - "items": { + "description": "The id of this layer.\nThis should be a simple, lowercase, human readable string that is used to identify the layer.", "type": "string" - } }, - "render": { - "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" + "name": { + "description": "The name of this layer\nUsed in the layer control panel and the 'Personal theme'.\n\nIf not given, will be hidden (and thus not toggable) in the layer control" }, - "condition": { - "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] + "description": { + "description": "A description for this layer.\nShown in the layer selections and in the personel theme" }, - "freeform": { - "description": "Allow freeform text input from the user", - "type": "object", - "properties": { - "key": { - "description": "If this key is present, then 'render' is used to display the value.\nIf this is undefined, the rendering is _always_ shown", - "type": "string" - } - }, - "required": [ - "key" - ] - }, - "mappings": { - "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", - "type": "array", - "items": { - "type": "object", - "properties": { - "if": { - "description": "If this condition is met, then the text under `then` will be shown.\nIf no value matches, and the user selects this mapping as an option, then these tags will be uploaded to OSM.\n\nFor example: {'if': 'diet:vegetarion=yes', 'then':'A vegetarian option is offered here'}\n\nThis can be an substituting-tag as well, e.g. {'if': 'addr:street:={_calculated_nearby_streetname}', 'then': '{_calculated_nearby_streetname}'}", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "then": { - "description": "If the condition `if` is met, the text `then` will be rendered.\nIf not known yet, the user will be presented with `then` as an option\nType: rendered" - }, - "icon": { - "description": "An icon supporting this mapping; typically shown pretty small\nType: icon", - "anyOf": [ - { - "type": "object", - "properties": { - "path": { - "description": "The path to the icon\nType: icon", - "type": "string" - }, - "class": { - "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", - "type": "string" - } - }, - "required": [ - "class", - "path" + "source": { + "description": "This determines where the data for the layer is fetched: from OSM or from an external geojson dataset.\n\nIf no 'geojson' is defined, data will be fetched from overpass and the OSM-API.\n\nEvery source _must_ define which tags _must_ be present in order to be picked up.", + "anyOf": [ + { + "allOf": [ + { + "type": "object", + "properties": { + "osmTags": { + "description": "Every source must set which tags have to be present in order to load the given layer.", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "maxCacheAge": { + "description": "The maximum amount of seconds that a tile is allowed to linger in the cache", + "type": "number" + } + }, + "required": [ + "osmTags" + ] + }, + { + "type": "object", + "properties": { + "overpassScript": { + "type": "string" + } + } + } ] - }, - { - "type": "string" - } - ] - } - }, - "required": [ - "if", - "then" + }, + { + "allOf": [ + { + "type": "object", + "properties": { + "osmTags": { + "description": "Every source must set which tags have to be present in order to load the given layer.", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "maxCacheAge": { + "description": "The maximum amount of seconds that a tile is allowed to linger in the cache", + "type": "number" + } + }, + "required": [ + "osmTags" + ] + }, + { + "type": "object", + "properties": { + "geoJson": { + "description": "The actual source of the data to load, if loaded via geojson.\n\n# A single geojson-file\nsource: {geoJson: \"https://my.source.net/some-geo-data.geojson\"}\n fetches a geojson from a third party source\n\n# A tiled geojson source\nsource: {geoJson: \"https://my.source.net/some-tile-geojson-{layer}-{z}-{x}-{y}.geojson\", geoJsonZoomLevel: 14}\n to use a tiled geojson source. The web server must offer multiple geojsons. {z}, {x} and {y} are substituted by the location; {layer} is substituted with the id of the loaded layer\n\nSome API's use a BBOX instead of a tile, this can be used by specifying {y_min}, {y_max}, {x_min} and {x_max}", + "type": "string" + }, + "geoJsonZoomLevel": { + "description": "To load a tiled geojson layer, set the zoomlevel of the tiles", + "type": "number" + }, + "isOsmCache": { + "description": "Indicates that the upstream geojson data is OSM-derived.\nUseful for e.g. merging or for scripts generating this cache", + "type": "boolean" + }, + "mercatorCrs": { + "description": "Some API's use a mercator-projection (EPSG:900913) instead of WGS84. Set the flag `mercatorCrs: true` in the source for this", + "type": "boolean" + }, + "idKey": { + "description": "Some API's have an id-field, but give it a different name.\nSetting this key will rename this field into 'id'", + "type": "string" + } + }, + "required": [ + "geoJson" + ] + } + ] + } ] - } - } - } - }, - "T": { - "type": "object" - }, - "default_4": { - "description": "The PointRenderingConfig gives all details onto how to render a single point of a feature.\n\nThis can be used if:\n\n- The feature is a point\n- To render something at the centroid of an area, or at the start, end or projected centroid of a way", - "type": "object", - "properties": { - "location": { - "description": "All the locations that this point should be rendered at.\nUsing `location: [\"point\", \"centroid\"] will always render centerpoint", - "type": "array", - "items": { - "type": "string" - } }, - "icon": { - "description": "The icon for an element.\nNote that this also doubles as the icon for this layer (rendered with the overpass-tags) ánd the icon in the presets.\n\nThe result of the icon is rendered as follows:\nthe resulting string is interpreted as a _list_ of items, separated by \";\". The bottommost layer is the first layer.\nAs a result, on could use a generic pin, then overlay it with a specific icon.\nTo make things even more practical, one can use all SVG's from the folder \"assets/svg\" and _substitute the color_ in it.\nE.g. to draw a red pin, use \"pin:#f00\", to have a green circle with your icon on top, use `circle:#0f0;`\n\nType: icon", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" + "calculatedTags": { + "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\n \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\n\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\n\nIf a tag has to be evaluated strictly, use ':=' instead:\n\n[\n\"_some_key:=some_javascript_expression\"\n]", + "type": "array", + "items": { + "type": "string" } - ] }, - "iconBadges": { - "description": "A list of extra badges to show next to the icon as small badge\nThey will be added as a 25% height icon at the bottom right of the icon, with all the badges in a flex layout.\n\nNote: strings are interpreted as icons, so layering and substituting is supported. You can use `circle:white;./my_icon.svg` to add a background circle", - "type": "array", - "items": { - "type": "object", - "properties": { - "if": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "then": { - "description": "Badge to show\nType: icon", - "anyOf": [ - { + "doNotDownload": { + "description": "If set, this layer will not query overpass; but it'll still match the tags above which are by chance returned by other layers.\nWorks well together with 'passAllFeatures', to add decoration", + "type": "boolean" + }, + "isShown": { + "description": "This tag rendering should either be 'yes' or 'no'. If 'no' is returned, then the feature will be hidden from view.\nThis is useful to hide certain features from view.\n\nImportant: hiding features does not work dynamically, but is only calculated when the data is first renders.\nThis implies that it is not possible to hide a feature after a tagging change\n\nThe default value is 'yes'", + "$ref": "#/definitions/TagRenderingConfigJson" + }, + "forceLoad": { + "description": "Advanced option - might be set by the theme compiler\n\nIf true, this data will _always_ be loaded, even if the theme is disabled", + "type": "boolean" + }, + "minzoom": { + "description": "The minimum needed zoomlevel required before loading of the data start\nDefault: 0", + "type": "number" + }, + "shownByDefault": { + "description": "Indicates if this layer is shown by default;\ncan be used to hide a layer from start, or to load the layer but only to show it where appropriate (e.g. for snapping to it)", + "type": "boolean" + }, + "minzoomVisible": { + "description": "The zoom level at which point the data is hidden again\nDefault: 100 (thus: always visible", + "type": "number" + }, + "title": { + "description": "The title shown in a popup for elements of this layer.", + "anyOf": [ + { "$ref": "#/definitions/TagRenderingConfigJson" - }, - { + }, + { "type": "string" - } - ] - } - }, - "required": [ - "if", - "then" - ] - } - }, - "iconSize": { - "description": "A string containing \"width,height\" or \"width,height,anchorpoint\" where anchorpoint is any of 'center', 'top', 'bottom', 'left', 'right', 'bottomleft','topright', ...\nDefault is '40,40,center'", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "rotation": { - "description": "The rotation of an icon, useful for e.g. directions.\nUsage: as if it were a css property for 'rotate', thus has to end with 'deg', e.g. `90deg`, `{direction}deg`, `calc(90deg - {camera:direction}deg)``", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "label": { - "description": "A HTML-fragment that is shown below the icon, for example:\n
{name}
\n\nIf the icon is undefined, then the label is shown in the center of the feature.\nNote that, if the wayhandling hides the icon then no label is shown as well.", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - } - }, - "required": [ - "location" - ] - }, - "default_5": { - "description": "The LineRenderingConfig gives all details onto how to render a single line of a feature.\n\nThis can be used if:\n\n- The feature is a line\n- The feature is an area", - "type": "object", - "properties": { - "color": { - "description": "The color for way-elements and SVG-elements.\nIf the value starts with \"--\", the style of the body element will be queried for the corresponding variable instead", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "width": { - "description": "The stroke-width for way-elements", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": [ - "string", - "number" - ] - } - ] - }, - "dashArray": { - "description": "A dasharray, e.g. \"5 6\"\nThe dasharray defines 'pixels of line, pixels of gap, pixels of line, pixels of gap',\nDefault value: \"\" (empty string == full line)", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "lineCap": { - "description": "The form at the end of a line", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "fill": { - "description": "Wehter or not to fill polygons", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "enum": [ - "no", - "yes" - ], - "type": "string" - } - ] - }, - "fillColor": { - "description": "The color to fill a polygon with.\nIf undefined, this will be slightly more opaque version of the stroke line", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "offset": { - "description": "The number of pixels this line should be moved.\nUse a positive numbe to move to the right, a negative to move to the left (left/right as defined by the drawing direction of the line).\n\nIMPORTANT: MapComplete will already normalize 'key:both:property' and 'key:both' into the corresponding 'key:left' and 'key:right' tagging (same for 'sidewalk=left/right/both' which is rewritten to 'sidewalk:left' and 'sidewalk:right')\nThis simplifies programming. Refer to the CalculatedTags.md-documentation for more details", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "number" - } - ] - } - } - }, - "QuestionableTagRenderingConfigJson": { - "description": "A QuestionableTagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nIf the desired tags are missing and a question is defined, a question will be shown instead.", - "type": "object", - "properties": { - "question": { - "description": "If it turns out that this tagRendering doesn't match _any_ value, then we show this question.\nIf undefined, the question is never asked and this tagrendering is read-only" - }, - "freeform": { - "description": "Allow freeform text input from the user", - "type": "object", - "properties": { - "key": { - "type": "string" - }, - "type": { - "description": "The type of the text-field, e.g. 'string', 'nat', 'float', 'date',...\nSee Docs/SpecialInputElements.md and UI/Input/ValidatedTextField.ts for supported values", - "type": "string" - }, - "placeholder": { - "description": "A (translated) text that is shown (as gray text) within the textfield" - }, - "helperArgs": { - "description": "Extra parameters to initialize the input helper arguments.\nFor semantics, see the 'SpecialInputElements.md'", - "type": "array", - "items": {} - }, - "addExtraTags": { - "description": "If a value is added with the textfield, these extra tag is addded.\nUseful to add a 'fixme=freeform textfield used - to be checked'", - "type": "array", - "items": { - "type": "string" - } - }, - "inline": { - "description": "When set, influences the way a question is asked.\nInstead of showing a full-widht text field, the text field will be shown within the rendering of the question.\n\nThis combines badly with special input elements, as it'll distort the layout.", - "type": "boolean" - }, - "default": { - "description": "default value to enter if no previous tagging is present.\nNormally undefined (aka do not enter anything)", - "type": "string" - } - }, - "required": [ - "key" - ] - }, - "multiAnswer": { - "description": "If true, use checkboxes instead of radio buttons when asking the question", - "type": "boolean" - }, - "mappings": { - "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", - "type": "array", - "items": { - "type": "object", - "properties": { - "if": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "then": { - "description": "Shown if the 'if is fulfilled\nType: rendered" - }, - "icon": { - "description": "An extra icon supporting the choice\nType: icon", - "anyOf": [ - { - "type": "object", - "properties": { - "path": { - "description": "The path to the icon\nType: icon", - "type": "string" - }, - "class": { - "description": "Size of the image", - "type": "string" - } - }, - "required": [ - "class", - "path" - ] - }, - { - "type": "string" - } - ] - }, - "hideInAnswer": { - "description": "In some cases, multiple taggings exist (e.g. a default assumption, or a commonly mapped abbreviation and a fully written variation).\n\nIn the latter case, a correct text should be shown, but only a single, canonical tagging should be selectable by the user.\nIn this case, one of the mappings can be hiden by setting this flag.\n\nTo demonstrate an example making a default assumption:\n\nmappings: [\n {\n if: \"access=\", -- no access tag present, we assume accessible\n then: \"Accessible to the general public\",\n hideInAnswer: true\n },\n {\n if: \"access=yes\",\n then: \"Accessible to the general public\", -- the user selected this, we add that to OSM\n },\n {\n if: \"access=no\",\n then: \"Not accessible to the public\"\n }\n]\n\n\nFor example, for an operator, we have `operator=Agentschap Natuur en Bos`, which is often abbreviated to `operator=ANB`.\nThen, we would add two mappings:\n{\n if: \"operator=Agentschap Natuur en Bos\" -- the non-abbreviated version which should be uploaded\n then: \"Maintained by Agentschap Natuur en Bos\"\n},\n{\n if: \"operator=ANB\", -- we don't want to upload abbreviations\n then: \"Maintained by Agentschap Natuur en Bos\"\n hideInAnswer: true\n}\n\nHide in answer can also be a tagsfilter, e.g. to make sure an option is only shown when appropriate.\nKeep in mind that this is reverse logic: it will be hidden in the answer if the condition is true, it will thus only show in the case of a mismatch\n\ne.g., for toilets: if \"wheelchair=no\", we know there is no wheelchair dedicated room.\nFor the location of the changing table, the option \"in the wheelchair accessible toilet is weird\", so we write:\n\n{\n \"question\": \"Where is the changing table located?\"\n \"mappings\": [\n {\"if\":\"changing_table:location=female\",\"then\":\"In the female restroom\"},\n {\"if\":\"changing_table:location=male\",\"then\":\"In the male restroom\"},\n {\"if\":\"changing_table:location=wheelchair\",\"then\":\"In the wheelchair accessible restroom\", \"hideInAnswer\": \"wheelchair=no\"},\n \n ]\n}\n\nAlso have a look for the meta-tags\n{\n if: \"operator=Agentschap Natuur en Bos\",\n then: \"Maintained by Agentschap Natuur en Bos\",\n hideInAnswer: \"_country!=be\"\n}", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": [ - "string", - "boolean" - ] - } - ] - }, - "ifnot": { - "description": "Only applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "addExtraTags": { - "description": "If chosen as answer, these tags will be applied as well onto the object.\nNot compatible with multiAnswer", - "type": "array", - "items": { - "type": "string" } - } - }, - "required": [ - "if", - "then" ] - } }, - "id": { - "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", - "type": "string" - }, - "group": { - "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", - "type": "string" - }, - "labels": { - "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", - "type": "array", - "items": { - "type": "string" - } - }, - "render": { - "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" - }, - "condition": { - "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } - } - }, - "default<(string|QuestionableTagRenderingConfigJson|{builtin:string;override:any;})[]>": { - "type": "object", - "properties": { - "rewrite": { - "type": "object", - "properties": { - "sourceString": { - "type": "array", - "items": { - "type": "string" - } - }, - "into": { - "type": "array", - "items": { - "type": "array", - "items": {} - } - } - }, - "required": [ - "into", - "sourceString" - ] - }, - "renderings": { - "type": "array", - "items": { + "titleIcons": { + "description": "Small icons shown next to the title.\nIf not specified, the OsmLink and wikipedia links will be used by default.\nUse an empty array to hide them.\nNote that \"defaults\" will insert all the default titleIcons (which are added automatically)\n\nType: icon[]", "anyOf": [ - { - "$ref": "#/definitions/QuestionableTagRenderingConfigJson" - }, - { + { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + } + }, + { + "type": "array", + "items": [ + { + "type": "string", + "enum": [ + "defaults" + ] + } + ], + "minItems": 1, + "maxItems": 1 + } + ] + }, + "mapRendering": { + "description": "Visualisation of the items on the map", + "anyOf": [ + { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/default_4" + }, + { + "$ref": "#/definitions/default_5" + } + ] + } + }, + { + "type": "null" + } + ] + }, + "passAllFeatures": { + "description": "If set, this layer will pass all the features it receives onto the next layer.\nThis is ideal for decoration, e.g. directionss on cameras", + "type": "boolean" + }, + "presets": { + "description": "Presets for this layer.\nA preset shows up when clicking the map on a without data (or when right-clicking/long-pressing);\nit will prompt the user to add a new point.\n\nThe most important aspect are the tags, which define which tags the new point will have;\nThe title is shown in the dialog, along with the first sentence of the description.\n\nUpon confirmation, the full description is shown beneath the buttons - perfect to add pictures and examples.\n\nNote: the icon of the preset is determined automatically based on the tags and the icon above. Don't worry about that!\nNB: if no presets are defined, the popup to add new points doesn't show up at all", + "type": "array", + "items": { "type": "object", "properties": { - "builtin": { - "type": "string" - }, - "override": {} + "title": { + "description": "The title - shown on the 'add-new'-button." + }, + "tags": { + "description": "The tags to add. It determines the icon too", + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "description": "The _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)" + }, + "exampleImages": { + "description": "Example images, which show real-life pictures of what such a feature might look like\n\nType: image", + "type": "array", + "items": { + "type": "string" + } + }, + "preciseInput": { + "description": "If set, the user will prompted to confirm the location before actually adding the data.\nThis will be with a 'drag crosshair'-method.\n\nIf 'preferredBackgroundCategory' is set, the element will attempt to pick a background layer of that category.", + "anyOf": [ + { + "type": "object", + "properties": { + "preferredBackground": { + "description": "The type of background picture", + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "string" + } + ] + }, + "snapToLayer": { + "description": "If specified, these layers will be shown to and the new point will be snapped towards it", + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "string" + } + ] + }, + "maxSnapDistance": { + "description": "If specified, a new point will only be snapped if it is within this range.\nDistance in meter\n\nDefault: 10", + "type": "number" + } + }, + "required": [ + "preferredBackground" + ] + }, + { + "enum": [ + true + ], + "type": "boolean" + } + ] + } }, "required": [ - "builtin", - "override" + "tags", + "title" ] - }, - { - "type": "string" - } - ] - } - } - }, - "required": [ - "renderings", - "rewrite" - ] - }, - "default_1": { - "type": "object", - "properties": { - "id": { - "description": "An id/name for this filter, used to set the URL parameters", - "type": "string" - }, - "options": { - "description": "The options for a filter\nIf there are multiple options these will be a list of radio buttons\nIf there is only one option this will be a checkbox\nFiltering is done based on the given osmTags that are compared to the objects in that layer.", - "type": "array", - "items": { - "type": "object", - "properties": { - "question": {}, - "osmTags": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "default": { - "type": "boolean" - }, - "fields": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "type": { - "type": "string" - } - }, - "required": [ - "name" - ] - } - } - }, - "required": [ - "question" - ] - } - } - }, - "required": [ - "id", - "options" - ] - }, - "DeleteConfigJson": { - "type": "object", - "properties": { - "extraDeleteReasons": { - "description": "*\nBy default, three reasons to delete a point are shown:\n\n- The point does not exist anymore\n- The point was a testing point\n- THe point could not be found\n\nHowever, for some layers, there might be different or more specific reasons for deletion which can be user friendly to set, e.g.:\n\n- the shop has closed\n- the climbing route has been closed of for nature conservation reasons\n- ...\n\nThese reasons can be stated here and will be shown in the list of options the user can choose from", - "type": "array", - "items": { - "type": "object", - "properties": { - "explanation": { - "description": "The text that will be shown to the user - translatable" - }, - "changesetMessage": { - "description": "The text that will be uploaded into the changeset or will be used in the fixme in case of a soft deletion\nShould be a few words, in english", - "type": "string" - } - }, - "required": [ - "changesetMessage", - "explanation" - ] - } - }, - "nonDeleteMappings": { - "description": "In some cases, a (starting) contributor might wish to delete a feature even though deletion is not appropriate.\n(The most relevant case are small paths running over private property. These should be marked as 'private' instead of deleted, as the community might trace the path again from aerial imagery, gettting us back to the original situation).\n\nBy adding a 'nonDeleteMapping', an option can be added into the list which will retag the feature.\nIt is important that the feature will be retagged in such a way that it won't be picked up by the layer anymore!", - "type": "array", - "items": { - "type": "object", - "properties": { - "if": { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - "then": {} - }, - "required": [ - "if", - "then" - ] - } - }, - "softDeletionTags": { - "description": "In some cases, the contributor is not allowed to delete the current feature (e.g. because it isn't a point, the point is referenced by a relation or the user isn't experienced enough).\nTo still offer the user a 'delete'-option, the feature is retagged with these tags. This is a soft deletion, as the point isn't actually removed from OSM but rather marked as 'disused'\nIt is important that the feature will be retagged in such a way that it won't be picked up by the layer anymore!\n\nExample (note that \"amenity=\" erases the 'amenity'-key alltogether):\n```\n{\n \"and\": [\"disussed:amenity=public_bookcase\", \"amenity=\"]\n}\n```\n\nor (notice the use of the ':='-tag to copy the old value of 'shop=*' into 'disused:shop='):\n```\n{\n \"and\": [\"disused:shop:={shop}\", \"shop=\"]\n}\n```", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" } - ] }, - "neededChangesets": { - "description": "*\nBy default, the contributor needs 20 previous changesets to delete points edited by others.\nFor some small features (e.g. bicycle racks) this is too much and this requirement can be lowered or dropped, which can be done here.", - "type": "number" - } - } - }, - "default_3": { - "type": "object", - "properties": { - "enableImproveAccuracy": { - "description": "One default reason to move a point is to improve accuracy.\nSet to false to disable this reason", - "type": "boolean" + "tagRenderings": { + "description": "All the tag renderings.\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together", + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/QuestionableTagRenderingConfigJson" + }, + { + "type": "object", + "properties": { + "builtin": { + "type": "string" + }, + "override": {} + }, + "required": [ + "builtin", + "override" + ] + }, + { + "$ref": "#/definitions/default<(string|QuestionableTagRenderingConfigJson|{builtin:string;override:any;})[]>" + }, + { + "type": "string" + } + ] + } }, - "enableRelocation": { - "description": "One default reason to move a point is because it has relocated\nSet to false to disable this reason", - "type": "boolean" - } - } - }, - "default_2": { - "type": "object", - "properties": { - "appliesToKey": { - "description": "Every key from this list will be normalized", - "type": "array", - "items": { + "filter": { + "description": "All the extra questions for filtering", + "anyOf": [ + { + "type": "array", + "items": { + "$ref": "#/definitions/default_1" + } + }, + { + "type": "object", + "properties": { + "sameAs": { + "type": "string" + } + }, + "required": [ + "sameAs" + ] + } + ] + }, + "deletion": { + "description": "This block defines under what circumstances the delete dialog is shown for objects of this layer.\nIf set, a dialog is shown to the user to (soft) delete the point.\nThe dialog is built to be user friendly and to prevent mistakes.\nIf deletion is not possible, the dialog will hide itself and show the reason of non-deletability instead.\n\nTo configure, the following values are possible:\n\n- false: never ever show the delete button\n- true: show the default delete button\n- undefined: use the mapcomplete default to show deletion or not. Currently, this is the same as 'false' but this will change in the future\n- or: a hash with options (see below)\n\n The delete dialog\n =================\n\n\n\n#### Hard deletion if enough experience\n\nA feature can only be deleted from OpenStreetMap by mapcomplete if:\n\n- It is a node\n- No ways or relations use the node\n- The logged-in user has enough experience OR the user is the only one to have edited the point previously\n- The logged-in user has no unread messages (or has a ton of experience)\n- The user did not select one of the 'non-delete-options' (see below)\n\nIn all other cases, a 'soft deletion' is used.\n\n#### Soft deletion\n\nA 'soft deletion' is when the point isn't deleted from OSM but retagged so that it'll won't how up in the mapcomplete theme anymore.\nThis makes it look like it was deleted, without doing damage. A fixme will be added to the point.\n\nNote that a soft deletion is _only_ possible if these tags are provided by the theme creator, as they'll be different for every theme\n\n#### No-delete options\n\nIn some cases, the contributor might want to delete something for the wrong reason (e.g. someone who wants to have a path removed \"because the path is on their private property\").\nHowever, the path exists in reality and should thus be on OSM - otherwise the next contributor will pass by and notice \"hey, there is a path missing here! Let me redraw it in OSM!)\n\nThe correct approach is to retag the feature in such a way that it is semantically correct *and* that it doesn't show up on the theme anymore.\nA no-delete option is offered as 'reason to delete it', but secretly retags.", + "anyOf": [ + { + "$ref": "#/definitions/DeleteConfigJson" + }, + { + "type": "boolean" + } + ] + }, + "allowMove": { + "description": "Indicates if a point can be moved and configures the modalities.\n\nA feature can be moved by MapComplete if:\n\n- It is a point\n- The point is _not_ part of a way or a a relation.\n\nOff by default. Can be enabled by setting this flag or by configuring.", + "anyOf": [ + { + "$ref": "#/definitions/default_3" + }, + { + "type": "boolean" + } + ] + }, + "allowSplit": { + "description": "IF set, a 'split this road' button is shown", + "type": "boolean" + }, + "units": { + "description": "In some cases, a value is represented in a certain unit (such as meters for heigt/distance/..., km/h for speed, ...)\n\nSometimes, multiple denominations are possible (e.g. km/h vs mile/h; megawatt vs kilowatt vs gigawatt for power generators, ...)\n\nThis brings in some troubles, as there are multiple ways to write it (no denomitation, 'm' vs 'meter' 'metre', ...)\n\nNot only do we want to write consistent data to OSM, we also want to present this consistently to the user.\nThis is handled by defining units.\n\n# Rendering\n\nTo render a value with long (human) denomination, use {canonical(key)}\n\n# Usage\n\nFirst of all, you define which keys have units applied, for example:\n\n```\nunits: [\n appliesTo: [\"maxspeed\", \"maxspeed:hgv\", \"maxspeed:bus\"]\n applicableUnits: [\n ...\n ]\n]\n```\n\nApplicableUnits defines which is the canonical extension, how it is presented to the user, ...:\n\n```\napplicableUnits: [\n{\n canonicalDenomination: \"km/h\",\n alternativeDenomination: [\"km/u\", \"kmh\", \"kph\"]\n default: true,\n human: {\n en: \"kilometer/hour\",\n nl: \"kilometer/uur\"\n },\n humanShort: {\n en: \"km/h\",\n nl: \"km/u\"\n }\n},\n{\n canoncialDenomination: \"mph\",\n ... similar for miles an hour ...\n}\n]\n```\n\n\nIf this is defined, then every key which the denominations apply to (`maxspeed`, `maxspeed:hgv` and `maxspeed:bus`) will be rewritten at the metatagging stage:\nevery value will be parsed and the canonical extension will be added add presented to the other parts of the code.\n\nAlso, if a freeform text field is used, an extra dropdown with applicable denominations will be given", + "type": "array", + "items": { + "$ref": "#/definitions/default_2" + } + }, + "syncSelection": { + "description": "If set, synchronizes wether or not this layer is selected.\n\nno: Do not sync at all, always revert to default\nlocal: keep selection on local storage\ntheme-only: sync via OSM, but this layer will only be toggled in this theme\nglobal: all layers with this ID will be synced accross all themes", + "enum": [ + "global", + "local", + "no", + "theme-only" + ], "type": "string" - } - }, - "eraseInvalidValues": { - "description": "If set, invalid values will be erased in the MC application (but not in OSM of course!)\nBe careful with setting this", - "type": "boolean" - }, - "applicableUnits": { - "description": "The possible denominations", - "type": "array", - "items": { - "$ref": "#/definitions/ApplicableUnitJson" - } } - }, - "required": [ - "applicableUnits", - "appliesToKey" - ] - } - }, - "$schema": "http://json-schema.org/draft-07/schema#" + }, + "required": [ + "id", + "mapRendering", + "source" + ], + "definitions": { + "AndOrTagConfigJson": { + "type": "object", + "properties": { + "and": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "or": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + } + } + }, + "ApplicableUnitJson": { + "type": "object", + "properties": { + "canonicalDenomination": { + "description": "The canonical value which will be added to the text.\ne.g. \"m\" for meters\nIf the user inputs '42', the canonical value will be added and it'll become '42m'", + "type": "string" + }, + "canonicalDenominationSingular": { + "description": "The canonical denomination in the case that the unit is precisely '1'", + "type": "string" + }, + "alternativeDenomination": { + "description": "A list of alternative values which can occur in the OSM database - used for parsing.", + "type": "array", + "items": { + "type": "string" + } + }, + "human": { + "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"meter\",\n \"fr\": \"metre\"\n}" + }, + "humanSingular": { + "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"minute\",\n \"nl\": \"minuut\"x²\n}" + }, + "prefix": { + "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", + "type": "boolean" + }, + "default": { + "description": "The default interpretation - only one can be set.\nIf none is set, the first unit will be considered the default interpretation of a value without a unit", + "type": "boolean" + } + }, + "required": [ + "canonicalDenomination" + ] + }, + "TagRenderingConfigJson": { + "description": "A TagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nFor an _editable_ tagRenerdering, use 'QuestionableTagRenderingConfigJson' instead, which extends this one", + "type": "object", + "properties": { + "id": { + "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", + "type": "string" + }, + "group": { + "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", + "type": "string" + }, + "labels": { + "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", + "type": "array", + "items": { + "type": "string" + } + }, + "render": { + "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" + }, + "condition": { + "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "freeform": { + "description": "Allow freeform text input from the user", + "type": "object", + "properties": { + "key": { + "description": "If this key is present, then 'render' is used to display the value.\nIf this is undefined, the rendering is _always_ shown", + "type": "string" + } + }, + "required": [ + "key" + ] + }, + "mappings": { + "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", + "type": "array", + "items": { + "type": "object", + "properties": { + "if": { + "description": "If this condition is met, then the text under `then` will be shown.\nIf no value matches, and the user selects this mapping as an option, then these tags will be uploaded to OSM.\n\nFor example: {'if': 'diet:vegetarion=yes', 'then':'A vegetarian option is offered here'}\n\nThis can be an substituting-tag as well, e.g. {'if': 'addr:street:={_calculated_nearby_streetname}', 'then': '{_calculated_nearby_streetname}'}", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "then": { + "description": "If the condition `if` is met, the text `then` will be rendered.\nIf not known yet, the user will be presented with `then` as an option\nType: rendered" + }, + "icon": { + "description": "An icon supporting this mapping; typically shown pretty small\nType: icon", + "anyOf": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", + "type": "string" + } + }, + "required": [ + "class", + "path" + ] + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "if", + "then" + ] + } + } + } + }, + "T": { + "type": "object" + }, + "default_4": { + "description": "The PointRenderingConfig gives all details onto how to render a single point of a feature.\n\nThis can be used if:\n\n- The feature is a point\n- To render something at the centroid of an area, or at the start, end or projected centroid of a way", + "type": "object", + "properties": { + "location": { + "description": "All the locations that this point should be rendered at.\nUsing `location: [\"point\", \"centroid\"] will always render centerpoint", + "type": "array", + "items": { + "type": "string" + } + }, + "icon": { + "description": "The icon for an element.\nNote that this also doubles as the icon for this layer (rendered with the overpass-tags) ánd the icon in the presets.\n\nThe result of the icon is rendered as follows:\nthe resulting string is interpreted as a _list_ of items, separated by \";\". The bottommost layer is the first layer.\nAs a result, on could use a generic pin, then overlay it with a specific icon.\nTo make things even more practical, one can use all SVG's from the folder \"assets/svg\" and _substitute the color_ in it.\nE.g. to draw a red pin, use \"pin:#f00\", to have a green circle with your icon on top, use `circle:#0f0;`\n\nType: icon", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "iconBadges": { + "description": "A list of extra badges to show next to the icon as small badge\nThey will be added as a 25% height icon at the bottom right of the icon, with all the badges in a flex layout.\n\nNote: strings are interpreted as icons, so layering and substituting is supported. You can use `circle:white;./my_icon.svg` to add a background circle", + "type": "array", + "items": { + "type": "object", + "properties": { + "if": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "then": { + "description": "Badge to show\nType: icon", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "if", + "then" + ] + } + }, + "iconSize": { + "description": "A string containing \"width,height\" or \"width,height,anchorpoint\" where anchorpoint is any of 'center', 'top', 'bottom', 'left', 'right', 'bottomleft','topright', ...\nDefault is '40,40,center'", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "rotation": { + "description": "The rotation of an icon, useful for e.g. directions.\nUsage: as if it were a css property for 'rotate', thus has to end with 'deg', e.g. `90deg`, `{direction}deg`, `calc(90deg - {camera:direction}deg)``", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "label": { + "description": "A HTML-fragment that is shown below the icon, for example:\n
{name}
\n\nIf the icon is undefined, then the label is shown in the center of the feature.\nNote that, if the wayhandling hides the icon then no label is shown as well.", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "location" + ] + }, + "default_5": { + "description": "The LineRenderingConfig gives all details onto how to render a single line of a feature.\n\nThis can be used if:\n\n- The feature is a line\n- The feature is an area", + "type": "object", + "properties": { + "color": { + "description": "The color for way-elements and SVG-elements.\nIf the value starts with \"--\", the style of the body element will be queried for the corresponding variable instead", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "width": { + "description": "The stroke-width for way-elements", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": [ + "string", + "number" + ] + } + ] + }, + "dashArray": { + "description": "A dasharray, e.g. \"5 6\"\nThe dasharray defines 'pixels of line, pixels of gap, pixels of line, pixels of gap',\nDefault value: \"\" (empty string == full line)", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "lineCap": { + "description": "The form at the end of a line", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "fill": { + "description": "Wehter or not to fill polygons", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "enum": [ + "no", + "yes" + ], + "type": "string" + } + ] + }, + "fillColor": { + "description": "The color to fill a polygon with.\nIf undefined, this will be slightly more opaque version of the stroke line", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "offset": { + "description": "The number of pixels this line should be moved.\nUse a positive numbe to move to the right, a negative to move to the left (left/right as defined by the drawing direction of the line).\n\nIMPORTANT: MapComplete will already normalize 'key:both:property' and 'key:both' into the corresponding 'key:left' and 'key:right' tagging (same for 'sidewalk=left/right/both' which is rewritten to 'sidewalk:left' and 'sidewalk:right')\nThis simplifies programming. Refer to the CalculatedTags.md-documentation for more details", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "number" + } + ] + } + } + }, + "QuestionableTagRenderingConfigJson": { + "description": "A QuestionableTagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nIf the desired tags are missing and a question is defined, a question will be shown instead.", + "type": "object", + "properties": { + "question": { + "description": "If it turns out that this tagRendering doesn't match _any_ value, then we show this question.\nIf undefined, the question is never asked and this tagrendering is read-only" + }, + "freeform": { + "description": "Allow freeform text input from the user", + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "type": { + "description": "The type of the text-field, e.g. 'string', 'nat', 'float', 'date',...\nSee Docs/SpecialInputElements.md and UI/Input/ValidatedTextField.ts for supported values", + "type": "string" + }, + "placeholder": { + "description": "A (translated) text that is shown (as gray text) within the textfield" + }, + "helperArgs": { + "description": "Extra parameters to initialize the input helper arguments.\nFor semantics, see the 'SpecialInputElements.md'", + "type": "array", + "items": {} + }, + "addExtraTags": { + "description": "If a value is added with the textfield, these extra tag is addded.\nUseful to add a 'fixme=freeform textfield used - to be checked'", + "type": "array", + "items": { + "type": "string" + } + }, + "inline": { + "description": "When set, influences the way a question is asked.\nInstead of showing a full-widht text field, the text field will be shown within the rendering of the question.\n\nThis combines badly with special input elements, as it'll distort the layout.", + "type": "boolean" + }, + "default": { + "description": "default value to enter if no previous tagging is present.\nNormally undefined (aka do not enter anything)", + "type": "string" + } + }, + "required": [ + "key" + ] + }, + "multiAnswer": { + "description": "If true, use checkboxes instead of radio buttons when asking the question", + "type": "boolean" + }, + "mappings": { + "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", + "type": "array", + "items": { + "type": "object", + "properties": { + "if": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "then": { + "description": "Shown if the 'if is fulfilled\nType: rendered" + }, + "icon": { + "description": "An extra icon supporting the choice\nType: icon", + "anyOf": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "Size of the image", + "type": "string" + } + }, + "required": [ + "class", + "path" + ] + }, + { + "type": "string" + } + ] + }, + "hideInAnswer": { + "description": "In some cases, multiple taggings exist (e.g. a default assumption, or a commonly mapped abbreviation and a fully written variation).\n\nIn the latter case, a correct text should be shown, but only a single, canonical tagging should be selectable by the user.\nIn this case, one of the mappings can be hiden by setting this flag.\n\nTo demonstrate an example making a default assumption:\n\nmappings: [\n {\n if: \"access=\", -- no access tag present, we assume accessible\n then: \"Accessible to the general public\",\n hideInAnswer: true\n },\n {\n if: \"access=yes\",\n then: \"Accessible to the general public\", -- the user selected this, we add that to OSM\n },\n {\n if: \"access=no\",\n then: \"Not accessible to the public\"\n }\n]\n\n\nFor example, for an operator, we have `operator=Agentschap Natuur en Bos`, which is often abbreviated to `operator=ANB`.\nThen, we would add two mappings:\n{\n if: \"operator=Agentschap Natuur en Bos\" -- the non-abbreviated version which should be uploaded\n then: \"Maintained by Agentschap Natuur en Bos\"\n},\n{\n if: \"operator=ANB\", -- we don't want to upload abbreviations\n then: \"Maintained by Agentschap Natuur en Bos\"\n hideInAnswer: true\n}\n\nHide in answer can also be a tagsfilter, e.g. to make sure an option is only shown when appropriate.\nKeep in mind that this is reverse logic: it will be hidden in the answer if the condition is true, it will thus only show in the case of a mismatch\n\ne.g., for toilets: if \"wheelchair=no\", we know there is no wheelchair dedicated room.\nFor the location of the changing table, the option \"in the wheelchair accessible toilet is weird\", so we write:\n\n{\n \"question\": \"Where is the changing table located?\"\n \"mappings\": [\n {\"if\":\"changing_table:location=female\",\"then\":\"In the female restroom\"},\n {\"if\":\"changing_table:location=male\",\"then\":\"In the male restroom\"},\n {\"if\":\"changing_table:location=wheelchair\",\"then\":\"In the wheelchair accessible restroom\", \"hideInAnswer\": \"wheelchair=no\"},\n \n ]\n}\n\nAlso have a look for the meta-tags\n{\n if: \"operator=Agentschap Natuur en Bos\",\n then: \"Maintained by Agentschap Natuur en Bos\",\n hideInAnswer: \"_country!=be\"\n}", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": [ + "string", + "boolean" + ] + } + ] + }, + "ifnot": { + "description": "Only applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "addExtraTags": { + "description": "If chosen as answer, these tags will be applied as well onto the object.\nNot compatible with multiAnswer", + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "if", + "then" + ] + } + }, + "id": { + "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", + "type": "string" + }, + "group": { + "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", + "type": "string" + }, + "labels": { + "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", + "type": "array", + "items": { + "type": "string" + } + }, + "render": { + "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" + }, + "condition": { + "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + } + }, + "default<(string|QuestionableTagRenderingConfigJson|{builtin:string;override:any;})[]>": { + "type": "object", + "properties": { + "rewrite": { + "type": "object", + "properties": { + "sourceString": { + "type": "array", + "items": { + "type": "string" + } + }, + "into": { + "type": "array", + "items": { + "type": "array", + "items": {} + } + } + }, + "required": [ + "into", + "sourceString" + ] + }, + "renderings": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/QuestionableTagRenderingConfigJson" + }, + { + "type": "object", + "properties": { + "builtin": { + "type": "string" + }, + "override": {} + }, + "required": [ + "builtin", + "override" + ] + }, + { + "type": "string" + } + ] + } + } + }, + "required": [ + "renderings", + "rewrite" + ] + }, + "default_1": { + "type": "object", + "properties": { + "id": { + "description": "An id/name for this filter, used to set the URL parameters", + "type": "string" + }, + "options": { + "description": "The options for a filter\nIf there are multiple options these will be a list of radio buttons\nIf there is only one option this will be a checkbox\nFiltering is done based on the given osmTags that are compared to the objects in that layer.", + "type": "array", + "items": { + "type": "object", + "properties": { + "question": {}, + "osmTags": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "default": { + "type": "boolean" + }, + "fields": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "name" + ] + } + } + }, + "required": [ + "question" + ] + } + } + }, + "required": [ + "id", + "options" + ] + }, + "DeleteConfigJson": { + "type": "object", + "properties": { + "extraDeleteReasons": { + "description": "*\nBy default, three reasons to delete a point are shown:\n\n- The point does not exist anymore\n- The point was a testing point\n- THe point could not be found\n\nHowever, for some layers, there might be different or more specific reasons for deletion which can be user friendly to set, e.g.:\n\n- the shop has closed\n- the climbing route has been closed of for nature conservation reasons\n- ...\n\nThese reasons can be stated here and will be shown in the list of options the user can choose from", + "type": "array", + "items": { + "type": "object", + "properties": { + "explanation": { + "description": "The text that will be shown to the user - translatable" + }, + "changesetMessage": { + "description": "The text that will be uploaded into the changeset or will be used in the fixme in case of a soft deletion\nShould be a few words, in english", + "type": "string" + } + }, + "required": [ + "changesetMessage", + "explanation" + ] + } + }, + "nonDeleteMappings": { + "description": "In some cases, a (starting) contributor might wish to delete a feature even though deletion is not appropriate.\n(The most relevant case are small paths running over private property. These should be marked as 'private' instead of deleted, as the community might trace the path again from aerial imagery, gettting us back to the original situation).\n\nBy adding a 'nonDeleteMapping', an option can be added into the list which will retag the feature.\nIt is important that the feature will be retagged in such a way that it won't be picked up by the layer anymore!", + "type": "array", + "items": { + "type": "object", + "properties": { + "if": { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + "then": {} + }, + "required": [ + "if", + "then" + ] + } + }, + "softDeletionTags": { + "description": "In some cases, the contributor is not allowed to delete the current feature (e.g. because it isn't a point, the point is referenced by a relation or the user isn't experienced enough).\nTo still offer the user a 'delete'-option, the feature is retagged with these tags. This is a soft deletion, as the point isn't actually removed from OSM but rather marked as 'disused'\nIt is important that the feature will be retagged in such a way that it won't be picked up by the layer anymore!\n\nExample (note that \"amenity=\" erases the 'amenity'-key alltogether):\n```\n{\n \"and\": [\"disussed:amenity=public_bookcase\", \"amenity=\"]\n}\n```\n\nor (notice the use of the ':='-tag to copy the old value of 'shop=*' into 'disused:shop='):\n```\n{\n \"and\": [\"disused:shop:={shop}\", \"shop=\"]\n}\n```", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "neededChangesets": { + "description": "*\nBy default, the contributor needs 20 previous changesets to delete points edited by others.\nFor some small features (e.g. bicycle racks) this is too much and this requirement can be lowered or dropped, which can be done here.", + "type": "number" + } + } + }, + "default_3": { + "type": "object", + "properties": { + "enableImproveAccuracy": { + "description": "One default reason to move a point is to improve accuracy.\nSet to false to disable this reason", + "type": "boolean" + }, + "enableRelocation": { + "description": "One default reason to move a point is because it has relocated\nSet to false to disable this reason", + "type": "boolean" + } + } + }, + "default_2": { + "type": "object", + "properties": { + "appliesToKey": { + "description": "Every key from this list will be normalized", + "type": "array", + "items": { + "type": "string" + } + }, + "eraseInvalidValues": { + "description": "If set, invalid values will be erased in the MC application (but not in OSM of course!)\nBe careful with setting this", + "type": "boolean" + }, + "applicableUnits": { + "description": "The possible denominations", + "type": "array", + "items": { + "$ref": "#/definitions/ApplicableUnitJson" + } + } + }, + "required": [ + "applicableUnits", + "appliesToKey" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" } \ No newline at end of file diff --git a/Docs/Schemas/LayoutConfigJsonJSC.ts b/Docs/Schemas/LayoutConfigJsonJSC.ts index 1367601236..f80e08e10f 100644 --- a/Docs/Schemas/LayoutConfigJsonJSC.ts +++ b/Docs/Schemas/LayoutConfigJsonJSC.ts @@ -1,1483 +1,1483 @@ export default { - "description": "Defines the entire theme.\n\nA theme is the collection of the layers that are shown; the intro text, the icon, ...\nIt more or less defines the entire experience.\n\nMost of the fields defined here are metadata about the theme, such as its name, description, supported languages, default starting location, ...\n\nThe main chunk of the json will however be the 'layers'-array, where the details of your layers are.\n\nGeneral remark: a type (string | any) indicates either a fixed or a translatable string.", - "type": "object", - "properties": { - "id": { - "description": "The id of this layout.\n\nThis is used as hashtag in the changeset message, which will read something like \"Adding data with #mapcomplete for theme #\"\nMake sure it is something decent and descriptive, it should be a simple, lowercase string.\n\nOn official themes, it'll become the name of the page, e.g.\n'cyclestreets' which become 'cyclestreets.html'", - "type": "string" - }, - "credits": { - "description": "Who helped to create this theme and should be attributed?", - "type": "string" - }, - "maintainer": { - "description": "Who does maintain this preset?", - "type": "string" - }, - "version": { - "description": "A version number, either semantically or by date.\nShould be sortable, where the higher value is the later version", - "type": "string" - }, - "mustHaveLanguage": { - "description": "Only used in 'generateLayerOverview': if present, every translation will be checked to make sure it is fully translated.\n\nThis must be a list of two-letter, lowercase codes which identifies the language, e.g. \"en\", \"nl\", ...", - "type": "array", - "items": { - "type": "string" - } - }, - "title": { - "description": "The title, as shown in the welcome message and the more-screen." - }, - "shortDescription": { - "description": "A short description, showed as social description and in the 'more theme'-buttons.\nNote that if this one is not defined, the first sentence of 'description' is used" - }, - "description": { - "description": "The description, as shown in the welcome message and the more-screen" - }, - "descriptionTail": { - "description": "A part of the description, shown under the login-button." - }, - "icon": { - "description": "The icon representing this theme.\nUsed as logo in the more-screen and (for official themes) as favicon, webmanifest logo, ...\nEither a URL or a base64 encoded value (which should include 'data:image/svg+xml;base64)\n\nType: icon", - "type": "string" - }, - "socialImage": { - "description": "Link to a 'social image' which is included as og:image-tag on official themes.\nUseful to share the theme on social media.\nSee https://www.h3xed.com/web-and-internet/how-to-use-og-image-meta-tag-facebook-reddit for more information$\n\nType: image", - "type": "string" - }, - "startZoom": { - "description": "Default location and zoom to start.\nNote that this is barely used. Once the user has visited mapcomplete at least once, the previous location of the user will be used", - "type": "number" - }, - "startLat": { - "type": "number" - }, - "startLon": { - "type": "number" - }, - "widenFactor": { - "description": "When a query is run, the data within bounds of the visible map is loaded.\nHowever, users tend to pan and zoom a lot. It is pretty annoying if every single pan means a reloading of the data.\nFor this, the bounds are widened in order to make a small pan still within bounds of the loaded data.\n\nIF widenfactor is 1, this feature is disabled. A recommended value is between 1 and 3", - "type": "number" - }, - "overpassMaxZoom": { - "description": "At low zoom levels, overpass is used to query features.\nAt high zoom level, the OSM api is used to fetch one or more BBOX aligning with a slippy tile.\nThe overpassMaxZoom controls the flipoverpoint: if the zoom is this or lower, overpass is used.", - "type": "number" - }, - "osmApiTileSize": { - "description": "When the OSM-api is used to fetch features, it does so in a tiled fashion.\nThese tiles are using a ceratin zoom level, that can be controlled here\nDefault: overpassMaxZoom + 1", - "type": "number" - }, - "overrideAll": { - "description": "An override applied on all layers of the theme.\n\nE.g.: if there are two layers defined:\n```\n\"layers\":[\n {\"title\": ..., \"tagRenderings\": [...], \"osmSource\":{\"tags\": ...}},\n {\"title\", ..., \"tagRenderings\", [...], \"osmSource\":{\"tags\" ...}}\n]\n```\n\nand overrideAll is specified:\n```\n\"overrideAll\": {\n \"osmSource\":{\"geoJsonSource\":\"xyz\"}\n}\nthen the result will be that all the layers will have these properties applied and result in:\n\"layers\":[\n {\"title\": ..., \"tagRenderings\": [...], \"osmSource\":{\"tags\": ..., \"geoJsonSource\":\"xyz\"}},\n {\"title\", ..., \"tagRenderings\", [...], \"osmSource\":{\"tags\" ..., \"geoJsonSource\":\"xyz\"}}\n]\n```\n\nIf 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\n\n\"overrideAll\": {\n \"+tagRenderings\": [ { ... some tagrendering ... }]\n}\n\nIn the above scenario, `sometagrendering` will be added at the beginning of the tagrenderings of every layer" - }, - "defaultBackgroundId": { - "description": "The id of the default background. BY default: vanilla OSM", - "type": "string" - }, - "tileLayerSources": { - "description": "Define some (overlay) slippy map tilesources", - "type": "array", - "items": { - "$ref": "#/definitions/default_6" - } - }, - "layers": { - "description": "The layers to display.\n\nEvery layer contains a description of which feature to display - the overpassTags which are queried.\nInstead of running one query for every layer, the query is fused.\n\nAfterwards, every layer is given the list of features.\nEvery layer takes away the features that match with them*, and give the leftovers to the next layers.\n\nThis implies that the _order_ of the layers is important in the case of features with the same tags;\nas the later layers might never receive their feature.\n\n*layers can also remove 'leftover'-features if the leftovers overlap with a feature in the layer itself\n\nNote that builtin layers can be reused. Either put in the name of the layer to reuse, or use {builtin: \"layername\", override: ...}\n\nThe 'override'-object will be copied over the original values of the layer, which allows to change certain aspects of the layer\n\nFor 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:\n\n```\n\"layer\": {\n \"builtin\": \"nature_reserve\",\n \"override\": {\"source\": \n {\"osmTags\": {\n \"+and\":[\"operator=Natuurpunt\"]\n }\n }\n }\n}\n```\n\nIt'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:\n\n```\n\"layer\": {\n \"builtin\": [\"benches\", \"drinking_water\"],\n \"override\": {\"minzoom\": 12}\n}\n```", - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/LayerConfigJson" - }, - { - "type": "object", - "properties": { - "builtin": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "string" - } - ] - }, - "override": {}, - "hideTagRenderingsWithLabels": { - "description": "TagRenderings with any of these labels will be removed from the layer.\nNote that the 'id' and 'group' are considered labels too", - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "builtin", - "override" - ] - }, - { + "description": "Defines the entire theme.\n\nA theme is the collection of the layers that are shown; the intro text, the icon, ...\nIt more or less defines the entire experience.\n\nMost of the fields defined here are metadata about the theme, such as its name, description, supported languages, default starting location, ...\n\nThe main chunk of the json will however be the 'layers'-array, where the details of your layers are.\n\nGeneral remark: a type (string | any) indicates either a fixed or a translatable string.", + "type": "object", + "properties": { + "id": { + "description": "The id of this layout.\n\nThis is used as hashtag in the changeset message, which will read something like \"Adding data with #mapcomplete for theme #\"\nMake sure it is something decent and descriptive, it should be a simple, lowercase string.\n\nOn official themes, it'll become the name of the page, e.g.\n'cyclestreets' which become 'cyclestreets.html'", "type": "string" - } - ] - } - }, - "clustering": { - "description": "If defined, data will be clustered.\nDefaults to {maxZoom: 16, minNeeded: 500}", - "anyOf": [ - { - "type": "object", - "properties": { - "maxZoom": { - "description": "All zoom levels above 'maxzoom' are not clustered anymore.\nDefaults to 18", - "type": "number" - }, - "minNeededElements": { - "description": "The number of elements per tile needed to start clustering\nIf clustering is defined, defaults to 250", - "type": "number" - } - } }, - { - "enum": [ - false - ], - "type": "boolean" - } - ] - }, - "customCss": { - "description": "The URL of a custom CSS stylesheet to modify the layout", - "type": "string" - }, - "hideFromOverview": { - "description": "If set to true, this layout will not be shown in the overview with more themes", - "type": "boolean" - }, - "lockLocation": { - "description": "If set to true, the basemap will not scroll outside of the area visible on initial zoom.\nIf set to [[lon, lat], [lon, lat]], the map will not scroll outside of those bounds.\nOff by default, which will enable panning to the entire world", - "anyOf": [ - { - "type": "array", - "items": [ - { - "type": "array", - "items": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "minItems": 2, - "maxItems": 2 - }, - { - "type": "array", - "items": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "minItems": 2, - "maxItems": 2 - } - ], - "minItems": 2, - "maxItems": 2 + "credits": { + "description": "Who helped to create this theme and should be attributed?", + "type": "string" }, - { - "type": "array", - "items": { + "maintainer": { + "description": "Who does maintain this preset?", + "type": "string" + }, + "version": { + "description": "A version number, either semantically or by date.\nShould be sortable, where the higher value is the later version", + "type": "string" + }, + "mustHaveLanguage": { + "description": "Only used in 'generateLayerOverview': if present, every translation will be checked to make sure it is fully translated.\n\nThis must be a list of two-letter, lowercase codes which identifies the language, e.g. \"en\", \"nl\", ...", "type": "array", "items": { - "type": "number" - } - } - } - ] - }, - "extraLink": { - "description": "Adds an additional button on the top-left of the application.\nThis can link to an arbitrary location.\n\nNote that {lat},{lon},{zoom}, {language} and {theme} will be replaced\n\nDefault: {icon: \"./assets/svg/pop-out.svg\", href: 'https://mapcomplete.osm.be/{theme}.html?lat={lat}&lon={lon}&z={zoom}, requirements: [\"iframe\",\"no-welcome-message]},", - "$ref": "#/definitions/default" - }, - "enableUserBadge": { - "description": "If set to false, disables logging in.\nThe userbadge will be hidden, all login-buttons will be hidden and editing will be disabled", - "type": "boolean" - }, - "enableShareScreen": { - "description": "If false, hides the tab 'share'-tab in the welcomeMessage", - "type": "boolean" - }, - "enableMoreQuests": { - "description": "Hides the tab with more themes in the welcomeMessage", - "type": "boolean" - }, - "enableLayers": { - "description": "If false, the layer selection/filter view will be hidden\nThe corresponding URL-parameter is 'fs-filters' instead of 'fs-layers'", - "type": "boolean" - }, - "enableSearch": { - "description": "If set to false, hides the search bar", - "type": "boolean" - }, - "enableAddNewPoints": { - "description": "If set to false, the ability to add new points or nodes will be disabled.\nEditing already existing features will still be possible", - "type": "boolean" - }, - "enableGeolocation": { - "description": "If set to false, the 'geolocation'-button will be hidden.", - "type": "boolean" - }, - "enableBackgroundLayerSelection": { - "description": "Enable switching the backgroundlayer.\nIf false, the quickswitch-buttons are removed (bottom left) and the dropdown in the layer selection is removed as well", - "type": "boolean" - }, - "enableShowAllQuestions": { - "description": "If set to true, will show _all_ unanswered questions in a popup instead of just the next one", - "type": "boolean" - }, - "enableDownload": { - "description": "If set to true, download button for the data will be shown (offers downloading as geojson and csv)", - "type": "boolean" - }, - "enablePdfDownload": { - "description": "If set to true, exporting a pdf is enabled", - "type": "boolean" - }, - "enableNoteImports": { - "description": "If true, notes will be loaded and parsed. If a note is an import (as created by the import_helper.html-tool from mapcomplete),\nthese notes will be shown if a relevant layer is present.", - "type": "boolean" - }, - "overpassUrl": { - "description": "Set one or more overpass URLs to use for this theme..", - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "string" - } - ] - }, - "overpassTimeout": { - "description": "Set a different timeout for overpass queries - in seconds. Default: 30s", - "type": "number" - } - }, - "required": [ - "description", - "icon", - "id", - "layers", - "maintainer", - "startLat", - "startLon", - "startZoom", - "title", - "version" - ], - "definitions": { - "AndOrTagConfigJson": { - "type": "object", - "properties": { - "and": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { "type": "string" - } - ] - } - }, - "or": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } - } - } - }, - "ApplicableUnitJson": { - "type": "object", - "properties": { - "canonicalDenomination": { - "description": "The canonical value which will be added to the text.\ne.g. \"m\" for meters\nIf the user inputs '42', the canonical value will be added and it'll become '42m'", - "type": "string" - }, - "canonicalDenominationSingular": { - "description": "The canonical denomination in the case that the unit is precisely '1'", - "type": "string" - }, - "alternativeDenomination": { - "description": "A list of alternative values which can occur in the OSM database - used for parsing.", - "type": "array", - "items": { - "type": "string" - } - }, - "human": { - "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"meter\",\n \"fr\": \"metre\"\n}" - }, - "humanSingular": { - "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"minute\",\n \"nl\": \"minuut\"x²\n}" - }, - "prefix": { - "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", - "type": "boolean" - }, - "default": { - "description": "The default interpretation - only one can be set.\nIf none is set, the first unit will be considered the default interpretation of a value without a unit", - "type": "boolean" - } - }, - "required": [ - "canonicalDenomination" - ] - }, - "TagRenderingConfigJson": { - "description": "A TagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nFor an _editable_ tagRenerdering, use 'QuestionableTagRenderingConfigJson' instead, which extends this one", - "type": "object", - "properties": { - "id": { - "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", - "type": "string" - }, - "group": { - "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", - "type": "string" - }, - "labels": { - "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", - "type": "array", - "items": { - "type": "string" - } - }, - "render": { - "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" - }, - "condition": { - "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" } - ] - }, - "freeform": { - "description": "Allow freeform text input from the user", - "type": "object", - "properties": { - "key": { - "description": "If this key is present, then 'render' is used to display the value.\nIf this is undefined, the rendering is _always_ shown", - "type": "string" - } - }, - "required": [ - "key" - ] - }, - "mappings": { - "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", - "type": "array", - "items": { - "type": "object", - "properties": { - "if": { - "description": "If this condition is met, then the text under `then` will be shown.\nIf no value matches, and the user selects this mapping as an option, then these tags will be uploaded to OSM.\n\nFor example: {'if': 'diet:vegetarion=yes', 'then':'A vegetarian option is offered here'}\n\nThis can be an substituting-tag as well, e.g. {'if': 'addr:street:={_calculated_nearby_streetname}', 'then': '{_calculated_nearby_streetname}'}", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "then": { - "description": "If the condition `if` is met, the text `then` will be rendered.\nIf not known yet, the user will be presented with `then` as an option\nType: rendered" - }, - "icon": { - "description": "An icon supporting this mapping; typically shown pretty small\nType: icon", - "anyOf": [ - { - "type": "object", - "properties": { - "path": { - "description": "The path to the icon\nType: icon", - "type": "string" - }, - "class": { - "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", - "type": "string" - } - }, - "required": [ - "class", - "path" - ] - }, - { - "type": "string" - } - ] - } - }, - "required": [ - "if", - "then" - ] - } - } - } - }, - "T": { - "type": "object" - }, - "default_4": { - "description": "The PointRenderingConfig gives all details onto how to render a single point of a feature.\n\nThis can be used if:\n\n- The feature is a point\n- To render something at the centroid of an area, or at the start, end or projected centroid of a way", - "type": "object", - "properties": { - "location": { - "description": "All the locations that this point should be rendered at.\nUsing `location: [\"point\", \"centroid\"] will always render centerpoint", - "type": "array", - "items": { - "type": "string" - } - }, - "icon": { - "description": "The icon for an element.\nNote that this also doubles as the icon for this layer (rendered with the overpass-tags) ánd the icon in the presets.\n\nThe result of the icon is rendered as follows:\nthe resulting string is interpreted as a _list_ of items, separated by \";\". The bottommost layer is the first layer.\nAs a result, on could use a generic pin, then overlay it with a specific icon.\nTo make things even more practical, one can use all SVG's from the folder \"assets/svg\" and _substitute the color_ in it.\nE.g. to draw a red pin, use \"pin:#f00\", to have a green circle with your icon on top, use `circle:#0f0;`\n\nType: icon", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "iconBadges": { - "description": "A list of extra badges to show next to the icon as small badge\nThey will be added as a 25% height icon at the bottom right of the icon, with all the badges in a flex layout.\n\nNote: strings are interpreted as icons, so layering and substituting is supported. You can use `circle:white;./my_icon.svg` to add a background circle", - "type": "array", - "items": { - "type": "object", - "properties": { - "if": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "then": { - "description": "Badge to show\nType: icon", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - } - }, - "required": [ - "if", - "then" - ] - } - }, - "iconSize": { - "description": "A string containing \"width,height\" or \"width,height,anchorpoint\" where anchorpoint is any of 'center', 'top', 'bottom', 'left', 'right', 'bottomleft','topright', ...\nDefault is '40,40,center'", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "rotation": { - "description": "The rotation of an icon, useful for e.g. directions.\nUsage: as if it were a css property for 'rotate', thus has to end with 'deg', e.g. `90deg`, `{direction}deg`, `calc(90deg - {camera:direction}deg)``", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "label": { - "description": "A HTML-fragment that is shown below the icon, for example:\n
{name}
\n\nIf the icon is undefined, then the label is shown in the center of the feature.\nNote that, if the wayhandling hides the icon then no label is shown as well.", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - } - }, - "required": [ - "location" - ] - }, - "default_5": { - "description": "The LineRenderingConfig gives all details onto how to render a single line of a feature.\n\nThis can be used if:\n\n- The feature is a line\n- The feature is an area", - "type": "object", - "properties": { - "color": { - "description": "The color for way-elements and SVG-elements.\nIf the value starts with \"--\", the style of the body element will be queried for the corresponding variable instead", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "width": { - "description": "The stroke-width for way-elements", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": [ - "string", - "number" - ] - } - ] - }, - "dashArray": { - "description": "A dasharray, e.g. \"5 6\"\nThe dasharray defines 'pixels of line, pixels of gap, pixels of line, pixels of gap',\nDefault value: \"\" (empty string == full line)", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "lineCap": { - "description": "The form at the end of a line", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "fill": { - "description": "Wehter or not to fill polygons", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "enum": [ - "no", - "yes" - ], - "type": "string" - } - ] - }, - "fillColor": { - "description": "The color to fill a polygon with.\nIf undefined, this will be slightly more opaque version of the stroke line", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "offset": { - "description": "The number of pixels this line should be moved.\nUse a positive numbe to move to the right, a negative to move to the left (left/right as defined by the drawing direction of the line).\n\nIMPORTANT: MapComplete will already normalize 'key:both:property' and 'key:both' into the corresponding 'key:left' and 'key:right' tagging (same for 'sidewalk=left/right/both' which is rewritten to 'sidewalk:left' and 'sidewalk:right')\nThis simplifies programming. Refer to the CalculatedTags.md-documentation for more details", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "number" - } - ] - } - } - }, - "QuestionableTagRenderingConfigJson": { - "description": "A QuestionableTagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nIf the desired tags are missing and a question is defined, a question will be shown instead.", - "type": "object", - "properties": { - "question": { - "description": "If it turns out that this tagRendering doesn't match _any_ value, then we show this question.\nIf undefined, the question is never asked and this tagrendering is read-only" - }, - "freeform": { - "description": "Allow freeform text input from the user", - "type": "object", - "properties": { - "key": { - "type": "string" - }, - "type": { - "description": "The type of the text-field, e.g. 'string', 'nat', 'float', 'date',...\nSee Docs/SpecialInputElements.md and UI/Input/ValidatedTextField.ts for supported values", - "type": "string" - }, - "placeholder": { - "description": "A (translated) text that is shown (as gray text) within the textfield" - }, - "helperArgs": { - "description": "Extra parameters to initialize the input helper arguments.\nFor semantics, see the 'SpecialInputElements.md'", - "type": "array", - "items": {} - }, - "addExtraTags": { - "description": "If a value is added with the textfield, these extra tag is addded.\nUseful to add a 'fixme=freeform textfield used - to be checked'", - "type": "array", - "items": { - "type": "string" - } - }, - "inline": { - "description": "When set, influences the way a question is asked.\nInstead of showing a full-widht text field, the text field will be shown within the rendering of the question.\n\nThis combines badly with special input elements, as it'll distort the layout.", - "type": "boolean" - }, - "default": { - "description": "default value to enter if no previous tagging is present.\nNormally undefined (aka do not enter anything)", - "type": "string" - } - }, - "required": [ - "key" - ] - }, - "multiAnswer": { - "description": "If true, use checkboxes instead of radio buttons when asking the question", - "type": "boolean" - }, - "mappings": { - "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", - "type": "array", - "items": { - "type": "object", - "properties": { - "if": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "then": { - "description": "Shown if the 'if is fulfilled\nType: rendered" - }, - "icon": { - "description": "An extra icon supporting the choice\nType: icon", - "anyOf": [ - { - "type": "object", - "properties": { - "path": { - "description": "The path to the icon\nType: icon", - "type": "string" - }, - "class": { - "description": "Size of the image", - "type": "string" - } - }, - "required": [ - "class", - "path" - ] - }, - { - "type": "string" - } - ] - }, - "hideInAnswer": { - "description": "In some cases, multiple taggings exist (e.g. a default assumption, or a commonly mapped abbreviation and a fully written variation).\n\nIn the latter case, a correct text should be shown, but only a single, canonical tagging should be selectable by the user.\nIn this case, one of the mappings can be hiden by setting this flag.\n\nTo demonstrate an example making a default assumption:\n\nmappings: [\n {\n if: \"access=\", -- no access tag present, we assume accessible\n then: \"Accessible to the general public\",\n hideInAnswer: true\n },\n {\n if: \"access=yes\",\n then: \"Accessible to the general public\", -- the user selected this, we add that to OSM\n },\n {\n if: \"access=no\",\n then: \"Not accessible to the public\"\n }\n]\n\n\nFor example, for an operator, we have `operator=Agentschap Natuur en Bos`, which is often abbreviated to `operator=ANB`.\nThen, we would add two mappings:\n{\n if: \"operator=Agentschap Natuur en Bos\" -- the non-abbreviated version which should be uploaded\n then: \"Maintained by Agentschap Natuur en Bos\"\n},\n{\n if: \"operator=ANB\", -- we don't want to upload abbreviations\n then: \"Maintained by Agentschap Natuur en Bos\"\n hideInAnswer: true\n}\n\nHide in answer can also be a tagsfilter, e.g. to make sure an option is only shown when appropriate.\nKeep in mind that this is reverse logic: it will be hidden in the answer if the condition is true, it will thus only show in the case of a mismatch\n\ne.g., for toilets: if \"wheelchair=no\", we know there is no wheelchair dedicated room.\nFor the location of the changing table, the option \"in the wheelchair accessible toilet is weird\", so we write:\n\n{\n \"question\": \"Where is the changing table located?\"\n \"mappings\": [\n {\"if\":\"changing_table:location=female\",\"then\":\"In the female restroom\"},\n {\"if\":\"changing_table:location=male\",\"then\":\"In the male restroom\"},\n {\"if\":\"changing_table:location=wheelchair\",\"then\":\"In the wheelchair accessible restroom\", \"hideInAnswer\": \"wheelchair=no\"},\n \n ]\n}\n\nAlso have a look for the meta-tags\n{\n if: \"operator=Agentschap Natuur en Bos\",\n then: \"Maintained by Agentschap Natuur en Bos\",\n hideInAnswer: \"_country!=be\"\n}", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": [ - "string", - "boolean" - ] - } - ] - }, - "ifnot": { - "description": "Only applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "addExtraTags": { - "description": "If chosen as answer, these tags will be applied as well onto the object.\nNot compatible with multiAnswer", - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "if", - "then" - ] - } - }, - "id": { - "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", - "type": "string" - }, - "group": { - "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", - "type": "string" - }, - "labels": { - "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", - "type": "array", - "items": { - "type": "string" - } - }, - "render": { - "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" - }, - "condition": { - "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } - } - }, - "default<(string|QuestionableTagRenderingConfigJson|{builtin:string;override:any;})[]>": { - "type": "object", - "properties": { - "rewrite": { - "type": "object", - "properties": { - "sourceString": { - "type": "array", - "items": { - "type": "string" - } - }, - "into": { - "type": "array", - "items": { - "type": "array", - "items": {} - } - } - }, - "required": [ - "into", - "sourceString" - ] - }, - "renderings": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/QuestionableTagRenderingConfigJson" - }, - { - "type": "object", - "properties": { - "builtin": { - "type": "string" - }, - "override": {} - }, - "required": [ - "builtin", - "override" - ] - }, - { - "type": "string" - } - ] - } - } - }, - "required": [ - "renderings", - "rewrite" - ] - }, - "default_1": { - "type": "object", - "properties": { - "id": { - "description": "An id/name for this filter, used to set the URL parameters", - "type": "string" - }, - "options": { - "description": "The options for a filter\nIf there are multiple options these will be a list of radio buttons\nIf there is only one option this will be a checkbox\nFiltering is done based on the given osmTags that are compared to the objects in that layer.", - "type": "array", - "items": { - "type": "object", - "properties": { - "question": {}, - "osmTags": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "default": { - "type": "boolean" - }, - "fields": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "type": { - "type": "string" - } - }, - "required": [ - "name" - ] - } - } - }, - "required": [ - "question" - ] - } - } - }, - "required": [ - "id", - "options" - ] - }, - "DeleteConfigJson": { - "type": "object", - "properties": { - "extraDeleteReasons": { - "description": "*\nBy default, three reasons to delete a point are shown:\n\n- The point does not exist anymore\n- The point was a testing point\n- THe point could not be found\n\nHowever, for some layers, there might be different or more specific reasons for deletion which can be user friendly to set, e.g.:\n\n- the shop has closed\n- the climbing route has been closed of for nature conservation reasons\n- ...\n\nThese reasons can be stated here and will be shown in the list of options the user can choose from", - "type": "array", - "items": { - "type": "object", - "properties": { - "explanation": { - "description": "The text that will be shown to the user - translatable" - }, - "changesetMessage": { - "description": "The text that will be uploaded into the changeset or will be used in the fixme in case of a soft deletion\nShould be a few words, in english", - "type": "string" - } - }, - "required": [ - "changesetMessage", - "explanation" - ] - } - }, - "nonDeleteMappings": { - "description": "In some cases, a (starting) contributor might wish to delete a feature even though deletion is not appropriate.\n(The most relevant case are small paths running over private property. These should be marked as 'private' instead of deleted, as the community might trace the path again from aerial imagery, gettting us back to the original situation).\n\nBy adding a 'nonDeleteMapping', an option can be added into the list which will retag the feature.\nIt is important that the feature will be retagged in such a way that it won't be picked up by the layer anymore!", - "type": "array", - "items": { - "type": "object", - "properties": { - "if": { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - "then": {} - }, - "required": [ - "if", - "then" - ] - } - }, - "softDeletionTags": { - "description": "In some cases, the contributor is not allowed to delete the current feature (e.g. because it isn't a point, the point is referenced by a relation or the user isn't experienced enough).\nTo still offer the user a 'delete'-option, the feature is retagged with these tags. This is a soft deletion, as the point isn't actually removed from OSM but rather marked as 'disused'\nIt is important that the feature will be retagged in such a way that it won't be picked up by the layer anymore!\n\nExample (note that \"amenity=\" erases the 'amenity'-key alltogether):\n```\n{\n \"and\": [\"disussed:amenity=public_bookcase\", \"amenity=\"]\n}\n```\n\nor (notice the use of the ':='-tag to copy the old value of 'shop=*' into 'disused:shop='):\n```\n{\n \"and\": [\"disused:shop:={shop}\", \"shop=\"]\n}\n```", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "neededChangesets": { - "description": "*\nBy default, the contributor needs 20 previous changesets to delete points edited by others.\nFor some small features (e.g. bicycle racks) this is too much and this requirement can be lowered or dropped, which can be done here.", - "type": "number" - } - } - }, - "default_3": { - "type": "object", - "properties": { - "enableImproveAccuracy": { - "description": "One default reason to move a point is to improve accuracy.\nSet to false to disable this reason", - "type": "boolean" - }, - "enableRelocation": { - "description": "One default reason to move a point is because it has relocated\nSet to false to disable this reason", - "type": "boolean" - } - } - }, - "default_2": { - "type": "object", - "properties": { - "appliesToKey": { - "description": "Every key from this list will be normalized", - "type": "array", - "items": { - "type": "string" - } - }, - "eraseInvalidValues": { - "description": "If set, invalid values will be erased in the MC application (but not in OSM of course!)\nBe careful with setting this", - "type": "boolean" - }, - "applicableUnits": { - "description": "The possible denominations", - "type": "array", - "items": { - "$ref": "#/definitions/ApplicableUnitJson" - } - } - }, - "required": [ - "applicableUnits", - "appliesToKey" - ] - }, - "default_6": { - "description": "Configuration for a tilesource config", - "type": "object", - "properties": { - "id": { - "description": "Id of this overlay, used in the URL-parameters to set the state", - "type": "string" - }, - "source": { - "description": "The path, where {x}, {y} and {z} will be substituted", - "type": "string" - }, - "isOverlay": { - "description": "Wether or not this is an overlay. Default: true", - "type": "boolean" - }, - "name": { - "description": "How this will be shown in the selection menu.\nMake undefined if this may not be toggled" - }, - "minZoom": { - "description": "Only visible at this or a higher zoom level", - "type": "number" - }, - "maxZoom": { - "description": "Only visible at this or a lower zoom level", - "type": "number" - }, - "defaultState": { - "description": "The default state, set to false to hide by default", - "type": "boolean" - } - }, - "required": [ - "defaultState", - "id", - "source" - ] - }, - "LayerConfigJson": { - "description": "Configuration for a single layer", - "type": "object", - "properties": { - "id": { - "description": "The id of this layer.\nThis should be a simple, lowercase, human readable string that is used to identify the layer.", - "type": "string" - }, - "name": { - "description": "The name of this layer\nUsed in the layer control panel and the 'Personal theme'.\n\nIf not given, will be hidden (and thus not toggable) in the layer control" - }, - "description": { - "description": "A description for this layer.\nShown in the layer selections and in the personel theme" - }, - "source": { - "description": "This determines where the data for the layer is fetched: from OSM or from an external geojson dataset.\n\nIf no 'geojson' is defined, data will be fetched from overpass and the OSM-API.\n\nEvery source _must_ define which tags _must_ be present in order to be picked up.", - "anyOf": [ - { - "allOf": [ - { - "type": "object", - "properties": { - "osmTags": { - "description": "Every source must set which tags have to be present in order to load the given layer.", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "maxCacheAge": { - "description": "The maximum amount of seconds that a tile is allowed to linger in the cache", - "type": "number" - } - }, - "required": [ - "osmTags" - ] - }, - { - "type": "object", - "properties": { - "overpassScript": { - "type": "string" - } - } - } - ] - }, - { - "allOf": [ - { - "type": "object", - "properties": { - "osmTags": { - "description": "Every source must set which tags have to be present in order to load the given layer.", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "maxCacheAge": { - "description": "The maximum amount of seconds that a tile is allowed to linger in the cache", - "type": "number" - } - }, - "required": [ - "osmTags" - ] - }, - { - "type": "object", - "properties": { - "geoJson": { - "description": "The actual source of the data to load, if loaded via geojson.\n\n# A single geojson-file\nsource: {geoJson: \"https://my.source.net/some-geo-data.geojson\"}\n fetches a geojson from a third party source\n\n# A tiled geojson source\nsource: {geoJson: \"https://my.source.net/some-tile-geojson-{layer}-{z}-{x}-{y}.geojson\", geoJsonZoomLevel: 14}\n to use a tiled geojson source. The web server must offer multiple geojsons. {z}, {x} and {y} are substituted by the location; {layer} is substituted with the id of the loaded layer\n\nSome API's use a BBOX instead of a tile, this can be used by specifying {y_min}, {y_max}, {x_min} and {x_max}", - "type": "string" - }, - "geoJsonZoomLevel": { - "description": "To load a tiled geojson layer, set the zoomlevel of the tiles", - "type": "number" - }, - "isOsmCache": { - "description": "Indicates that the upstream geojson data is OSM-derived.\nUseful for e.g. merging or for scripts generating this cache", - "type": "boolean" - }, - "mercatorCrs": { - "description": "Some API's use a mercator-projection (EPSG:900913) instead of WGS84. Set the flag `mercatorCrs: true` in the source for this", - "type": "boolean" - }, - "idKey": { - "description": "Some API's have an id-field, but give it a different name.\nSetting this key will rename this field into 'id'", - "type": "string" - } - }, - "required": [ - "geoJson" - ] - } - ] - } - ] - }, - "calculatedTags": { - "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\n \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\n\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\n\nIf a tag has to be evaluated strictly, use ':=' instead:\n\n[\n\"_some_key:=some_javascript_expression\"\n]", - "type": "array", - "items": { - "type": "string" - } - }, - "doNotDownload": { - "description": "If set, this layer will not query overpass; but it'll still match the tags above which are by chance returned by other layers.\nWorks well together with 'passAllFeatures', to add decoration", - "type": "boolean" - }, - "isShown": { - "description": "This tag rendering should either be 'yes' or 'no'. If 'no' is returned, then the feature will be hidden from view.\nThis is useful to hide certain features from view.\n\nImportant: hiding features does not work dynamically, but is only calculated when the data is first renders.\nThis implies that it is not possible to hide a feature after a tagging change\n\nThe default value is 'yes'", - "$ref": "#/definitions/TagRenderingConfigJson" - }, - "forceLoad": { - "description": "Advanced option - might be set by the theme compiler\n\nIf true, this data will _always_ be loaded, even if the theme is disabled", - "type": "boolean" - }, - "minzoom": { - "description": "The minimum needed zoomlevel required before loading of the data start\nDefault: 0", - "type": "number" - }, - "shownByDefault": { - "description": "Indicates if this layer is shown by default;\ncan be used to hide a layer from start, or to load the layer but only to show it where appropriate (e.g. for snapping to it)", - "type": "boolean" - }, - "minzoomVisible": { - "description": "The zoom level at which point the data is hidden again\nDefault: 100 (thus: always visible", - "type": "number" }, "title": { - "description": "The title shown in a popup for elements of this layer.", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] + "description": "The title, as shown in the welcome message and the more-screen." }, - "titleIcons": { - "description": "Small icons shown next to the title.\nIf not specified, the OsmLink and wikipedia links will be used by default.\nUse an empty array to hide them.\nNote that \"defaults\" will insert all the default titleIcons (which are added automatically)\n\nType: icon[]", - "anyOf": [ - { - "type": "array", - "items": { + "shortDescription": { + "description": "A short description, showed as social description and in the 'more theme'-buttons.\nNote that if this one is not defined, the first sentence of 'description' is used" + }, + "description": { + "description": "The description, as shown in the welcome message and the more-screen" + }, + "descriptionTail": { + "description": "A part of the description, shown under the login-button." + }, + "icon": { + "description": "The icon representing this theme.\nUsed as logo in the more-screen and (for official themes) as favicon, webmanifest logo, ...\nEither a URL or a base64 encoded value (which should include 'data:image/svg+xml;base64)\n\nType: icon", + "type": "string" + }, + "socialImage": { + "description": "Link to a 'social image' which is included as og:image-tag on official themes.\nUseful to share the theme on social media.\nSee https://www.h3xed.com/web-and-internet/how-to-use-og-image-meta-tag-facebook-reddit for more information$\n\nType: image", + "type": "string" + }, + "startZoom": { + "description": "Default location and zoom to start.\nNote that this is barely used. Once the user has visited mapcomplete at least once, the previous location of the user will be used", + "type": "number" + }, + "startLat": { + "type": "number" + }, + "startLon": { + "type": "number" + }, + "widenFactor": { + "description": "When a query is run, the data within bounds of the visible map is loaded.\nHowever, users tend to pan and zoom a lot. It is pretty annoying if every single pan means a reloading of the data.\nFor this, the bounds are widened in order to make a small pan still within bounds of the loaded data.\n\nIF widenfactor is 1, this feature is disabled. A recommended value is between 1 and 3", + "type": "number" + }, + "overpassMaxZoom": { + "description": "At low zoom levels, overpass is used to query features.\nAt high zoom level, the OSM api is used to fetch one or more BBOX aligning with a slippy tile.\nThe overpassMaxZoom controls the flipoverpoint: if the zoom is this or lower, overpass is used.", + "type": "number" + }, + "osmApiTileSize": { + "description": "When the OSM-api is used to fetch features, it does so in a tiled fashion.\nThese tiles are using a ceratin zoom level, that can be controlled here\nDefault: overpassMaxZoom + 1", + "type": "number" + }, + "overrideAll": { + "description": "An override applied on all layers of the theme.\n\nE.g.: if there are two layers defined:\n```\n\"layers\":[\n {\"title\": ..., \"tagRenderings\": [...], \"osmSource\":{\"tags\": ...}},\n {\"title\", ..., \"tagRenderings\", [...], \"osmSource\":{\"tags\" ...}}\n]\n```\n\nand overrideAll is specified:\n```\n\"overrideAll\": {\n \"osmSource\":{\"geoJsonSource\":\"xyz\"}\n}\nthen the result will be that all the layers will have these properties applied and result in:\n\"layers\":[\n {\"title\": ..., \"tagRenderings\": [...], \"osmSource\":{\"tags\": ..., \"geoJsonSource\":\"xyz\"}},\n {\"title\", ..., \"tagRenderings\", [...], \"osmSource\":{\"tags\" ..., \"geoJsonSource\":\"xyz\"}}\n]\n```\n\nIf 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\n\n\"overrideAll\": {\n \"+tagRenderings\": [ { ... some tagrendering ... }]\n}\n\nIn the above scenario, `sometagrendering` will be added at the beginning of the tagrenderings of every layer" + }, + "defaultBackgroundId": { + "description": "The id of the default background. BY default: vanilla OSM", + "type": "string" + }, + "tileLayerSources": { + "description": "Define some (overlay) slippy map tilesources", + "type": "array", + "items": { + "$ref": "#/definitions/default_6" + } + }, + "layers": { + "description": "The layers to display.\n\nEvery layer contains a description of which feature to display - the overpassTags which are queried.\nInstead of running one query for every layer, the query is fused.\n\nAfterwards, every layer is given the list of features.\nEvery layer takes away the features that match with them*, and give the leftovers to the next layers.\n\nThis implies that the _order_ of the layers is important in the case of features with the same tags;\nas the later layers might never receive their feature.\n\n*layers can also remove 'leftover'-features if the leftovers overlap with a feature in the layer itself\n\nNote that builtin layers can be reused. Either put in the name of the layer to reuse, or use {builtin: \"layername\", override: ...}\n\nThe 'override'-object will be copied over the original values of the layer, which allows to change certain aspects of the layer\n\nFor 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:\n\n```\n\"layer\": {\n \"builtin\": \"nature_reserve\",\n \"override\": {\"source\": \n {\"osmTags\": {\n \"+and\":[\"operator=Natuurpunt\"]\n }\n }\n }\n}\n```\n\nIt'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:\n\n```\n\"layer\": {\n \"builtin\": [\"benches\", \"drinking_water\"],\n \"override\": {\"minzoom\": 12}\n}\n```", + "type": "array", + "items": { "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } + { + "$ref": "#/definitions/LayerConfigJson" + }, + { + "type": "object", + "properties": { + "builtin": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "string" + } + ] + }, + "override": {}, + "hideTagRenderingsWithLabels": { + "description": "TagRenderings with any of these labels will be removed from the layer.\nNote that the 'id' and 'group' are considered labels too", + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "builtin", + "override" + ] + }, + { + "type": "string" + } ] - } - }, - { - "type": "array", - "items": [ + } + }, + "clustering": { + "description": "If defined, data will be clustered.\nDefaults to {maxZoom: 16, minNeeded: 500}", + "anyOf": [ { - "type": "string", - "enum": [ - "defaults" - ] - } - ], - "minItems": 1, - "maxItems": 1 - } - ] - }, - "mapRendering": { - "description": "Visualisation of the items on the map", - "anyOf": [ - { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/default_4" - }, - { - "$ref": "#/definitions/default_5" - } - ] - } - }, - { - "type": "null" - } - ] - }, - "passAllFeatures": { - "description": "If set, this layer will pass all the features it receives onto the next layer.\nThis is ideal for decoration, e.g. directionss on cameras", - "type": "boolean" - }, - "presets": { - "description": "Presets for this layer.\nA preset shows up when clicking the map on a without data (or when right-clicking/long-pressing);\nit will prompt the user to add a new point.\n\nThe most important aspect are the tags, which define which tags the new point will have;\nThe title is shown in the dialog, along with the first sentence of the description.\n\nUpon confirmation, the full description is shown beneath the buttons - perfect to add pictures and examples.\n\nNote: the icon of the preset is determined automatically based on the tags and the icon above. Don't worry about that!\nNB: if no presets are defined, the popup to add new points doesn't show up at all", - "type": "array", - "items": { - "type": "object", - "properties": { - "title": { - "description": "The title - shown on the 'add-new'-button." - }, - "tags": { - "description": "The tags to add. It determines the icon too", - "type": "array", - "items": { - "type": "string" - } - }, - "description": { - "description": "The _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)" - }, - "exampleImages": { - "description": "Example images, which show real-life pictures of what such a feature might look like\n\nType: image", - "type": "array", - "items": { - "type": "string" - } - }, - "preciseInput": { - "description": "If set, the user will prompted to confirm the location before actually adding the data.\nThis will be with a 'drag crosshair'-method.\n\nIf 'preferredBackgroundCategory' is set, the element will attempt to pick a background layer of that category.", - "anyOf": [ - { "type": "object", "properties": { - "preferredBackground": { - "description": "The type of background picture", - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "string" - } - ] - }, - "snapToLayer": { - "description": "If specified, these layers will be shown to and the new point will be snapped towards it", - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "string" - } - ] - }, - "maxSnapDistance": { - "description": "If specified, a new point will only be snapped if it is within this range.\nDistance in meter\n\nDefault: 10", - "type": "number" - } - }, - "required": [ - "preferredBackground" - ] - }, - { + "maxZoom": { + "description": "All zoom levels above 'maxzoom' are not clustered anymore.\nDefaults to 18", + "type": "number" + }, + "minNeededElements": { + "description": "The number of elements per tile needed to start clustering\nIf clustering is defined, defaults to 250", + "type": "number" + } + } + }, + { "enum": [ - true + false ], "type": "boolean" - } - ] - } + } + ] + }, + "customCss": { + "description": "The URL of a custom CSS stylesheet to modify the layout", + "type": "string" + }, + "hideFromOverview": { + "description": "If set to true, this layout will not be shown in the overview with more themes", + "type": "boolean" + }, + "lockLocation": { + "description": "If set to true, the basemap will not scroll outside of the area visible on initial zoom.\nIf set to [[lon, lat], [lon, lat]], the map will not scroll outside of those bounds.\nOff by default, which will enable panning to the entire world", + "anyOf": [ + { + "type": "array", + "items": [ + { + "type": "array", + "items": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "minItems": 2, + "maxItems": 2 + }, + { + "type": "array", + "items": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "minItems": 2, + "maxItems": 2 + } + ], + "minItems": 2, + "maxItems": 2 + }, + { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "number" + } + } + } + ] + }, + "extraLink": { + "description": "Adds an additional button on the top-left of the application.\nThis can link to an arbitrary location.\n\nNote that {lat},{lon},{zoom}, {language} and {theme} will be replaced\n\nDefault: {icon: \"./assets/svg/pop-out.svg\", href: 'https://mapcomplete.osm.be/{theme}.html?lat={lat}&lon={lon}&z={zoom}, requirements: [\"iframe\",\"no-welcome-message]},", + "$ref": "#/definitions/default" + }, + "enableUserBadge": { + "description": "If set to false, disables logging in.\nThe userbadge will be hidden, all login-buttons will be hidden and editing will be disabled", + "type": "boolean" + }, + "enableShareScreen": { + "description": "If false, hides the tab 'share'-tab in the welcomeMessage", + "type": "boolean" + }, + "enableMoreQuests": { + "description": "Hides the tab with more themes in the welcomeMessage", + "type": "boolean" + }, + "enableLayers": { + "description": "If false, the layer selection/filter view will be hidden\nThe corresponding URL-parameter is 'fs-filters' instead of 'fs-layers'", + "type": "boolean" + }, + "enableSearch": { + "description": "If set to false, hides the search bar", + "type": "boolean" + }, + "enableAddNewPoints": { + "description": "If set to false, the ability to add new points or nodes will be disabled.\nEditing already existing features will still be possible", + "type": "boolean" + }, + "enableGeolocation": { + "description": "If set to false, the 'geolocation'-button will be hidden.", + "type": "boolean" + }, + "enableBackgroundLayerSelection": { + "description": "Enable switching the backgroundlayer.\nIf false, the quickswitch-buttons are removed (bottom left) and the dropdown in the layer selection is removed as well", + "type": "boolean" + }, + "enableShowAllQuestions": { + "description": "If set to true, will show _all_ unanswered questions in a popup instead of just the next one", + "type": "boolean" + }, + "enableDownload": { + "description": "If set to true, download button for the data will be shown (offers downloading as geojson and csv)", + "type": "boolean" + }, + "enablePdfDownload": { + "description": "If set to true, exporting a pdf is enabled", + "type": "boolean" + }, + "enableNoteImports": { + "description": "If true, notes will be loaded and parsed. If a note is an import (as created by the import_helper.html-tool from mapcomplete),\nthese notes will be shown if a relevant layer is present.", + "type": "boolean" + }, + "overpassUrl": { + "description": "Set one or more overpass URLs to use for this theme..", + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "string" + } + ] + }, + "overpassTimeout": { + "description": "Set a different timeout for overpass queries - in seconds. Default: 30s", + "type": "number" + } + }, + "required": [ + "description", + "icon", + "id", + "layers", + "maintainer", + "startLat", + "startLon", + "startZoom", + "title", + "version" + ], + "definitions": { + "AndOrTagConfigJson": { + "type": "object", + "properties": { + "and": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "or": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + } + } + }, + "ApplicableUnitJson": { + "type": "object", + "properties": { + "canonicalDenomination": { + "description": "The canonical value which will be added to the text.\ne.g. \"m\" for meters\nIf the user inputs '42', the canonical value will be added and it'll become '42m'", + "type": "string" + }, + "canonicalDenominationSingular": { + "description": "The canonical denomination in the case that the unit is precisely '1'", + "type": "string" + }, + "alternativeDenomination": { + "description": "A list of alternative values which can occur in the OSM database - used for parsing.", + "type": "array", + "items": { + "type": "string" + } + }, + "human": { + "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"meter\",\n \"fr\": \"metre\"\n}" + }, + "humanSingular": { + "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"minute\",\n \"nl\": \"minuut\"x²\n}" + }, + "prefix": { + "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", + "type": "boolean" + }, + "default": { + "description": "The default interpretation - only one can be set.\nIf none is set, the first unit will be considered the default interpretation of a value without a unit", + "type": "boolean" + } }, "required": [ - "tags", - "title" + "canonicalDenomination" ] - } }, - "tagRenderings": { - "description": "All the tag renderings.\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together", - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/QuestionableTagRenderingConfigJson" - }, - { - "type": "object", - "properties": { - "builtin": { + "TagRenderingConfigJson": { + "description": "A TagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nFor an _editable_ tagRenerdering, use 'QuestionableTagRenderingConfigJson' instead, which extends this one", + "type": "object", + "properties": { + "id": { + "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", "type": "string" - }, - "override": {} }, - "required": [ - "builtin", - "override" - ] - }, - { - "$ref": "#/definitions/default<(string|QuestionableTagRenderingConfigJson|{builtin:string;override:any;})[]>" - }, - { - "type": "string" - } - ] - } - }, - "filter": { - "description": "All the extra questions for filtering", - "anyOf": [ - { - "type": "array", - "items": { - "$ref": "#/definitions/default_1" - } - }, - { - "type": "object", - "properties": { - "sameAs": { - "type": "string" + "group": { + "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", + "type": "string" + }, + "labels": { + "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", + "type": "array", + "items": { + "type": "string" + } + }, + "render": { + "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" + }, + "condition": { + "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "freeform": { + "description": "Allow freeform text input from the user", + "type": "object", + "properties": { + "key": { + "description": "If this key is present, then 'render' is used to display the value.\nIf this is undefined, the rendering is _always_ shown", + "type": "string" + } + }, + "required": [ + "key" + ] + }, + "mappings": { + "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", + "type": "array", + "items": { + "type": "object", + "properties": { + "if": { + "description": "If this condition is met, then the text under `then` will be shown.\nIf no value matches, and the user selects this mapping as an option, then these tags will be uploaded to OSM.\n\nFor example: {'if': 'diet:vegetarion=yes', 'then':'A vegetarian option is offered here'}\n\nThis can be an substituting-tag as well, e.g. {'if': 'addr:street:={_calculated_nearby_streetname}', 'then': '{_calculated_nearby_streetname}'}", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "then": { + "description": "If the condition `if` is met, the text `then` will be rendered.\nIf not known yet, the user will be presented with `then` as an option\nType: rendered" + }, + "icon": { + "description": "An icon supporting this mapping; typically shown pretty small\nType: icon", + "anyOf": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", + "type": "string" + } + }, + "required": [ + "class", + "path" + ] + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "if", + "then" + ] + } } - }, - "required": [ - "sameAs" - ] } - ] }, - "deletion": { - "description": "This block defines under what circumstances the delete dialog is shown for objects of this layer.\nIf set, a dialog is shown to the user to (soft) delete the point.\nThe dialog is built to be user friendly and to prevent mistakes.\nIf deletion is not possible, the dialog will hide itself and show the reason of non-deletability instead.\n\nTo configure, the following values are possible:\n\n- false: never ever show the delete button\n- true: show the default delete button\n- undefined: use the mapcomplete default to show deletion or not. Currently, this is the same as 'false' but this will change in the future\n- or: a hash with options (see below)\n\n The delete dialog\n =================\n\n\n\n#### Hard deletion if enough experience\n\nA feature can only be deleted from OpenStreetMap by mapcomplete if:\n\n- It is a node\n- No ways or relations use the node\n- The logged-in user has enough experience OR the user is the only one to have edited the point previously\n- The logged-in user has no unread messages (or has a ton of experience)\n- The user did not select one of the 'non-delete-options' (see below)\n\nIn all other cases, a 'soft deletion' is used.\n\n#### Soft deletion\n\nA 'soft deletion' is when the point isn't deleted from OSM but retagged so that it'll won't how up in the mapcomplete theme anymore.\nThis makes it look like it was deleted, without doing damage. A fixme will be added to the point.\n\nNote that a soft deletion is _only_ possible if these tags are provided by the theme creator, as they'll be different for every theme\n\n#### No-delete options\n\nIn some cases, the contributor might want to delete something for the wrong reason (e.g. someone who wants to have a path removed \"because the path is on their private property\").\nHowever, the path exists in reality and should thus be on OSM - otherwise the next contributor will pass by and notice \"hey, there is a path missing here! Let me redraw it in OSM!)\n\nThe correct approach is to retag the feature in such a way that it is semantically correct *and* that it doesn't show up on the theme anymore.\nA no-delete option is offered as 'reason to delete it', but secretly retags.", - "anyOf": [ - { - "$ref": "#/definitions/DeleteConfigJson" + "T": { + "type": "object" + }, + "default_4": { + "description": "The PointRenderingConfig gives all details onto how to render a single point of a feature.\n\nThis can be used if:\n\n- The feature is a point\n- To render something at the centroid of an area, or at the start, end or projected centroid of a way", + "type": "object", + "properties": { + "location": { + "description": "All the locations that this point should be rendered at.\nUsing `location: [\"point\", \"centroid\"] will always render centerpoint", + "type": "array", + "items": { + "type": "string" + } + }, + "icon": { + "description": "The icon for an element.\nNote that this also doubles as the icon for this layer (rendered with the overpass-tags) ánd the icon in the presets.\n\nThe result of the icon is rendered as follows:\nthe resulting string is interpreted as a _list_ of items, separated by \";\". The bottommost layer is the first layer.\nAs a result, on could use a generic pin, then overlay it with a specific icon.\nTo make things even more practical, one can use all SVG's from the folder \"assets/svg\" and _substitute the color_ in it.\nE.g. to draw a red pin, use \"pin:#f00\", to have a green circle with your icon on top, use `circle:#0f0;`\n\nType: icon", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "iconBadges": { + "description": "A list of extra badges to show next to the icon as small badge\nThey will be added as a 25% height icon at the bottom right of the icon, with all the badges in a flex layout.\n\nNote: strings are interpreted as icons, so layering and substituting is supported. You can use `circle:white;./my_icon.svg` to add a background circle", + "type": "array", + "items": { + "type": "object", + "properties": { + "if": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "then": { + "description": "Badge to show\nType: icon", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "if", + "then" + ] + } + }, + "iconSize": { + "description": "A string containing \"width,height\" or \"width,height,anchorpoint\" where anchorpoint is any of 'center', 'top', 'bottom', 'left', 'right', 'bottomleft','topright', ...\nDefault is '40,40,center'", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "rotation": { + "description": "The rotation of an icon, useful for e.g. directions.\nUsage: as if it were a css property for 'rotate', thus has to end with 'deg', e.g. `90deg`, `{direction}deg`, `calc(90deg - {camera:direction}deg)``", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "label": { + "description": "A HTML-fragment that is shown below the icon, for example:\n
{name}
\n\nIf the icon is undefined, then the label is shown in the center of the feature.\nNote that, if the wayhandling hides the icon then no label is shown as well.", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + } }, - { - "type": "boolean" - } - ] + "required": [ + "location" + ] }, - "allowMove": { - "description": "Indicates if a point can be moved and configures the modalities.\n\nA feature can be moved by MapComplete if:\n\n- It is a point\n- The point is _not_ part of a way or a a relation.\n\nOff by default. Can be enabled by setting this flag or by configuring.", - "anyOf": [ - { - "$ref": "#/definitions/default_3" + "default_5": { + "description": "The LineRenderingConfig gives all details onto how to render a single line of a feature.\n\nThis can be used if:\n\n- The feature is a line\n- The feature is an area", + "type": "object", + "properties": { + "color": { + "description": "The color for way-elements and SVG-elements.\nIf the value starts with \"--\", the style of the body element will be queried for the corresponding variable instead", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "width": { + "description": "The stroke-width for way-elements", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": [ + "string", + "number" + ] + } + ] + }, + "dashArray": { + "description": "A dasharray, e.g. \"5 6\"\nThe dasharray defines 'pixels of line, pixels of gap, pixels of line, pixels of gap',\nDefault value: \"\" (empty string == full line)", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "lineCap": { + "description": "The form at the end of a line", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "fill": { + "description": "Wehter or not to fill polygons", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "enum": [ + "no", + "yes" + ], + "type": "string" + } + ] + }, + "fillColor": { + "description": "The color to fill a polygon with.\nIf undefined, this will be slightly more opaque version of the stroke line", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "offset": { + "description": "The number of pixels this line should be moved.\nUse a positive numbe to move to the right, a negative to move to the left (left/right as defined by the drawing direction of the line).\n\nIMPORTANT: MapComplete will already normalize 'key:both:property' and 'key:both' into the corresponding 'key:left' and 'key:right' tagging (same for 'sidewalk=left/right/both' which is rewritten to 'sidewalk:left' and 'sidewalk:right')\nThis simplifies programming. Refer to the CalculatedTags.md-documentation for more details", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "number" + } + ] + } + } + }, + "QuestionableTagRenderingConfigJson": { + "description": "A QuestionableTagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nIf the desired tags are missing and a question is defined, a question will be shown instead.", + "type": "object", + "properties": { + "question": { + "description": "If it turns out that this tagRendering doesn't match _any_ value, then we show this question.\nIf undefined, the question is never asked and this tagrendering is read-only" + }, + "freeform": { + "description": "Allow freeform text input from the user", + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "type": { + "description": "The type of the text-field, e.g. 'string', 'nat', 'float', 'date',...\nSee Docs/SpecialInputElements.md and UI/Input/ValidatedTextField.ts for supported values", + "type": "string" + }, + "placeholder": { + "description": "A (translated) text that is shown (as gray text) within the textfield" + }, + "helperArgs": { + "description": "Extra parameters to initialize the input helper arguments.\nFor semantics, see the 'SpecialInputElements.md'", + "type": "array", + "items": {} + }, + "addExtraTags": { + "description": "If a value is added with the textfield, these extra tag is addded.\nUseful to add a 'fixme=freeform textfield used - to be checked'", + "type": "array", + "items": { + "type": "string" + } + }, + "inline": { + "description": "When set, influences the way a question is asked.\nInstead of showing a full-widht text field, the text field will be shown within the rendering of the question.\n\nThis combines badly with special input elements, as it'll distort the layout.", + "type": "boolean" + }, + "default": { + "description": "default value to enter if no previous tagging is present.\nNormally undefined (aka do not enter anything)", + "type": "string" + } + }, + "required": [ + "key" + ] + }, + "multiAnswer": { + "description": "If true, use checkboxes instead of radio buttons when asking the question", + "type": "boolean" + }, + "mappings": { + "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", + "type": "array", + "items": { + "type": "object", + "properties": { + "if": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "then": { + "description": "Shown if the 'if is fulfilled\nType: rendered" + }, + "icon": { + "description": "An extra icon supporting the choice\nType: icon", + "anyOf": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "Size of the image", + "type": "string" + } + }, + "required": [ + "class", + "path" + ] + }, + { + "type": "string" + } + ] + }, + "hideInAnswer": { + "description": "In some cases, multiple taggings exist (e.g. a default assumption, or a commonly mapped abbreviation and a fully written variation).\n\nIn the latter case, a correct text should be shown, but only a single, canonical tagging should be selectable by the user.\nIn this case, one of the mappings can be hiden by setting this flag.\n\nTo demonstrate an example making a default assumption:\n\nmappings: [\n {\n if: \"access=\", -- no access tag present, we assume accessible\n then: \"Accessible to the general public\",\n hideInAnswer: true\n },\n {\n if: \"access=yes\",\n then: \"Accessible to the general public\", -- the user selected this, we add that to OSM\n },\n {\n if: \"access=no\",\n then: \"Not accessible to the public\"\n }\n]\n\n\nFor example, for an operator, we have `operator=Agentschap Natuur en Bos`, which is often abbreviated to `operator=ANB`.\nThen, we would add two mappings:\n{\n if: \"operator=Agentschap Natuur en Bos\" -- the non-abbreviated version which should be uploaded\n then: \"Maintained by Agentschap Natuur en Bos\"\n},\n{\n if: \"operator=ANB\", -- we don't want to upload abbreviations\n then: \"Maintained by Agentschap Natuur en Bos\"\n hideInAnswer: true\n}\n\nHide in answer can also be a tagsfilter, e.g. to make sure an option is only shown when appropriate.\nKeep in mind that this is reverse logic: it will be hidden in the answer if the condition is true, it will thus only show in the case of a mismatch\n\ne.g., for toilets: if \"wheelchair=no\", we know there is no wheelchair dedicated room.\nFor the location of the changing table, the option \"in the wheelchair accessible toilet is weird\", so we write:\n\n{\n \"question\": \"Where is the changing table located?\"\n \"mappings\": [\n {\"if\":\"changing_table:location=female\",\"then\":\"In the female restroom\"},\n {\"if\":\"changing_table:location=male\",\"then\":\"In the male restroom\"},\n {\"if\":\"changing_table:location=wheelchair\",\"then\":\"In the wheelchair accessible restroom\", \"hideInAnswer\": \"wheelchair=no\"},\n \n ]\n}\n\nAlso have a look for the meta-tags\n{\n if: \"operator=Agentschap Natuur en Bos\",\n then: \"Maintained by Agentschap Natuur en Bos\",\n hideInAnswer: \"_country!=be\"\n}", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": [ + "string", + "boolean" + ] + } + ] + }, + "ifnot": { + "description": "Only applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "addExtraTags": { + "description": "If chosen as answer, these tags will be applied as well onto the object.\nNot compatible with multiAnswer", + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "if", + "then" + ] + } + }, + "id": { + "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", + "type": "string" + }, + "group": { + "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", + "type": "string" + }, + "labels": { + "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", + "type": "array", + "items": { + "type": "string" + } + }, + "render": { + "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" + }, + "condition": { + "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + } + }, + "default<(string|QuestionableTagRenderingConfigJson|{builtin:string;override:any;})[]>": { + "type": "object", + "properties": { + "rewrite": { + "type": "object", + "properties": { + "sourceString": { + "type": "array", + "items": { + "type": "string" + } + }, + "into": { + "type": "array", + "items": { + "type": "array", + "items": {} + } + } + }, + "required": [ + "into", + "sourceString" + ] + }, + "renderings": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/QuestionableTagRenderingConfigJson" + }, + { + "type": "object", + "properties": { + "builtin": { + "type": "string" + }, + "override": {} + }, + "required": [ + "builtin", + "override" + ] + }, + { + "type": "string" + } + ] + } + } }, - { - "type": "boolean" + "required": [ + "renderings", + "rewrite" + ] + }, + "default_1": { + "type": "object", + "properties": { + "id": { + "description": "An id/name for this filter, used to set the URL parameters", + "type": "string" + }, + "options": { + "description": "The options for a filter\nIf there are multiple options these will be a list of radio buttons\nIf there is only one option this will be a checkbox\nFiltering is done based on the given osmTags that are compared to the objects in that layer.", + "type": "array", + "items": { + "type": "object", + "properties": { + "question": {}, + "osmTags": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "default": { + "type": "boolean" + }, + "fields": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "name" + ] + } + } + }, + "required": [ + "question" + ] + } + } + }, + "required": [ + "id", + "options" + ] + }, + "DeleteConfigJson": { + "type": "object", + "properties": { + "extraDeleteReasons": { + "description": "*\nBy default, three reasons to delete a point are shown:\n\n- The point does not exist anymore\n- The point was a testing point\n- THe point could not be found\n\nHowever, for some layers, there might be different or more specific reasons for deletion which can be user friendly to set, e.g.:\n\n- the shop has closed\n- the climbing route has been closed of for nature conservation reasons\n- ...\n\nThese reasons can be stated here and will be shown in the list of options the user can choose from", + "type": "array", + "items": { + "type": "object", + "properties": { + "explanation": { + "description": "The text that will be shown to the user - translatable" + }, + "changesetMessage": { + "description": "The text that will be uploaded into the changeset or will be used in the fixme in case of a soft deletion\nShould be a few words, in english", + "type": "string" + } + }, + "required": [ + "changesetMessage", + "explanation" + ] + } + }, + "nonDeleteMappings": { + "description": "In some cases, a (starting) contributor might wish to delete a feature even though deletion is not appropriate.\n(The most relevant case are small paths running over private property. These should be marked as 'private' instead of deleted, as the community might trace the path again from aerial imagery, gettting us back to the original situation).\n\nBy adding a 'nonDeleteMapping', an option can be added into the list which will retag the feature.\nIt is important that the feature will be retagged in such a way that it won't be picked up by the layer anymore!", + "type": "array", + "items": { + "type": "object", + "properties": { + "if": { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + "then": {} + }, + "required": [ + "if", + "then" + ] + } + }, + "softDeletionTags": { + "description": "In some cases, the contributor is not allowed to delete the current feature (e.g. because it isn't a point, the point is referenced by a relation or the user isn't experienced enough).\nTo still offer the user a 'delete'-option, the feature is retagged with these tags. This is a soft deletion, as the point isn't actually removed from OSM but rather marked as 'disused'\nIt is important that the feature will be retagged in such a way that it won't be picked up by the layer anymore!\n\nExample (note that \"amenity=\" erases the 'amenity'-key alltogether):\n```\n{\n \"and\": [\"disussed:amenity=public_bookcase\", \"amenity=\"]\n}\n```\n\nor (notice the use of the ':='-tag to copy the old value of 'shop=*' into 'disused:shop='):\n```\n{\n \"and\": [\"disused:shop:={shop}\", \"shop=\"]\n}\n```", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "neededChangesets": { + "description": "*\nBy default, the contributor needs 20 previous changesets to delete points edited by others.\nFor some small features (e.g. bicycle racks) this is too much and this requirement can be lowered or dropped, which can be done here.", + "type": "number" + } } - ] }, - "allowSplit": { - "description": "IF set, a 'split this road' button is shown", - "type": "boolean" + "default_3": { + "type": "object", + "properties": { + "enableImproveAccuracy": { + "description": "One default reason to move a point is to improve accuracy.\nSet to false to disable this reason", + "type": "boolean" + }, + "enableRelocation": { + "description": "One default reason to move a point is because it has relocated\nSet to false to disable this reason", + "type": "boolean" + } + } }, - "units": { - "description": "In some cases, a value is represented in a certain unit (such as meters for heigt/distance/..., km/h for speed, ...)\n\nSometimes, multiple denominations are possible (e.g. km/h vs mile/h; megawatt vs kilowatt vs gigawatt for power generators, ...)\n\nThis brings in some troubles, as there are multiple ways to write it (no denomitation, 'm' vs 'meter' 'metre', ...)\n\nNot only do we want to write consistent data to OSM, we also want to present this consistently to the user.\nThis is handled by defining units.\n\n# Rendering\n\nTo render a value with long (human) denomination, use {canonical(key)}\n\n# Usage\n\nFirst of all, you define which keys have units applied, for example:\n\n```\nunits: [\n appliesTo: [\"maxspeed\", \"maxspeed:hgv\", \"maxspeed:bus\"]\n applicableUnits: [\n ...\n ]\n]\n```\n\nApplicableUnits defines which is the canonical extension, how it is presented to the user, ...:\n\n```\napplicableUnits: [\n{\n canonicalDenomination: \"km/h\",\n alternativeDenomination: [\"km/u\", \"kmh\", \"kph\"]\n default: true,\n human: {\n en: \"kilometer/hour\",\n nl: \"kilometer/uur\"\n },\n humanShort: {\n en: \"km/h\",\n nl: \"km/u\"\n }\n},\n{\n canoncialDenomination: \"mph\",\n ... similar for miles an hour ...\n}\n]\n```\n\n\nIf this is defined, then every key which the denominations apply to (`maxspeed`, `maxspeed:hgv` and `maxspeed:bus`) will be rewritten at the metatagging stage:\nevery value will be parsed and the canonical extension will be added add presented to the other parts of the code.\n\nAlso, if a freeform text field is used, an extra dropdown with applicable denominations will be given", - "type": "array", - "items": { - "$ref": "#/definitions/default_2" - } + "default_2": { + "type": "object", + "properties": { + "appliesToKey": { + "description": "Every key from this list will be normalized", + "type": "array", + "items": { + "type": "string" + } + }, + "eraseInvalidValues": { + "description": "If set, invalid values will be erased in the MC application (but not in OSM of course!)\nBe careful with setting this", + "type": "boolean" + }, + "applicableUnits": { + "description": "The possible denominations", + "type": "array", + "items": { + "$ref": "#/definitions/ApplicableUnitJson" + } + } + }, + "required": [ + "applicableUnits", + "appliesToKey" + ] }, - "syncSelection": { - "description": "If set, synchronizes wether or not this layer is selected.\n\nno: Do not sync at all, always revert to default\nlocal: keep selection on local storage\ntheme-only: sync via OSM, but this layer will only be toggled in this theme\nglobal: all layers with this ID will be synced accross all themes", - "enum": [ - "global", - "local", - "no", - "theme-only" - ], - "type": "string" + "default_6": { + "description": "Configuration for a tilesource config", + "type": "object", + "properties": { + "id": { + "description": "Id of this overlay, used in the URL-parameters to set the state", + "type": "string" + }, + "source": { + "description": "The path, where {x}, {y} and {z} will be substituted", + "type": "string" + }, + "isOverlay": { + "description": "Wether or not this is an overlay. Default: true", + "type": "boolean" + }, + "name": { + "description": "How this will be shown in the selection menu.\nMake undefined if this may not be toggled" + }, + "minZoom": { + "description": "Only visible at this or a higher zoom level", + "type": "number" + }, + "maxZoom": { + "description": "Only visible at this or a lower zoom level", + "type": "number" + }, + "defaultState": { + "description": "The default state, set to false to hide by default", + "type": "boolean" + } + }, + "required": [ + "defaultState", + "id", + "source" + ] + }, + "LayerConfigJson": { + "description": "Configuration for a single layer", + "type": "object", + "properties": { + "id": { + "description": "The id of this layer.\nThis should be a simple, lowercase, human readable string that is used to identify the layer.", + "type": "string" + }, + "name": { + "description": "The name of this layer\nUsed in the layer control panel and the 'Personal theme'.\n\nIf not given, will be hidden (and thus not toggable) in the layer control" + }, + "description": { + "description": "A description for this layer.\nShown in the layer selections and in the personel theme" + }, + "source": { + "description": "This determines where the data for the layer is fetched: from OSM or from an external geojson dataset.\n\nIf no 'geojson' is defined, data will be fetched from overpass and the OSM-API.\n\nEvery source _must_ define which tags _must_ be present in order to be picked up.", + "anyOf": [ + { + "allOf": [ + { + "type": "object", + "properties": { + "osmTags": { + "description": "Every source must set which tags have to be present in order to load the given layer.", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "maxCacheAge": { + "description": "The maximum amount of seconds that a tile is allowed to linger in the cache", + "type": "number" + } + }, + "required": [ + "osmTags" + ] + }, + { + "type": "object", + "properties": { + "overpassScript": { + "type": "string" + } + } + } + ] + }, + { + "allOf": [ + { + "type": "object", + "properties": { + "osmTags": { + "description": "Every source must set which tags have to be present in order to load the given layer.", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "maxCacheAge": { + "description": "The maximum amount of seconds that a tile is allowed to linger in the cache", + "type": "number" + } + }, + "required": [ + "osmTags" + ] + }, + { + "type": "object", + "properties": { + "geoJson": { + "description": "The actual source of the data to load, if loaded via geojson.\n\n# A single geojson-file\nsource: {geoJson: \"https://my.source.net/some-geo-data.geojson\"}\n fetches a geojson from a third party source\n\n# A tiled geojson source\nsource: {geoJson: \"https://my.source.net/some-tile-geojson-{layer}-{z}-{x}-{y}.geojson\", geoJsonZoomLevel: 14}\n to use a tiled geojson source. The web server must offer multiple geojsons. {z}, {x} and {y} are substituted by the location; {layer} is substituted with the id of the loaded layer\n\nSome API's use a BBOX instead of a tile, this can be used by specifying {y_min}, {y_max}, {x_min} and {x_max}", + "type": "string" + }, + "geoJsonZoomLevel": { + "description": "To load a tiled geojson layer, set the zoomlevel of the tiles", + "type": "number" + }, + "isOsmCache": { + "description": "Indicates that the upstream geojson data is OSM-derived.\nUseful for e.g. merging or for scripts generating this cache", + "type": "boolean" + }, + "mercatorCrs": { + "description": "Some API's use a mercator-projection (EPSG:900913) instead of WGS84. Set the flag `mercatorCrs: true` in the source for this", + "type": "boolean" + }, + "idKey": { + "description": "Some API's have an id-field, but give it a different name.\nSetting this key will rename this field into 'id'", + "type": "string" + } + }, + "required": [ + "geoJson" + ] + } + ] + } + ] + }, + "calculatedTags": { + "description": "A list of extra tags to calculate, specified as \"keyToAssignTo=javascript-expression\".\nThere are a few extra functions available. Refer to Docs/CalculatedTags.md for more information\nThe functions will be run in order, e.g.\n[\n \"_max_overlap_m2=Math.max(...feat.overlapsWith(\"someOtherLayer\").map(o => o.overlap))\n \"_max_overlap_ratio=Number(feat._max_overlap_m2)/feat.area\n]\n\nThe specified tags are evaluated lazily. E.g. if a calculated tag is only used in the popup (e.g. the number of nearby features),\nthe expensive calculation will only be performed then for that feature. This avoids clogging up the contributors PC when all features are loaded.\n\nIf a tag has to be evaluated strictly, use ':=' instead:\n\n[\n\"_some_key:=some_javascript_expression\"\n]", + "type": "array", + "items": { + "type": "string" + } + }, + "doNotDownload": { + "description": "If set, this layer will not query overpass; but it'll still match the tags above which are by chance returned by other layers.\nWorks well together with 'passAllFeatures', to add decoration", + "type": "boolean" + }, + "isShown": { + "description": "This tag rendering should either be 'yes' or 'no'. If 'no' is returned, then the feature will be hidden from view.\nThis is useful to hide certain features from view.\n\nImportant: hiding features does not work dynamically, but is only calculated when the data is first renders.\nThis implies that it is not possible to hide a feature after a tagging change\n\nThe default value is 'yes'", + "$ref": "#/definitions/TagRenderingConfigJson" + }, + "forceLoad": { + "description": "Advanced option - might be set by the theme compiler\n\nIf true, this data will _always_ be loaded, even if the theme is disabled", + "type": "boolean" + }, + "minzoom": { + "description": "The minimum needed zoomlevel required before loading of the data start\nDefault: 0", + "type": "number" + }, + "shownByDefault": { + "description": "Indicates if this layer is shown by default;\ncan be used to hide a layer from start, or to load the layer but only to show it where appropriate (e.g. for snapping to it)", + "type": "boolean" + }, + "minzoomVisible": { + "description": "The zoom level at which point the data is hidden again\nDefault: 100 (thus: always visible", + "type": "number" + }, + "title": { + "description": "The title shown in a popup for elements of this layer.", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "titleIcons": { + "description": "Small icons shown next to the title.\nIf not specified, the OsmLink and wikipedia links will be used by default.\nUse an empty array to hide them.\nNote that \"defaults\" will insert all the default titleIcons (which are added automatically)\n\nType: icon[]", + "anyOf": [ + { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + } + }, + { + "type": "array", + "items": [ + { + "type": "string", + "enum": [ + "defaults" + ] + } + ], + "minItems": 1, + "maxItems": 1 + } + ] + }, + "mapRendering": { + "description": "Visualisation of the items on the map", + "anyOf": [ + { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/default_4" + }, + { + "$ref": "#/definitions/default_5" + } + ] + } + }, + { + "type": "null" + } + ] + }, + "passAllFeatures": { + "description": "If set, this layer will pass all the features it receives onto the next layer.\nThis is ideal for decoration, e.g. directionss on cameras", + "type": "boolean" + }, + "presets": { + "description": "Presets for this layer.\nA preset shows up when clicking the map on a without data (or when right-clicking/long-pressing);\nit will prompt the user to add a new point.\n\nThe most important aspect are the tags, which define which tags the new point will have;\nThe title is shown in the dialog, along with the first sentence of the description.\n\nUpon confirmation, the full description is shown beneath the buttons - perfect to add pictures and examples.\n\nNote: the icon of the preset is determined automatically based on the tags and the icon above. Don't worry about that!\nNB: if no presets are defined, the popup to add new points doesn't show up at all", + "type": "array", + "items": { + "type": "object", + "properties": { + "title": { + "description": "The title - shown on the 'add-new'-button." + }, + "tags": { + "description": "The tags to add. It determines the icon too", + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "description": "The _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)" + }, + "exampleImages": { + "description": "Example images, which show real-life pictures of what such a feature might look like\n\nType: image", + "type": "array", + "items": { + "type": "string" + } + }, + "preciseInput": { + "description": "If set, the user will prompted to confirm the location before actually adding the data.\nThis will be with a 'drag crosshair'-method.\n\nIf 'preferredBackgroundCategory' is set, the element will attempt to pick a background layer of that category.", + "anyOf": [ + { + "type": "object", + "properties": { + "preferredBackground": { + "description": "The type of background picture", + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "string" + } + ] + }, + "snapToLayer": { + "description": "If specified, these layers will be shown to and the new point will be snapped towards it", + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "string" + } + ] + }, + "maxSnapDistance": { + "description": "If specified, a new point will only be snapped if it is within this range.\nDistance in meter\n\nDefault: 10", + "type": "number" + } + }, + "required": [ + "preferredBackground" + ] + }, + { + "enum": [ + true + ], + "type": "boolean" + } + ] + } + }, + "required": [ + "tags", + "title" + ] + } + }, + "tagRenderings": { + "description": "All the tag renderings.\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together", + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/QuestionableTagRenderingConfigJson" + }, + { + "type": "object", + "properties": { + "builtin": { + "type": "string" + }, + "override": {} + }, + "required": [ + "builtin", + "override" + ] + }, + { + "$ref": "#/definitions/default<(string|QuestionableTagRenderingConfigJson|{builtin:string;override:any;})[]>" + }, + { + "type": "string" + } + ] + } + }, + "filter": { + "description": "All the extra questions for filtering", + "anyOf": [ + { + "type": "array", + "items": { + "$ref": "#/definitions/default_1" + } + }, + { + "type": "object", + "properties": { + "sameAs": { + "type": "string" + } + }, + "required": [ + "sameAs" + ] + } + ] + }, + "deletion": { + "description": "This block defines under what circumstances the delete dialog is shown for objects of this layer.\nIf set, a dialog is shown to the user to (soft) delete the point.\nThe dialog is built to be user friendly and to prevent mistakes.\nIf deletion is not possible, the dialog will hide itself and show the reason of non-deletability instead.\n\nTo configure, the following values are possible:\n\n- false: never ever show the delete button\n- true: show the default delete button\n- undefined: use the mapcomplete default to show deletion or not. Currently, this is the same as 'false' but this will change in the future\n- or: a hash with options (see below)\n\n The delete dialog\n =================\n\n\n\n#### Hard deletion if enough experience\n\nA feature can only be deleted from OpenStreetMap by mapcomplete if:\n\n- It is a node\n- No ways or relations use the node\n- The logged-in user has enough experience OR the user is the only one to have edited the point previously\n- The logged-in user has no unread messages (or has a ton of experience)\n- The user did not select one of the 'non-delete-options' (see below)\n\nIn all other cases, a 'soft deletion' is used.\n\n#### Soft deletion\n\nA 'soft deletion' is when the point isn't deleted from OSM but retagged so that it'll won't how up in the mapcomplete theme anymore.\nThis makes it look like it was deleted, without doing damage. A fixme will be added to the point.\n\nNote that a soft deletion is _only_ possible if these tags are provided by the theme creator, as they'll be different for every theme\n\n#### No-delete options\n\nIn some cases, the contributor might want to delete something for the wrong reason (e.g. someone who wants to have a path removed \"because the path is on their private property\").\nHowever, the path exists in reality and should thus be on OSM - otherwise the next contributor will pass by and notice \"hey, there is a path missing here! Let me redraw it in OSM!)\n\nThe correct approach is to retag the feature in such a way that it is semantically correct *and* that it doesn't show up on the theme anymore.\nA no-delete option is offered as 'reason to delete it', but secretly retags.", + "anyOf": [ + { + "$ref": "#/definitions/DeleteConfigJson" + }, + { + "type": "boolean" + } + ] + }, + "allowMove": { + "description": "Indicates if a point can be moved and configures the modalities.\n\nA feature can be moved by MapComplete if:\n\n- It is a point\n- The point is _not_ part of a way or a a relation.\n\nOff by default. Can be enabled by setting this flag or by configuring.", + "anyOf": [ + { + "$ref": "#/definitions/default_3" + }, + { + "type": "boolean" + } + ] + }, + "allowSplit": { + "description": "IF set, a 'split this road' button is shown", + "type": "boolean" + }, + "units": { + "description": "In some cases, a value is represented in a certain unit (such as meters for heigt/distance/..., km/h for speed, ...)\n\nSometimes, multiple denominations are possible (e.g. km/h vs mile/h; megawatt vs kilowatt vs gigawatt for power generators, ...)\n\nThis brings in some troubles, as there are multiple ways to write it (no denomitation, 'm' vs 'meter' 'metre', ...)\n\nNot only do we want to write consistent data to OSM, we also want to present this consistently to the user.\nThis is handled by defining units.\n\n# Rendering\n\nTo render a value with long (human) denomination, use {canonical(key)}\n\n# Usage\n\nFirst of all, you define which keys have units applied, for example:\n\n```\nunits: [\n appliesTo: [\"maxspeed\", \"maxspeed:hgv\", \"maxspeed:bus\"]\n applicableUnits: [\n ...\n ]\n]\n```\n\nApplicableUnits defines which is the canonical extension, how it is presented to the user, ...:\n\n```\napplicableUnits: [\n{\n canonicalDenomination: \"km/h\",\n alternativeDenomination: [\"km/u\", \"kmh\", \"kph\"]\n default: true,\n human: {\n en: \"kilometer/hour\",\n nl: \"kilometer/uur\"\n },\n humanShort: {\n en: \"km/h\",\n nl: \"km/u\"\n }\n},\n{\n canoncialDenomination: \"mph\",\n ... similar for miles an hour ...\n}\n]\n```\n\n\nIf this is defined, then every key which the denominations apply to (`maxspeed`, `maxspeed:hgv` and `maxspeed:bus`) will be rewritten at the metatagging stage:\nevery value will be parsed and the canonical extension will be added add presented to the other parts of the code.\n\nAlso, if a freeform text field is used, an extra dropdown with applicable denominations will be given", + "type": "array", + "items": { + "$ref": "#/definitions/default_2" + } + }, + "syncSelection": { + "description": "If set, synchronizes wether or not this layer is selected.\n\nno: Do not sync at all, always revert to default\nlocal: keep selection on local storage\ntheme-only: sync via OSM, but this layer will only be toggled in this theme\nglobal: all layers with this ID will be synced accross all themes", + "enum": [ + "global", + "local", + "no", + "theme-only" + ], + "type": "string" + } + }, + "required": [ + "id", + "mapRendering", + "source" + ] + }, + "default": { + "type": "object", + "properties": { + "icon": { + "type": "string" + }, + "text": {}, + "href": { + "type": "string" + }, + "newTab": { + "type": "boolean" + }, + "requirements": { + "type": "array", + "items": { + "enum": [ + "iframe", + "no-iframe", + "no-welcome-message", + "welcome-message" + ], + "type": "string" + } + } + }, + "required": [ + "href" + ] } - }, - "required": [ - "id", - "mapRendering", - "source" - ] }, - "default": { - "type": "object", - "properties": { - "icon": { - "type": "string" - }, - "text": {}, - "href": { - "type": "string" - }, - "newTab": { - "type": "boolean" - }, - "requirements": { - "type": "array", - "items": { - "enum": [ - "iframe", - "no-iframe", - "no-welcome-message", - "welcome-message" - ], - "type": "string" - } - } - }, - "required": [ - "href" - ] - } - }, - "$schema": "http://json-schema.org/draft-07/schema#" + "$schema": "http://json-schema.org/draft-07/schema#" } \ No newline at end of file diff --git a/Docs/Schemas/LineRenderingConfigJsonJSC.ts b/Docs/Schemas/LineRenderingConfigJsonJSC.ts index 07e394d907..1c35298ec3 100644 --- a/Docs/Schemas/LineRenderingConfigJsonJSC.ts +++ b/Docs/Schemas/LineRenderingConfigJsonJSC.ts @@ -1,261 +1,261 @@ export default { - "description": "The LineRenderingConfig gives all details onto how to render a single line of a feature.\n\nThis can be used if:\n\n- The feature is a line\n- The feature is an area", - "type": "object", - "properties": { - "color": { - "description": "The color for way-elements and SVG-elements.\nIf the value starts with \"--\", the style of the body element will be queried for the corresponding variable instead", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "width": { - "description": "The stroke-width for way-elements", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": [ - "string", - "number" - ] - } - ] - }, - "dashArray": { - "description": "A dasharray, e.g. \"5 6\"\nThe dasharray defines 'pixels of line, pixels of gap, pixels of line, pixels of gap',\nDefault value: \"\" (empty string == full line)", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "lineCap": { - "description": "The form at the end of a line", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "fill": { - "description": "Wehter or not to fill polygons", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "enum": [ - "no", - "yes" - ], - "type": "string" - } - ] - }, - "fillColor": { - "description": "The color to fill a polygon with.\nIf undefined, this will be slightly more opaque version of the stroke line", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "offset": { - "description": "The number of pixels this line should be moved.\nUse a positive numbe to move to the right, a negative to move to the left (left/right as defined by the drawing direction of the line).\n\nIMPORTANT: MapComplete will already normalize 'key:both:property' and 'key:both' into the corresponding 'key:left' and 'key:right' tagging (same for 'sidewalk=left/right/both' which is rewritten to 'sidewalk:left' and 'sidewalk:right')\nThis simplifies programming. Refer to the CalculatedTags.md-documentation for more details", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "number" - } - ] - } - }, - "definitions": { - "AndOrTagConfigJson": { - "type": "object", - "properties": { - "and": { - "type": "array", - "items": { + "description": "The LineRenderingConfig gives all details onto how to render a single line of a feature.\n\nThis can be used if:\n\n- The feature is a line\n- The feature is an area", + "type": "object", + "properties": { + "color": { + "description": "The color for way-elements and SVG-elements.\nIf the value starts with \"--\", the style of the body element will be queried for the corresponding variable instead", "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } ] - } }, - "or": { - "type": "array", - "items": { + "width": { + "description": "The stroke-width for way-elements", "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": [ + "string", + "number" + ] + } + ] + }, + "dashArray": { + "description": "A dasharray, e.g. \"5 6\"\nThe dasharray defines 'pixels of line, pixels of gap, pixels of line, pixels of gap',\nDefault value: \"\" (empty string == full line)", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "lineCap": { + "description": "The form at the end of a line", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "fill": { + "description": "Wehter or not to fill polygons", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "enum": [ + "no", + "yes" + ], + "type": "string" + } + ] + }, + "fillColor": { + "description": "The color to fill a polygon with.\nIf undefined, this will be slightly more opaque version of the stroke line", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "offset": { + "description": "The number of pixels this line should be moved.\nUse a positive numbe to move to the right, a negative to move to the left (left/right as defined by the drawing direction of the line).\n\nIMPORTANT: MapComplete will already normalize 'key:both:property' and 'key:both' into the corresponding 'key:left' and 'key:right' tagging (same for 'sidewalk=left/right/both' which is rewritten to 'sidewalk:left' and 'sidewalk:right')\nThis simplifies programming. Refer to the CalculatedTags.md-documentation for more details", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "number" + } ] - } } - } }, - "ApplicableUnitJson": { - "type": "object", - "properties": { - "canonicalDenomination": { - "description": "The canonical value which will be added to the text.\ne.g. \"m\" for meters\nIf the user inputs '42', the canonical value will be added and it'll become '42m'", - "type": "string" - }, - "canonicalDenominationSingular": { - "description": "The canonical denomination in the case that the unit is precisely '1'", - "type": "string" - }, - "alternativeDenomination": { - "description": "A list of alternative values which can occur in the OSM database - used for parsing.", - "type": "array", - "items": { - "type": "string" - } - }, - "human": { - "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"meter\",\n \"fr\": \"metre\"\n}" - }, - "humanSingular": { - "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"minute\",\n \"nl\": \"minuut\"x²\n}" - }, - "prefix": { - "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", - "type": "boolean" - }, - "default": { - "description": "The default interpretation - only one can be set.\nIf none is set, the first unit will be considered the default interpretation of a value without a unit", - "type": "boolean" - } - }, - "required": [ - "canonicalDenomination" - ] - }, - "TagRenderingConfigJson": { - "description": "A TagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nFor an _editable_ tagRenerdering, use 'QuestionableTagRenderingConfigJson' instead, which extends this one", - "type": "object", - "properties": { - "id": { - "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", - "type": "string" - }, - "group": { - "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", - "type": "string" - }, - "labels": { - "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", - "type": "array", - "items": { - "type": "string" - } - }, - "render": { - "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" - }, - "condition": { - "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "freeform": { - "description": "Allow freeform text input from the user", - "type": "object", - "properties": { - "key": { - "description": "If this key is present, then 'render' is used to display the value.\nIf this is undefined, the rendering is _always_ shown", - "type": "string" - } - }, - "required": [ - "key" - ] - }, - "mappings": { - "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", - "type": "array", - "items": { + "definitions": { + "AndOrTagConfigJson": { "type": "object", "properties": { - "if": { - "description": "If this condition is met, then the text under `then` will be shown.\nIf no value matches, and the user selects this mapping as an option, then these tags will be uploaded to OSM.\n\nFor example: {'if': 'diet:vegetarion=yes', 'then':'A vegetarian option is offered here'}\n\nThis can be an substituting-tag as well, e.g. {'if': 'addr:street:={_calculated_nearby_streetname}', 'then': '{_calculated_nearby_streetname}'}", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { + "and": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "or": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + } + } + }, + "ApplicableUnitJson": { + "type": "object", + "properties": { + "canonicalDenomination": { + "description": "The canonical value which will be added to the text.\ne.g. \"m\" for meters\nIf the user inputs '42', the canonical value will be added and it'll become '42m'", "type": "string" - } - ] - }, - "then": { - "description": "If the condition `if` is met, the text `then` will be rendered.\nIf not known yet, the user will be presented with `then` as an option\nType: rendered" - }, - "icon": { - "description": "An icon supporting this mapping; typically shown pretty small\nType: icon", - "anyOf": [ - { - "type": "object", - "properties": { - "path": { - "description": "The path to the icon\nType: icon", - "type": "string" - }, - "class": { - "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", - "type": "string" - } - }, - "required": [ - "class", - "path" - ] - }, - { + }, + "canonicalDenominationSingular": { + "description": "The canonical denomination in the case that the unit is precisely '1'", "type": "string" - } - ] - } + }, + "alternativeDenomination": { + "description": "A list of alternative values which can occur in the OSM database - used for parsing.", + "type": "array", + "items": { + "type": "string" + } + }, + "human": { + "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"meter\",\n \"fr\": \"metre\"\n}" + }, + "humanSingular": { + "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"minute\",\n \"nl\": \"minuut\"x²\n}" + }, + "prefix": { + "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", + "type": "boolean" + }, + "default": { + "description": "The default interpretation - only one can be set.\nIf none is set, the first unit will be considered the default interpretation of a value without a unit", + "type": "boolean" + } }, "required": [ - "if", - "then" + "canonicalDenomination" ] - } + }, + "TagRenderingConfigJson": { + "description": "A TagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nFor an _editable_ tagRenerdering, use 'QuestionableTagRenderingConfigJson' instead, which extends this one", + "type": "object", + "properties": { + "id": { + "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", + "type": "string" + }, + "group": { + "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", + "type": "string" + }, + "labels": { + "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", + "type": "array", + "items": { + "type": "string" + } + }, + "render": { + "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" + }, + "condition": { + "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "freeform": { + "description": "Allow freeform text input from the user", + "type": "object", + "properties": { + "key": { + "description": "If this key is present, then 'render' is used to display the value.\nIf this is undefined, the rendering is _always_ shown", + "type": "string" + } + }, + "required": [ + "key" + ] + }, + "mappings": { + "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", + "type": "array", + "items": { + "type": "object", + "properties": { + "if": { + "description": "If this condition is met, then the text under `then` will be shown.\nIf no value matches, and the user selects this mapping as an option, then these tags will be uploaded to OSM.\n\nFor example: {'if': 'diet:vegetarion=yes', 'then':'A vegetarian option is offered here'}\n\nThis can be an substituting-tag as well, e.g. {'if': 'addr:street:={_calculated_nearby_streetname}', 'then': '{_calculated_nearby_streetname}'}", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "then": { + "description": "If the condition `if` is met, the text `then` will be rendered.\nIf not known yet, the user will be presented with `then` as an option\nType: rendered" + }, + "icon": { + "description": "An icon supporting this mapping; typically shown pretty small\nType: icon", + "anyOf": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", + "type": "string" + } + }, + "required": [ + "class", + "path" + ] + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "if", + "then" + ] + } + } + } } - } - } - }, - "$schema": "http://json-schema.org/draft-07/schema#" + }, + "$schema": "http://json-schema.org/draft-07/schema#" } \ No newline at end of file diff --git a/Docs/Schemas/MoveConfigJsonJSC.ts b/Docs/Schemas/MoveConfigJsonJSC.ts index 23f191109b..0d7dede65a 100644 --- a/Docs/Schemas/MoveConfigJsonJSC.ts +++ b/Docs/Schemas/MoveConfigJsonJSC.ts @@ -1,84 +1,84 @@ export default { - "type": "object", - "properties": { - "enableImproveAccuracy": { - "description": "One default reason to move a point is to improve accuracy.\nSet to false to disable this reason", - "type": "boolean" - }, - "enableRelocation": { - "description": "One default reason to move a point is because it has relocated\nSet to false to disable this reason", - "type": "boolean" - } - }, - "definitions": { - "AndOrTagConfigJson": { - "type": "object", - "properties": { - "and": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } + "type": "object", + "properties": { + "enableImproveAccuracy": { + "description": "One default reason to move a point is to improve accuracy.\nSet to false to disable this reason", + "type": "boolean" }, - "or": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } + "enableRelocation": { + "description": "One default reason to move a point is because it has relocated\nSet to false to disable this reason", + "type": "boolean" } - } }, - "ApplicableUnitJson": { - "type": "object", - "properties": { - "canonicalDenomination": { - "description": "The canonical value which will be added to the text.\ne.g. \"m\" for meters\nIf the user inputs '42', the canonical value will be added and it'll become '42m'", - "type": "string" + "definitions": { + "AndOrTagConfigJson": { + "type": "object", + "properties": { + "and": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "or": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + } + } }, - "canonicalDenominationSingular": { - "description": "The canonical denomination in the case that the unit is precisely '1'", - "type": "string" - }, - "alternativeDenomination": { - "description": "A list of alternative values which can occur in the OSM database - used for parsing.", - "type": "array", - "items": { - "type": "string" - } - }, - "human": { - "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"meter\",\n \"fr\": \"metre\"\n}" - }, - "humanSingular": { - "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"minute\",\n \"nl\": \"minuut\"x²\n}" - }, - "prefix": { - "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", - "type": "boolean" - }, - "default": { - "description": "The default interpretation - only one can be set.\nIf none is set, the first unit will be considered the default interpretation of a value without a unit", - "type": "boolean" + "ApplicableUnitJson": { + "type": "object", + "properties": { + "canonicalDenomination": { + "description": "The canonical value which will be added to the text.\ne.g. \"m\" for meters\nIf the user inputs '42', the canonical value will be added and it'll become '42m'", + "type": "string" + }, + "canonicalDenominationSingular": { + "description": "The canonical denomination in the case that the unit is precisely '1'", + "type": "string" + }, + "alternativeDenomination": { + "description": "A list of alternative values which can occur in the OSM database - used for parsing.", + "type": "array", + "items": { + "type": "string" + } + }, + "human": { + "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"meter\",\n \"fr\": \"metre\"\n}" + }, + "humanSingular": { + "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"minute\",\n \"nl\": \"minuut\"x²\n}" + }, + "prefix": { + "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", + "type": "boolean" + }, + "default": { + "description": "The default interpretation - only one can be set.\nIf none is set, the first unit will be considered the default interpretation of a value without a unit", + "type": "boolean" + } + }, + "required": [ + "canonicalDenomination" + ] } - }, - "required": [ - "canonicalDenomination" - ] - } - }, - "$schema": "http://json-schema.org/draft-07/schema#" + }, + "$schema": "http://json-schema.org/draft-07/schema#" } \ No newline at end of file diff --git a/Docs/Schemas/PointRenderingConfigJsonJSC.ts b/Docs/Schemas/PointRenderingConfigJsonJSC.ts index 55d09eb381..371378c9ed 100644 --- a/Docs/Schemas/PointRenderingConfigJsonJSC.ts +++ b/Docs/Schemas/PointRenderingConfigJsonJSC.ts @@ -1,265 +1,265 @@ export default { - "description": "The PointRenderingConfig gives all details onto how to render a single point of a feature.\n\nThis can be used if:\n\n- The feature is a point\n- To render something at the centroid of an area, or at the start, end or projected centroid of a way", - "type": "object", - "properties": { - "location": { - "description": "All the locations that this point should be rendered at.\nUsing `location: [\"point\", \"centroid\"] will always render centerpoint", - "type": "array", - "items": { - "type": "string" - } - }, - "icon": { - "description": "The icon for an element.\nNote that this also doubles as the icon for this layer (rendered with the overpass-tags) ánd the icon in the presets.\n\nThe result of the icon is rendered as follows:\nthe resulting string is interpreted as a _list_ of items, separated by \";\". The bottommost layer is the first layer.\nAs a result, on could use a generic pin, then overlay it with a specific icon.\nTo make things even more practical, one can use all SVG's from the folder \"assets/svg\" and _substitute the color_ in it.\nE.g. to draw a red pin, use \"pin:#f00\", to have a green circle with your icon on top, use `circle:#0f0;`\n\nType: icon", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "iconBadges": { - "description": "A list of extra badges to show next to the icon as small badge\nThey will be added as a 25% height icon at the bottom right of the icon, with all the badges in a flex layout.\n\nNote: strings are interpreted as icons, so layering and substituting is supported. You can use `circle:white;./my_icon.svg` to add a background circle", - "type": "array", - "items": { - "type": "object", - "properties": { - "if": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { + "description": "The PointRenderingConfig gives all details onto how to render a single point of a feature.\n\nThis can be used if:\n\n- The feature is a point\n- To render something at the centroid of an area, or at the start, end or projected centroid of a way", + "type": "object", + "properties": { + "location": { + "description": "All the locations that this point should be rendered at.\nUsing `location: [\"point\", \"centroid\"] will always render centerpoint", + "type": "array", + "items": { "type": "string" - } - ] - }, - "then": { - "description": "Badge to show\nType: icon", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - } - }, - "required": [ - "if", - "then" - ] - } - }, - "iconSize": { - "description": "A string containing \"width,height\" or \"width,height,anchorpoint\" where anchorpoint is any of 'center', 'top', 'bottom', 'left', 'right', 'bottomleft','topright', ...\nDefault is '40,40,center'", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "rotation": { - "description": "The rotation of an icon, useful for e.g. directions.\nUsage: as if it were a css property for 'rotate', thus has to end with 'deg', e.g. `90deg`, `{direction}deg`, `calc(90deg - {camera:direction}deg)``", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "label": { - "description": "A HTML-fragment that is shown below the icon, for example:\n
{name}
\n\nIf the icon is undefined, then the label is shown in the center of the feature.\nNote that, if the wayhandling hides the icon then no label is shown as well.", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - } - }, - "required": [ - "location" - ], - "definitions": { - "AndOrTagConfigJson": { - "type": "object", - "properties": { - "and": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } - }, - "or": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } - } - } - }, - "ApplicableUnitJson": { - "type": "object", - "properties": { - "canonicalDenomination": { - "description": "The canonical value which will be added to the text.\ne.g. \"m\" for meters\nIf the user inputs '42', the canonical value will be added and it'll become '42m'", - "type": "string" - }, - "canonicalDenominationSingular": { - "description": "The canonical denomination in the case that the unit is precisely '1'", - "type": "string" - }, - "alternativeDenomination": { - "description": "A list of alternative values which can occur in the OSM database - used for parsing.", - "type": "array", - "items": { - "type": "string" - } - }, - "human": { - "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"meter\",\n \"fr\": \"metre\"\n}" - }, - "humanSingular": { - "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"minute\",\n \"nl\": \"minuut\"x²\n}" - }, - "prefix": { - "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", - "type": "boolean" - }, - "default": { - "description": "The default interpretation - only one can be set.\nIf none is set, the first unit will be considered the default interpretation of a value without a unit", - "type": "boolean" - } - }, - "required": [ - "canonicalDenomination" - ] - }, - "TagRenderingConfigJson": { - "description": "A TagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nFor an _editable_ tagRenerdering, use 'QuestionableTagRenderingConfigJson' instead, which extends this one", - "type": "object", - "properties": { - "id": { - "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", - "type": "string" - }, - "group": { - "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", - "type": "string" - }, - "labels": { - "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", - "type": "array", - "items": { - "type": "string" - } - }, - "render": { - "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" - }, - "condition": { - "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" } - ] }, - "freeform": { - "description": "Allow freeform text input from the user", - "type": "object", - "properties": { - "key": { - "description": "If this key is present, then 'render' is used to display the value.\nIf this is undefined, the rendering is _always_ shown", - "type": "string" + "icon": { + "description": "The icon for an element.\nNote that this also doubles as the icon for this layer (rendered with the overpass-tags) ánd the icon in the presets.\n\nThe result of the icon is rendered as follows:\nthe resulting string is interpreted as a _list_ of items, separated by \";\". The bottommost layer is the first layer.\nAs a result, on could use a generic pin, then overlay it with a specific icon.\nTo make things even more practical, one can use all SVG's from the folder \"assets/svg\" and _substitute the color_ in it.\nE.g. to draw a red pin, use \"pin:#f00\", to have a green circle with your icon on top, use `circle:#0f0;`\n\nType: icon", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "iconBadges": { + "description": "A list of extra badges to show next to the icon as small badge\nThey will be added as a 25% height icon at the bottom right of the icon, with all the badges in a flex layout.\n\nNote: strings are interpreted as icons, so layering and substituting is supported. You can use `circle:white;./my_icon.svg` to add a background circle", + "type": "array", + "items": { + "type": "object", + "properties": { + "if": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "then": { + "description": "Badge to show\nType: icon", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "if", + "then" + ] } - }, - "required": [ - "key" - ] }, - "mappings": { - "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", - "type": "array", - "items": { + "iconSize": { + "description": "A string containing \"width,height\" or \"width,height,anchorpoint\" where anchorpoint is any of 'center', 'top', 'bottom', 'left', 'right', 'bottomleft','topright', ...\nDefault is '40,40,center'", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "rotation": { + "description": "The rotation of an icon, useful for e.g. directions.\nUsage: as if it were a css property for 'rotate', thus has to end with 'deg', e.g. `90deg`, `{direction}deg`, `calc(90deg - {camera:direction}deg)``", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "label": { + "description": "A HTML-fragment that is shown below the icon, for example:\n
{name}
\n\nIf the icon is undefined, then the label is shown in the center of the feature.\nNote that, if the wayhandling hides the icon then no label is shown as well.", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "location" + ], + "definitions": { + "AndOrTagConfigJson": { "type": "object", "properties": { - "if": { - "description": "If this condition is met, then the text under `then` will be shown.\nIf no value matches, and the user selects this mapping as an option, then these tags will be uploaded to OSM.\n\nFor example: {'if': 'diet:vegetarion=yes', 'then':'A vegetarian option is offered here'}\n\nThis can be an substituting-tag as well, e.g. {'if': 'addr:street:={_calculated_nearby_streetname}', 'then': '{_calculated_nearby_streetname}'}", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { + "and": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "or": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + } + } + }, + "ApplicableUnitJson": { + "type": "object", + "properties": { + "canonicalDenomination": { + "description": "The canonical value which will be added to the text.\ne.g. \"m\" for meters\nIf the user inputs '42', the canonical value will be added and it'll become '42m'", "type": "string" - } - ] - }, - "then": { - "description": "If the condition `if` is met, the text `then` will be rendered.\nIf not known yet, the user will be presented with `then` as an option\nType: rendered" - }, - "icon": { - "description": "An icon supporting this mapping; typically shown pretty small\nType: icon", - "anyOf": [ - { - "type": "object", - "properties": { - "path": { - "description": "The path to the icon\nType: icon", - "type": "string" - }, - "class": { - "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", - "type": "string" - } - }, - "required": [ - "class", - "path" - ] - }, - { + }, + "canonicalDenominationSingular": { + "description": "The canonical denomination in the case that the unit is precisely '1'", "type": "string" - } - ] - } + }, + "alternativeDenomination": { + "description": "A list of alternative values which can occur in the OSM database - used for parsing.", + "type": "array", + "items": { + "type": "string" + } + }, + "human": { + "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"meter\",\n \"fr\": \"metre\"\n}" + }, + "humanSingular": { + "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"minute\",\n \"nl\": \"minuut\"x²\n}" + }, + "prefix": { + "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", + "type": "boolean" + }, + "default": { + "description": "The default interpretation - only one can be set.\nIf none is set, the first unit will be considered the default interpretation of a value without a unit", + "type": "boolean" + } }, "required": [ - "if", - "then" + "canonicalDenomination" ] - } + }, + "TagRenderingConfigJson": { + "description": "A TagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nFor an _editable_ tagRenerdering, use 'QuestionableTagRenderingConfigJson' instead, which extends this one", + "type": "object", + "properties": { + "id": { + "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", + "type": "string" + }, + "group": { + "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", + "type": "string" + }, + "labels": { + "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", + "type": "array", + "items": { + "type": "string" + } + }, + "render": { + "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" + }, + "condition": { + "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "freeform": { + "description": "Allow freeform text input from the user", + "type": "object", + "properties": { + "key": { + "description": "If this key is present, then 'render' is used to display the value.\nIf this is undefined, the rendering is _always_ shown", + "type": "string" + } + }, + "required": [ + "key" + ] + }, + "mappings": { + "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", + "type": "array", + "items": { + "type": "object", + "properties": { + "if": { + "description": "If this condition is met, then the text under `then` will be shown.\nIf no value matches, and the user selects this mapping as an option, then these tags will be uploaded to OSM.\n\nFor example: {'if': 'diet:vegetarion=yes', 'then':'A vegetarian option is offered here'}\n\nThis can be an substituting-tag as well, e.g. {'if': 'addr:street:={_calculated_nearby_streetname}', 'then': '{_calculated_nearby_streetname}'}", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "then": { + "description": "If the condition `if` is met, the text `then` will be rendered.\nIf not known yet, the user will be presented with `then` as an option\nType: rendered" + }, + "icon": { + "description": "An icon supporting this mapping; typically shown pretty small\nType: icon", + "anyOf": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", + "type": "string" + } + }, + "required": [ + "class", + "path" + ] + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "if", + "then" + ] + } + } + } } - } - } - }, - "$schema": "http://json-schema.org/draft-07/schema#" + }, + "$schema": "http://json-schema.org/draft-07/schema#" } \ No newline at end of file diff --git a/Docs/Schemas/QuestionableTagRenderingConfigJsonJSC.ts b/Docs/Schemas/QuestionableTagRenderingConfigJsonJSC.ts index ca2ffe2820..0fcdb00e0b 100644 --- a/Docs/Schemas/QuestionableTagRenderingConfigJsonJSC.ts +++ b/Docs/Schemas/QuestionableTagRenderingConfigJsonJSC.ts @@ -1,335 +1,335 @@ export default { - "description": "A QuestionableTagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nIf the desired tags are missing and a question is defined, a question will be shown instead.", - "type": "object", - "properties": { - "question": { - "description": "If it turns out that this tagRendering doesn't match _any_ value, then we show this question.\nIf undefined, the question is never asked and this tagrendering is read-only" - }, - "freeform": { - "description": "Allow freeform text input from the user", - "type": "object", - "properties": { - "key": { - "type": "string" - }, - "type": { - "description": "The type of the text-field, e.g. 'string', 'nat', 'float', 'date',...\nSee Docs/SpecialInputElements.md and UI/Input/ValidatedTextField.ts for supported values", - "type": "string" - }, - "placeholder": { - "description": "A (translated) text that is shown (as gray text) within the textfield" - }, - "helperArgs": { - "description": "Extra parameters to initialize the input helper arguments.\nFor semantics, see the 'SpecialInputElements.md'", - "type": "array", - "items": {} - }, - "addExtraTags": { - "description": "If a value is added with the textfield, these extra tag is addded.\nUseful to add a 'fixme=freeform textfield used - to be checked'", - "type": "array", - "items": { - "type": "string" - } - }, - "inline": { - "description": "When set, influences the way a question is asked.\nInstead of showing a full-widht text field, the text field will be shown within the rendering of the question.\n\nThis combines badly with special input elements, as it'll distort the layout.", - "type": "boolean" - }, - "default": { - "description": "default value to enter if no previous tagging is present.\nNormally undefined (aka do not enter anything)", - "type": "string" - } - }, - "required": [ - "key" - ] - }, - "multiAnswer": { - "description": "If true, use checkboxes instead of radio buttons when asking the question", - "type": "boolean" - }, - "mappings": { - "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", - "type": "array", - "items": { - "type": "object", - "properties": { - "if": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "then": { - "description": "Shown if the 'if is fulfilled\nType: rendered" - }, - "icon": { - "description": "An extra icon supporting the choice\nType: icon", - "anyOf": [ - { - "type": "object", - "properties": { - "path": { - "description": "The path to the icon\nType: icon", - "type": "string" - }, - "class": { - "description": "Size of the image", - "type": "string" - } - }, - "required": [ - "class", - "path" - ] - }, - { - "type": "string" - } - ] - }, - "hideInAnswer": { - "description": "In some cases, multiple taggings exist (e.g. a default assumption, or a commonly mapped abbreviation and a fully written variation).\n\nIn the latter case, a correct text should be shown, but only a single, canonical tagging should be selectable by the user.\nIn this case, one of the mappings can be hiden by setting this flag.\n\nTo demonstrate an example making a default assumption:\n\nmappings: [\n {\n if: \"access=\", -- no access tag present, we assume accessible\n then: \"Accessible to the general public\",\n hideInAnswer: true\n },\n {\n if: \"access=yes\",\n then: \"Accessible to the general public\", -- the user selected this, we add that to OSM\n },\n {\n if: \"access=no\",\n then: \"Not accessible to the public\"\n }\n]\n\n\nFor example, for an operator, we have `operator=Agentschap Natuur en Bos`, which is often abbreviated to `operator=ANB`.\nThen, we would add two mappings:\n{\n if: \"operator=Agentschap Natuur en Bos\" -- the non-abbreviated version which should be uploaded\n then: \"Maintained by Agentschap Natuur en Bos\"\n},\n{\n if: \"operator=ANB\", -- we don't want to upload abbreviations\n then: \"Maintained by Agentschap Natuur en Bos\"\n hideInAnswer: true\n}\n\nHide in answer can also be a tagsfilter, e.g. to make sure an option is only shown when appropriate.\nKeep in mind that this is reverse logic: it will be hidden in the answer if the condition is true, it will thus only show in the case of a mismatch\n\ne.g., for toilets: if \"wheelchair=no\", we know there is no wheelchair dedicated room.\nFor the location of the changing table, the option \"in the wheelchair accessible toilet is weird\", so we write:\n\n{\n \"question\": \"Where is the changing table located?\"\n \"mappings\": [\n {\"if\":\"changing_table:location=female\",\"then\":\"In the female restroom\"},\n {\"if\":\"changing_table:location=male\",\"then\":\"In the male restroom\"},\n {\"if\":\"changing_table:location=wheelchair\",\"then\":\"In the wheelchair accessible restroom\", \"hideInAnswer\": \"wheelchair=no\"},\n \n ]\n}\n\nAlso have a look for the meta-tags\n{\n if: \"operator=Agentschap Natuur en Bos\",\n then: \"Maintained by Agentschap Natuur en Bos\",\n hideInAnswer: \"_country!=be\"\n}", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": [ - "string", - "boolean" - ] - } - ] - }, - "ifnot": { - "description": "Only applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "addExtraTags": { - "description": "If chosen as answer, these tags will be applied as well onto the object.\nNot compatible with multiAnswer", - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "if", - "then" - ] - } - }, - "id": { - "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", - "type": "string" - }, - "group": { - "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", - "type": "string" - }, - "labels": { - "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", - "type": "array", - "items": { - "type": "string" - } - }, - "render": { - "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" - }, - "condition": { - "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } - }, - "definitions": { - "AndOrTagConfigJson": { - "type": "object", - "properties": { - "and": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } - }, - "or": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } - } - } - }, - "ApplicableUnitJson": { - "type": "object", - "properties": { - "canonicalDenomination": { - "description": "The canonical value which will be added to the text.\ne.g. \"m\" for meters\nIf the user inputs '42', the canonical value will be added and it'll become '42m'", - "type": "string" - }, - "canonicalDenominationSingular": { - "description": "The canonical denomination in the case that the unit is precisely '1'", - "type": "string" - }, - "alternativeDenomination": { - "description": "A list of alternative values which can occur in the OSM database - used for parsing.", - "type": "array", - "items": { - "type": "string" - } - }, - "human": { - "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"meter\",\n \"fr\": \"metre\"\n}" - }, - "humanSingular": { - "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"minute\",\n \"nl\": \"minuut\"x²\n}" - }, - "prefix": { - "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", - "type": "boolean" - }, - "default": { - "description": "The default interpretation - only one can be set.\nIf none is set, the first unit will be considered the default interpretation of a value without a unit", - "type": "boolean" - } - }, - "required": [ - "canonicalDenomination" - ] - }, - "TagRenderingConfigJson": { - "description": "A TagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nFor an _editable_ tagRenerdering, use 'QuestionableTagRenderingConfigJson' instead, which extends this one", - "type": "object", - "properties": { - "id": { - "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", - "type": "string" - }, - "group": { - "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", - "type": "string" - }, - "labels": { - "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", - "type": "array", - "items": { - "type": "string" - } - }, - "render": { - "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" - }, - "condition": { - "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] + "description": "A QuestionableTagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nIf the desired tags are missing and a question is defined, a question will be shown instead.", + "type": "object", + "properties": { + "question": { + "description": "If it turns out that this tagRendering doesn't match _any_ value, then we show this question.\nIf undefined, the question is never asked and this tagrendering is read-only" }, "freeform": { - "description": "Allow freeform text input from the user", - "type": "object", - "properties": { - "key": { - "description": "If this key is present, then 'render' is used to display the value.\nIf this is undefined, the rendering is _always_ shown", - "type": "string" - } - }, - "required": [ - "key" - ] - }, - "mappings": { - "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", - "type": "array", - "items": { + "description": "Allow freeform text input from the user", "type": "object", "properties": { - "if": { - "description": "If this condition is met, then the text under `then` will be shown.\nIf no value matches, and the user selects this mapping as an option, then these tags will be uploaded to OSM.\n\nFor example: {'if': 'diet:vegetarion=yes', 'then':'A vegetarian option is offered here'}\n\nThis can be an substituting-tag as well, e.g. {'if': 'addr:street:={_calculated_nearby_streetname}', 'then': '{_calculated_nearby_streetname}'}", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { + "key": { "type": "string" - } - ] - }, - "then": { - "description": "If the condition `if` is met, the text `then` will be rendered.\nIf not known yet, the user will be presented with `then` as an option\nType: rendered" - }, - "icon": { - "description": "An icon supporting this mapping; typically shown pretty small\nType: icon", - "anyOf": [ - { - "type": "object", - "properties": { - "path": { - "description": "The path to the icon\nType: icon", - "type": "string" - }, - "class": { - "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", - "type": "string" - } - }, - "required": [ - "class", - "path" - ] - }, - { + }, + "type": { + "description": "The type of the text-field, e.g. 'string', 'nat', 'float', 'date',...\nSee Docs/SpecialInputElements.md and UI/Input/ValidatedTextField.ts for supported values", "type": "string" - } - ] - } + }, + "placeholder": { + "description": "A (translated) text that is shown (as gray text) within the textfield" + }, + "helperArgs": { + "description": "Extra parameters to initialize the input helper arguments.\nFor semantics, see the 'SpecialInputElements.md'", + "type": "array", + "items": {} + }, + "addExtraTags": { + "description": "If a value is added with the textfield, these extra tag is addded.\nUseful to add a 'fixme=freeform textfield used - to be checked'", + "type": "array", + "items": { + "type": "string" + } + }, + "inline": { + "description": "When set, influences the way a question is asked.\nInstead of showing a full-widht text field, the text field will be shown within the rendering of the question.\n\nThis combines badly with special input elements, as it'll distort the layout.", + "type": "boolean" + }, + "default": { + "description": "default value to enter if no previous tagging is present.\nNormally undefined (aka do not enter anything)", + "type": "string" + } }, "required": [ - "if", - "then" + "key" + ] + }, + "multiAnswer": { + "description": "If true, use checkboxes instead of radio buttons when asking the question", + "type": "boolean" + }, + "mappings": { + "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", + "type": "array", + "items": { + "type": "object", + "properties": { + "if": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "then": { + "description": "Shown if the 'if is fulfilled\nType: rendered" + }, + "icon": { + "description": "An extra icon supporting the choice\nType: icon", + "anyOf": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "Size of the image", + "type": "string" + } + }, + "required": [ + "class", + "path" + ] + }, + { + "type": "string" + } + ] + }, + "hideInAnswer": { + "description": "In some cases, multiple taggings exist (e.g. a default assumption, or a commonly mapped abbreviation and a fully written variation).\n\nIn the latter case, a correct text should be shown, but only a single, canonical tagging should be selectable by the user.\nIn this case, one of the mappings can be hiden by setting this flag.\n\nTo demonstrate an example making a default assumption:\n\nmappings: [\n {\n if: \"access=\", -- no access tag present, we assume accessible\n then: \"Accessible to the general public\",\n hideInAnswer: true\n },\n {\n if: \"access=yes\",\n then: \"Accessible to the general public\", -- the user selected this, we add that to OSM\n },\n {\n if: \"access=no\",\n then: \"Not accessible to the public\"\n }\n]\n\n\nFor example, for an operator, we have `operator=Agentschap Natuur en Bos`, which is often abbreviated to `operator=ANB`.\nThen, we would add two mappings:\n{\n if: \"operator=Agentschap Natuur en Bos\" -- the non-abbreviated version which should be uploaded\n then: \"Maintained by Agentschap Natuur en Bos\"\n},\n{\n if: \"operator=ANB\", -- we don't want to upload abbreviations\n then: \"Maintained by Agentschap Natuur en Bos\"\n hideInAnswer: true\n}\n\nHide in answer can also be a tagsfilter, e.g. to make sure an option is only shown when appropriate.\nKeep in mind that this is reverse logic: it will be hidden in the answer if the condition is true, it will thus only show in the case of a mismatch\n\ne.g., for toilets: if \"wheelchair=no\", we know there is no wheelchair dedicated room.\nFor the location of the changing table, the option \"in the wheelchair accessible toilet is weird\", so we write:\n\n{\n \"question\": \"Where is the changing table located?\"\n \"mappings\": [\n {\"if\":\"changing_table:location=female\",\"then\":\"In the female restroom\"},\n {\"if\":\"changing_table:location=male\",\"then\":\"In the male restroom\"},\n {\"if\":\"changing_table:location=wheelchair\",\"then\":\"In the wheelchair accessible restroom\", \"hideInAnswer\": \"wheelchair=no\"},\n \n ]\n}\n\nAlso have a look for the meta-tags\n{\n if: \"operator=Agentschap Natuur en Bos\",\n then: \"Maintained by Agentschap Natuur en Bos\",\n hideInAnswer: \"_country!=be\"\n}", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": [ + "string", + "boolean" + ] + } + ] + }, + "ifnot": { + "description": "Only applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "addExtraTags": { + "description": "If chosen as answer, these tags will be applied as well onto the object.\nNot compatible with multiAnswer", + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "if", + "then" + ] + } + }, + "id": { + "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", + "type": "string" + }, + "group": { + "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", + "type": "string" + }, + "labels": { + "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", + "type": "array", + "items": { + "type": "string" + } + }, + "render": { + "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" + }, + "condition": { + "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } ] - } } - } - } - }, - "$schema": "http://json-schema.org/draft-07/schema#" + }, + "definitions": { + "AndOrTagConfigJson": { + "type": "object", + "properties": { + "and": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "or": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + } + } + }, + "ApplicableUnitJson": { + "type": "object", + "properties": { + "canonicalDenomination": { + "description": "The canonical value which will be added to the text.\ne.g. \"m\" for meters\nIf the user inputs '42', the canonical value will be added and it'll become '42m'", + "type": "string" + }, + "canonicalDenominationSingular": { + "description": "The canonical denomination in the case that the unit is precisely '1'", + "type": "string" + }, + "alternativeDenomination": { + "description": "A list of alternative values which can occur in the OSM database - used for parsing.", + "type": "array", + "items": { + "type": "string" + } + }, + "human": { + "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"meter\",\n \"fr\": \"metre\"\n}" + }, + "humanSingular": { + "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"minute\",\n \"nl\": \"minuut\"x²\n}" + }, + "prefix": { + "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", + "type": "boolean" + }, + "default": { + "description": "The default interpretation - only one can be set.\nIf none is set, the first unit will be considered the default interpretation of a value without a unit", + "type": "boolean" + } + }, + "required": [ + "canonicalDenomination" + ] + }, + "TagRenderingConfigJson": { + "description": "A TagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nFor an _editable_ tagRenerdering, use 'QuestionableTagRenderingConfigJson' instead, which extends this one", + "type": "object", + "properties": { + "id": { + "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", + "type": "string" + }, + "group": { + "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", + "type": "string" + }, + "labels": { + "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", + "type": "array", + "items": { + "type": "string" + } + }, + "render": { + "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" + }, + "condition": { + "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "freeform": { + "description": "Allow freeform text input from the user", + "type": "object", + "properties": { + "key": { + "description": "If this key is present, then 'render' is used to display the value.\nIf this is undefined, the rendering is _always_ shown", + "type": "string" + } + }, + "required": [ + "key" + ] + }, + "mappings": { + "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", + "type": "array", + "items": { + "type": "object", + "properties": { + "if": { + "description": "If this condition is met, then the text under `then` will be shown.\nIf no value matches, and the user selects this mapping as an option, then these tags will be uploaded to OSM.\n\nFor example: {'if': 'diet:vegetarion=yes', 'then':'A vegetarian option is offered here'}\n\nThis can be an substituting-tag as well, e.g. {'if': 'addr:street:={_calculated_nearby_streetname}', 'then': '{_calculated_nearby_streetname}'}", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "then": { + "description": "If the condition `if` is met, the text `then` will be rendered.\nIf not known yet, the user will be presented with `then` as an option\nType: rendered" + }, + "icon": { + "description": "An icon supporting this mapping; typically shown pretty small\nType: icon", + "anyOf": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", + "type": "string" + } + }, + "required": [ + "class", + "path" + ] + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "if", + "then" + ] + } + } + } + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" } \ No newline at end of file diff --git a/Docs/Schemas/RewritableConfigJsonJSC.ts b/Docs/Schemas/RewritableConfigJsonJSC.ts index 26134d0222..9ddb180381 100644 --- a/Docs/Schemas/RewritableConfigJsonJSC.ts +++ b/Docs/Schemas/RewritableConfigJsonJSC.ts @@ -1,208 +1,208 @@ export default { - "type": "object", - "properties": { - "rewrite": { - "type": "object", - "properties": { - "sourceString": { - "type": "array", - "items": { - "type": "string" - } - }, - "into": { - "type": "array", - "items": { - "type": "array", - "items": {} - } - } - }, - "required": [ - "into", - "sourceString" - ] - }, - "renderings": { - "$ref": "#/definitions/T" - } - }, - "required": [ - "renderings", - "rewrite" - ], - "definitions": { - "AndOrTagConfigJson": { - "type": "object", - "properties": { - "and": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } - }, - "or": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } - } - } - }, - "ApplicableUnitJson": { - "type": "object", - "properties": { - "canonicalDenomination": { - "description": "The canonical value which will be added to the text.\ne.g. \"m\" for meters\nIf the user inputs '42', the canonical value will be added and it'll become '42m'", - "type": "string" - }, - "canonicalDenominationSingular": { - "description": "The canonical denomination in the case that the unit is precisely '1'", - "type": "string" - }, - "alternativeDenomination": { - "description": "A list of alternative values which can occur in the OSM database - used for parsing.", - "type": "array", - "items": { - "type": "string" - } - }, - "human": { - "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"meter\",\n \"fr\": \"metre\"\n}" - }, - "humanSingular": { - "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"minute\",\n \"nl\": \"minuut\"x²\n}" - }, - "prefix": { - "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", - "type": "boolean" - }, - "default": { - "description": "The default interpretation - only one can be set.\nIf none is set, the first unit will be considered the default interpretation of a value without a unit", - "type": "boolean" - } - }, - "required": [ - "canonicalDenomination" - ] - }, - "TagRenderingConfigJson": { - "description": "A TagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nFor an _editable_ tagRenerdering, use 'QuestionableTagRenderingConfigJson' instead, which extends this one", - "type": "object", - "properties": { - "id": { - "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", - "type": "string" - }, - "group": { - "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", - "type": "string" - }, - "labels": { - "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", - "type": "array", - "items": { - "type": "string" - } - }, - "render": { - "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" - }, - "condition": { - "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "freeform": { - "description": "Allow freeform text input from the user", - "type": "object", - "properties": { - "key": { - "description": "If this key is present, then 'render' is used to display the value.\nIf this is undefined, the rendering is _always_ shown", - "type": "string" - } - }, - "required": [ - "key" - ] - }, - "mappings": { - "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", - "type": "array", - "items": { + "type": "object", + "properties": { + "rewrite": { "type": "object", "properties": { - "if": { - "description": "If this condition is met, then the text under `then` will be shown.\nIf no value matches, and the user selects this mapping as an option, then these tags will be uploaded to OSM.\n\nFor example: {'if': 'diet:vegetarion=yes', 'then':'A vegetarian option is offered here'}\n\nThis can be an substituting-tag as well, e.g. {'if': 'addr:street:={_calculated_nearby_streetname}', 'then': '{_calculated_nearby_streetname}'}", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "then": { - "description": "If the condition `if` is met, the text `then` will be rendered.\nIf not known yet, the user will be presented with `then` as an option\nType: rendered" - }, - "icon": { - "description": "An icon supporting this mapping; typically shown pretty small\nType: icon", - "anyOf": [ - { - "type": "object", - "properties": { - "path": { - "description": "The path to the icon\nType: icon", + "sourceString": { + "type": "array", + "items": { "type": "string" - }, - "class": { - "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", - "type": "string" - } - }, - "required": [ - "class", - "path" - ] - }, - { - "type": "string" - } - ] - } + } + }, + "into": { + "type": "array", + "items": { + "type": "array", + "items": {} + } + } }, "required": [ - "if", - "then" + "into", + "sourceString" ] - } + }, + "renderings": { + "$ref": "#/definitions/T" } - } }, - "T": { - "type": "object" - } - }, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": [ + "renderings", + "rewrite" + ], + "definitions": { + "AndOrTagConfigJson": { + "type": "object", + "properties": { + "and": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "or": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + } + } + }, + "ApplicableUnitJson": { + "type": "object", + "properties": { + "canonicalDenomination": { + "description": "The canonical value which will be added to the text.\ne.g. \"m\" for meters\nIf the user inputs '42', the canonical value will be added and it'll become '42m'", + "type": "string" + }, + "canonicalDenominationSingular": { + "description": "The canonical denomination in the case that the unit is precisely '1'", + "type": "string" + }, + "alternativeDenomination": { + "description": "A list of alternative values which can occur in the OSM database - used for parsing.", + "type": "array", + "items": { + "type": "string" + } + }, + "human": { + "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"meter\",\n \"fr\": \"metre\"\n}" + }, + "humanSingular": { + "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"minute\",\n \"nl\": \"minuut\"x²\n}" + }, + "prefix": { + "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", + "type": "boolean" + }, + "default": { + "description": "The default interpretation - only one can be set.\nIf none is set, the first unit will be considered the default interpretation of a value without a unit", + "type": "boolean" + } + }, + "required": [ + "canonicalDenomination" + ] + }, + "TagRenderingConfigJson": { + "description": "A TagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nFor an _editable_ tagRenerdering, use 'QuestionableTagRenderingConfigJson' instead, which extends this one", + "type": "object", + "properties": { + "id": { + "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", + "type": "string" + }, + "group": { + "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", + "type": "string" + }, + "labels": { + "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", + "type": "array", + "items": { + "type": "string" + } + }, + "render": { + "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" + }, + "condition": { + "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "freeform": { + "description": "Allow freeform text input from the user", + "type": "object", + "properties": { + "key": { + "description": "If this key is present, then 'render' is used to display the value.\nIf this is undefined, the rendering is _always_ shown", + "type": "string" + } + }, + "required": [ + "key" + ] + }, + "mappings": { + "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", + "type": "array", + "items": { + "type": "object", + "properties": { + "if": { + "description": "If this condition is met, then the text under `then` will be shown.\nIf no value matches, and the user selects this mapping as an option, then these tags will be uploaded to OSM.\n\nFor example: {'if': 'diet:vegetarion=yes', 'then':'A vegetarian option is offered here'}\n\nThis can be an substituting-tag as well, e.g. {'if': 'addr:street:={_calculated_nearby_streetname}', 'then': '{_calculated_nearby_streetname}'}", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "then": { + "description": "If the condition `if` is met, the text `then` will be rendered.\nIf not known yet, the user will be presented with `then` as an option\nType: rendered" + }, + "icon": { + "description": "An icon supporting this mapping; typically shown pretty small\nType: icon", + "anyOf": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", + "type": "string" + } + }, + "required": [ + "class", + "path" + ] + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "if", + "then" + ] + } + } + } + }, + "T": { + "type": "object" + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" } \ No newline at end of file diff --git a/Docs/Schemas/TagRenderingConfigJsonJSC.ts b/Docs/Schemas/TagRenderingConfigJsonJSC.ts index 9d4e22b6a0..11afa40fc2 100644 --- a/Docs/Schemas/TagRenderingConfigJsonJSC.ts +++ b/Docs/Schemas/TagRenderingConfigJsonJSC.ts @@ -1,134 +1,134 @@ export default { - "description": "A TagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nFor an _editable_ tagRenerdering, use 'QuestionableTagRenderingConfigJson' instead, which extends this one", - "type": "object", - "properties": { - "id": { - "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", - "type": "string" - }, - "group": { - "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", - "type": "string" - }, - "labels": { - "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", - "type": "array", - "items": { - "type": "string" - } - }, - "render": { - "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" - }, - "condition": { - "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" + "description": "A TagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nFor an _editable_ tagRenerdering, use 'QuestionableTagRenderingConfigJson' instead, which extends this one", + "type": "object", + "properties": { + "id": { + "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", + "type": "string" }, - { - "type": "string" - } - ] - }, - "freeform": { - "description": "Allow freeform text input from the user", - "type": "object", - "properties": { - "key": { - "description": "If this key is present, then 'render' is used to display the value.\nIf this is undefined, the rendering is _always_ shown", - "type": "string" - } - }, - "required": [ - "key" - ] - }, - "mappings": { - "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", - "type": "array", - "items": { - "type": "object", - "properties": { - "if": { - "description": "If this condition is met, then the text under `then` will be shown.\nIf no value matches, and the user selects this mapping as an option, then these tags will be uploaded to OSM.\n\nFor example: {'if': 'diet:vegetarion=yes', 'then':'A vegetarian option is offered here'}\n\nThis can be an substituting-tag as well, e.g. {'if': 'addr:street:={_calculated_nearby_streetname}', 'then': '{_calculated_nearby_streetname}'}", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { + "group": { + "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", + "type": "string" + }, + "labels": { + "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", + "type": "array", + "items": { "type": "string" - } - ] - }, - "then": { - "description": "If the condition `if` is met, the text `then` will be rendered.\nIf not known yet, the user will be presented with `then` as an option\nType: rendered" - }, - "icon": { - "description": "An icon supporting this mapping; typically shown pretty small\nType: icon", + } + }, + "render": { + "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" + }, + "condition": { + "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", "anyOf": [ - { + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "freeform": { + "description": "Allow freeform text input from the user", + "type": "object", + "properties": { + "key": { + "description": "If this key is present, then 'render' is used to display the value.\nIf this is undefined, the rendering is _always_ shown", + "type": "string" + } + }, + "required": [ + "key" + ] + }, + "mappings": { + "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", + "type": "array", + "items": { "type": "object", "properties": { - "path": { - "description": "The path to the icon\nType: icon", - "type": "string" - }, - "class": { - "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", - "type": "string" - } + "if": { + "description": "If this condition is met, then the text under `then` will be shown.\nIf no value matches, and the user selects this mapping as an option, then these tags will be uploaded to OSM.\n\nFor example: {'if': 'diet:vegetarion=yes', 'then':'A vegetarian option is offered here'}\n\nThis can be an substituting-tag as well, e.g. {'if': 'addr:street:={_calculated_nearby_streetname}', 'then': '{_calculated_nearby_streetname}'}", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "then": { + "description": "If the condition `if` is met, the text `then` will be rendered.\nIf not known yet, the user will be presented with `then` as an option\nType: rendered" + }, + "icon": { + "description": "An icon supporting this mapping; typically shown pretty small\nType: icon", + "anyOf": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", + "type": "string" + } + }, + "required": [ + "class", + "path" + ] + }, + { + "type": "string" + } + ] + } }, "required": [ - "class", - "path" + "if", + "then" ] - }, - { - "type": "string" - } - ] - } - }, - "required": [ - "if", - "then" - ] - } - } - }, - "definitions": { - "AndOrTagConfigJson": { - "type": "object", - "properties": { - "and": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } - }, - "or": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } + } } - } - } - }, - "$schema": "http://json-schema.org/draft-07/schema#" + }, + "definitions": { + "AndOrTagConfigJson": { + "type": "object", + "properties": { + "and": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "or": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + } + } + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" } \ No newline at end of file diff --git a/Docs/Schemas/TilesourceConfigJsonJSC.ts b/Docs/Schemas/TilesourceConfigJsonJSC.ts index 7f9e0d3194..e9120cab1a 100644 --- a/Docs/Schemas/TilesourceConfigJsonJSC.ts +++ b/Docs/Schemas/TilesourceConfigJsonJSC.ts @@ -1,770 +1,770 @@ export default { - "description": "Configuration for a tilesource config", - "type": "object", - "properties": { - "id": { - "description": "Id of this overlay, used in the URL-parameters to set the state", - "type": "string" - }, - "source": { - "description": "The path, where {x}, {y} and {z} will be substituted", - "type": "string" - }, - "isOverlay": { - "description": "Wether or not this is an overlay. Default: true", - "type": "boolean" - }, - "name": { - "description": "How this will be shown in the selection menu.\nMake undefined if this may not be toggled" - }, - "minZoom": { - "description": "Only visible at this or a higher zoom level", - "type": "number" - }, - "maxZoom": { - "description": "Only visible at this or a lower zoom level", - "type": "number" - }, - "defaultState": { - "description": "The default state, set to false to hide by default", - "type": "boolean" - } - }, - "required": [ - "defaultState", - "id", - "source" - ], - "definitions": { - "AndOrTagConfigJson": { - "type": "object", - "properties": { - "and": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } - }, - "or": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } - } - } - }, - "ApplicableUnitJson": { - "type": "object", - "properties": { - "canonicalDenomination": { - "description": "The canonical value which will be added to the text.\ne.g. \"m\" for meters\nIf the user inputs '42', the canonical value will be added and it'll become '42m'", - "type": "string" - }, - "canonicalDenominationSingular": { - "description": "The canonical denomination in the case that the unit is precisely '1'", - "type": "string" - }, - "alternativeDenomination": { - "description": "A list of alternative values which can occur in the OSM database - used for parsing.", - "type": "array", - "items": { - "type": "string" - } - }, - "human": { - "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"meter\",\n \"fr\": \"metre\"\n}" - }, - "humanSingular": { - "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"minute\",\n \"nl\": \"minuut\"x²\n}" - }, - "prefix": { - "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", - "type": "boolean" - }, - "default": { - "description": "The default interpretation - only one can be set.\nIf none is set, the first unit will be considered the default interpretation of a value without a unit", - "type": "boolean" - } - }, - "required": [ - "canonicalDenomination" - ] - }, - "TagRenderingConfigJson": { - "description": "A TagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nFor an _editable_ tagRenerdering, use 'QuestionableTagRenderingConfigJson' instead, which extends this one", - "type": "object", - "properties": { + "description": "Configuration for a tilesource config", + "type": "object", + "properties": { "id": { - "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", - "type": "string" - }, - "group": { - "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", - "type": "string" - }, - "labels": { - "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", - "type": "array", - "items": { + "description": "Id of this overlay, used in the URL-parameters to set the state", "type": "string" - } }, - "render": { - "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" - }, - "condition": { - "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "freeform": { - "description": "Allow freeform text input from the user", - "type": "object", - "properties": { - "key": { - "description": "If this key is present, then 'render' is used to display the value.\nIf this is undefined, the rendering is _always_ shown", - "type": "string" - } - }, - "required": [ - "key" - ] - }, - "mappings": { - "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", - "type": "array", - "items": { - "type": "object", - "properties": { - "if": { - "description": "If this condition is met, then the text under `then` will be shown.\nIf no value matches, and the user selects this mapping as an option, then these tags will be uploaded to OSM.\n\nFor example: {'if': 'diet:vegetarion=yes', 'then':'A vegetarian option is offered here'}\n\nThis can be an substituting-tag as well, e.g. {'if': 'addr:street:={_calculated_nearby_streetname}', 'then': '{_calculated_nearby_streetname}'}", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "then": { - "description": "If the condition `if` is met, the text `then` will be rendered.\nIf not known yet, the user will be presented with `then` as an option\nType: rendered" - }, - "icon": { - "description": "An icon supporting this mapping; typically shown pretty small\nType: icon", - "anyOf": [ - { - "type": "object", - "properties": { - "path": { - "description": "The path to the icon\nType: icon", - "type": "string" - }, - "class": { - "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", - "type": "string" - } - }, - "required": [ - "class", - "path" - ] - }, - { - "type": "string" - } - ] - } - }, - "required": [ - "if", - "then" - ] - } - } - } - }, - "T": { - "type": "object" - }, - "default_4": { - "description": "The PointRenderingConfig gives all details onto how to render a single point of a feature.\n\nThis can be used if:\n\n- The feature is a point\n- To render something at the centroid of an area, or at the start, end or projected centroid of a way", - "type": "object", - "properties": { - "location": { - "description": "All the locations that this point should be rendered at.\nUsing `location: [\"point\", \"centroid\"] will always render centerpoint", - "type": "array", - "items": { + "source": { + "description": "The path, where {x}, {y} and {z} will be substituted", "type": "string" - } }, - "icon": { - "description": "The icon for an element.\nNote that this also doubles as the icon for this layer (rendered with the overpass-tags) ánd the icon in the presets.\n\nThe result of the icon is rendered as follows:\nthe resulting string is interpreted as a _list_ of items, separated by \";\". The bottommost layer is the first layer.\nAs a result, on could use a generic pin, then overlay it with a specific icon.\nTo make things even more practical, one can use all SVG's from the folder \"assets/svg\" and _substitute the color_ in it.\nE.g. to draw a red pin, use \"pin:#f00\", to have a green circle with your icon on top, use `circle:#0f0;`\n\nType: icon", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] + "isOverlay": { + "description": "Wether or not this is an overlay. Default: true", + "type": "boolean" }, - "iconBadges": { - "description": "A list of extra badges to show next to the icon as small badge\nThey will be added as a 25% height icon at the bottom right of the icon, with all the badges in a flex layout.\n\nNote: strings are interpreted as icons, so layering and substituting is supported. You can use `circle:white;./my_icon.svg` to add a background circle", - "type": "array", - "items": { - "type": "object", - "properties": { - "if": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "then": { - "description": "Badge to show\nType: icon", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - } - }, - "required": [ - "if", - "then" - ] - } + "name": { + "description": "How this will be shown in the selection menu.\nMake undefined if this may not be toggled" }, - "iconSize": { - "description": "A string containing \"width,height\" or \"width,height,anchorpoint\" where anchorpoint is any of 'center', 'top', 'bottom', 'left', 'right', 'bottomleft','topright', ...\nDefault is '40,40,center'", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] + "minZoom": { + "description": "Only visible at this or a higher zoom level", + "type": "number" }, - "rotation": { - "description": "The rotation of an icon, useful for e.g. directions.\nUsage: as if it were a css property for 'rotate', thus has to end with 'deg', e.g. `90deg`, `{direction}deg`, `calc(90deg - {camera:direction}deg)``", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] + "maxZoom": { + "description": "Only visible at this or a lower zoom level", + "type": "number" }, - "label": { - "description": "A HTML-fragment that is shown below the icon, for example:\n
{name}
\n\nIf the icon is undefined, then the label is shown in the center of the feature.\nNote that, if the wayhandling hides the icon then no label is shown as well.", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] + "defaultState": { + "description": "The default state, set to false to hide by default", + "type": "boolean" } - }, - "required": [ - "location" - ] }, - "default_5": { - "description": "The LineRenderingConfig gives all details onto how to render a single line of a feature.\n\nThis can be used if:\n\n- The feature is a line\n- The feature is an area", - "type": "object", - "properties": { - "color": { - "description": "The color for way-elements and SVG-elements.\nIf the value starts with \"--\", the style of the body element will be queried for the corresponding variable instead", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "width": { - "description": "The stroke-width for way-elements", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": [ - "string", - "number" - ] - } - ] - }, - "dashArray": { - "description": "A dasharray, e.g. \"5 6\"\nThe dasharray defines 'pixels of line, pixels of gap, pixels of line, pixels of gap',\nDefault value: \"\" (empty string == full line)", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "lineCap": { - "description": "The form at the end of a line", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "fill": { - "description": "Wehter or not to fill polygons", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "enum": [ - "no", - "yes" - ], - "type": "string" - } - ] - }, - "fillColor": { - "description": "The color to fill a polygon with.\nIf undefined, this will be slightly more opaque version of the stroke line", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "string" - } - ] - }, - "offset": { - "description": "The number of pixels this line should be moved.\nUse a positive numbe to move to the right, a negative to move to the left (left/right as defined by the drawing direction of the line).\n\nIMPORTANT: MapComplete will already normalize 'key:both:property' and 'key:both' into the corresponding 'key:left' and 'key:right' tagging (same for 'sidewalk=left/right/both' which is rewritten to 'sidewalk:left' and 'sidewalk:right')\nThis simplifies programming. Refer to the CalculatedTags.md-documentation for more details", - "anyOf": [ - { - "$ref": "#/definitions/TagRenderingConfigJson" - }, - { - "type": "number" - } - ] - } - } - }, - "QuestionableTagRenderingConfigJson": { - "description": "A QuestionableTagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nIf the desired tags are missing and a question is defined, a question will be shown instead.", - "type": "object", - "properties": { - "question": { - "description": "If it turns out that this tagRendering doesn't match _any_ value, then we show this question.\nIf undefined, the question is never asked and this tagrendering is read-only" - }, - "freeform": { - "description": "Allow freeform text input from the user", - "type": "object", - "properties": { - "key": { - "type": "string" - }, - "type": { - "description": "The type of the text-field, e.g. 'string', 'nat', 'float', 'date',...\nSee Docs/SpecialInputElements.md and UI/Input/ValidatedTextField.ts for supported values", - "type": "string" - }, - "placeholder": { - "description": "A (translated) text that is shown (as gray text) within the textfield" - }, - "helperArgs": { - "description": "Extra parameters to initialize the input helper arguments.\nFor semantics, see the 'SpecialInputElements.md'", - "type": "array", - "items": {} - }, - "addExtraTags": { - "description": "If a value is added with the textfield, these extra tag is addded.\nUseful to add a 'fixme=freeform textfield used - to be checked'", - "type": "array", - "items": { - "type": "string" - } - }, - "inline": { - "description": "When set, influences the way a question is asked.\nInstead of showing a full-widht text field, the text field will be shown within the rendering of the question.\n\nThis combines badly with special input elements, as it'll distort the layout.", - "type": "boolean" - }, - "default": { - "description": "default value to enter if no previous tagging is present.\nNormally undefined (aka do not enter anything)", - "type": "string" - } - }, - "required": [ - "key" - ] - }, - "multiAnswer": { - "description": "If true, use checkboxes instead of radio buttons when asking the question", - "type": "boolean" - }, - "mappings": { - "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", - "type": "array", - "items": { - "type": "object", - "properties": { - "if": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "then": { - "description": "Shown if the 'if is fulfilled\nType: rendered" - }, - "icon": { - "description": "An extra icon supporting the choice\nType: icon", - "anyOf": [ - { - "type": "object", - "properties": { - "path": { - "description": "The path to the icon\nType: icon", - "type": "string" - }, - "class": { - "description": "Size of the image", - "type": "string" - } - }, - "required": [ - "class", - "path" - ] - }, - { - "type": "string" - } - ] - }, - "hideInAnswer": { - "description": "In some cases, multiple taggings exist (e.g. a default assumption, or a commonly mapped abbreviation and a fully written variation).\n\nIn the latter case, a correct text should be shown, but only a single, canonical tagging should be selectable by the user.\nIn this case, one of the mappings can be hiden by setting this flag.\n\nTo demonstrate an example making a default assumption:\n\nmappings: [\n {\n if: \"access=\", -- no access tag present, we assume accessible\n then: \"Accessible to the general public\",\n hideInAnswer: true\n },\n {\n if: \"access=yes\",\n then: \"Accessible to the general public\", -- the user selected this, we add that to OSM\n },\n {\n if: \"access=no\",\n then: \"Not accessible to the public\"\n }\n]\n\n\nFor example, for an operator, we have `operator=Agentschap Natuur en Bos`, which is often abbreviated to `operator=ANB`.\nThen, we would add two mappings:\n{\n if: \"operator=Agentschap Natuur en Bos\" -- the non-abbreviated version which should be uploaded\n then: \"Maintained by Agentschap Natuur en Bos\"\n},\n{\n if: \"operator=ANB\", -- we don't want to upload abbreviations\n then: \"Maintained by Agentschap Natuur en Bos\"\n hideInAnswer: true\n}\n\nHide in answer can also be a tagsfilter, e.g. to make sure an option is only shown when appropriate.\nKeep in mind that this is reverse logic: it will be hidden in the answer if the condition is true, it will thus only show in the case of a mismatch\n\ne.g., for toilets: if \"wheelchair=no\", we know there is no wheelchair dedicated room.\nFor the location of the changing table, the option \"in the wheelchair accessible toilet is weird\", so we write:\n\n{\n \"question\": \"Where is the changing table located?\"\n \"mappings\": [\n {\"if\":\"changing_table:location=female\",\"then\":\"In the female restroom\"},\n {\"if\":\"changing_table:location=male\",\"then\":\"In the male restroom\"},\n {\"if\":\"changing_table:location=wheelchair\",\"then\":\"In the wheelchair accessible restroom\", \"hideInAnswer\": \"wheelchair=no\"},\n \n ]\n}\n\nAlso have a look for the meta-tags\n{\n if: \"operator=Agentschap Natuur en Bos\",\n then: \"Maintained by Agentschap Natuur en Bos\",\n hideInAnswer: \"_country!=be\"\n}", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": [ - "string", - "boolean" - ] - } - ] - }, - "ifnot": { - "description": "Only applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "addExtraTags": { - "description": "If chosen as answer, these tags will be applied as well onto the object.\nNot compatible with multiAnswer", - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "if", - "then" - ] - } - }, - "id": { - "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", - "type": "string" - }, - "group": { - "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", - "type": "string" - }, - "labels": { - "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", - "type": "array", - "items": { - "type": "string" - } - }, - "render": { - "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" - }, - "condition": { - "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } - } - }, - "default<(string|QuestionableTagRenderingConfigJson|{builtin:string;override:any;})[]>": { - "type": "object", - "properties": { - "rewrite": { - "type": "object", - "properties": { - "sourceString": { - "type": "array", - "items": { - "type": "string" - } - }, - "into": { - "type": "array", - "items": { - "type": "array", - "items": {} - } - } - }, - "required": [ - "into", - "sourceString" - ] - }, - "renderings": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/QuestionableTagRenderingConfigJson" - }, - { - "type": "object", - "properties": { - "builtin": { - "type": "string" - }, - "override": {} - }, - "required": [ - "builtin", - "override" - ] - }, - { - "type": "string" - } - ] - } - } - }, - "required": [ - "renderings", - "rewrite" - ] - }, - "default_1": { - "type": "object", - "properties": { - "id": { - "description": "An id/name for this filter, used to set the URL parameters", - "type": "string" - }, - "options": { - "description": "The options for a filter\nIf there are multiple options these will be a list of radio buttons\nIf there is only one option this will be a checkbox\nFiltering is done based on the given osmTags that are compared to the objects in that layer.", - "type": "array", - "items": { - "type": "object", - "properties": { - "question": {}, - "osmTags": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - }, - "default": { - "type": "boolean" - }, - "fields": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "type": { - "type": "string" - } - }, - "required": [ - "name" - ] - } - } - }, - "required": [ - "question" - ] - } - } - }, - "required": [ + "required": [ + "defaultState", "id", - "options" - ] - }, - "DeleteConfigJson": { - "type": "object", - "properties": { - "extraDeleteReasons": { - "description": "*\nBy default, three reasons to delete a point are shown:\n\n- The point does not exist anymore\n- The point was a testing point\n- THe point could not be found\n\nHowever, for some layers, there might be different or more specific reasons for deletion which can be user friendly to set, e.g.:\n\n- the shop has closed\n- the climbing route has been closed of for nature conservation reasons\n- ...\n\nThese reasons can be stated here and will be shown in the list of options the user can choose from", - "type": "array", - "items": { + "source" + ], + "definitions": { + "AndOrTagConfigJson": { "type": "object", "properties": { - "explanation": { - "description": "The text that will be shown to the user - translatable" - }, - "changesetMessage": { - "description": "The text that will be uploaded into the changeset or will be used in the fixme in case of a soft deletion\nShould be a few words, in english", - "type": "string" - } - }, - "required": [ - "changesetMessage", - "explanation" - ] - } - }, - "nonDeleteMappings": { - "description": "In some cases, a (starting) contributor might wish to delete a feature even though deletion is not appropriate.\n(The most relevant case are small paths running over private property. These should be marked as 'private' instead of deleted, as the community might trace the path again from aerial imagery, gettting us back to the original situation).\n\nBy adding a 'nonDeleteMapping', an option can be added into the list which will retag the feature.\nIt is important that the feature will be retagged in such a way that it won't be picked up by the layer anymore!", - "type": "array", - "items": { - "type": "object", - "properties": { - "if": { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - "then": {} - }, - "required": [ - "if", - "then" - ] - } - }, - "softDeletionTags": { - "description": "In some cases, the contributor is not allowed to delete the current feature (e.g. because it isn't a point, the point is referenced by a relation or the user isn't experienced enough).\nTo still offer the user a 'delete'-option, the feature is retagged with these tags. This is a soft deletion, as the point isn't actually removed from OSM but rather marked as 'disused'\nIt is important that the feature will be retagged in such a way that it won't be picked up by the layer anymore!\n\nExample (note that \"amenity=\" erases the 'amenity'-key alltogether):\n```\n{\n \"and\": [\"disussed:amenity=public_bookcase\", \"amenity=\"]\n}\n```\n\nor (notice the use of the ':='-tag to copy the old value of 'shop=*' into 'disused:shop='):\n```\n{\n \"and\": [\"disused:shop:={shop}\", \"shop=\"]\n}\n```", - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" + "and": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "or": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + } } - ] }, - "neededChangesets": { - "description": "*\nBy default, the contributor needs 20 previous changesets to delete points edited by others.\nFor some small features (e.g. bicycle racks) this is too much and this requirement can be lowered or dropped, which can be done here.", - "type": "number" + "ApplicableUnitJson": { + "type": "object", + "properties": { + "canonicalDenomination": { + "description": "The canonical value which will be added to the text.\ne.g. \"m\" for meters\nIf the user inputs '42', the canonical value will be added and it'll become '42m'", + "type": "string" + }, + "canonicalDenominationSingular": { + "description": "The canonical denomination in the case that the unit is precisely '1'", + "type": "string" + }, + "alternativeDenomination": { + "description": "A list of alternative values which can occur in the OSM database - used for parsing.", + "type": "array", + "items": { + "type": "string" + } + }, + "human": { + "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"meter\",\n \"fr\": \"metre\"\n}" + }, + "humanSingular": { + "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"minute\",\n \"nl\": \"minuut\"x²\n}" + }, + "prefix": { + "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", + "type": "boolean" + }, + "default": { + "description": "The default interpretation - only one can be set.\nIf none is set, the first unit will be considered the default interpretation of a value without a unit", + "type": "boolean" + } + }, + "required": [ + "canonicalDenomination" + ] + }, + "TagRenderingConfigJson": { + "description": "A TagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nFor an _editable_ tagRenerdering, use 'QuestionableTagRenderingConfigJson' instead, which extends this one", + "type": "object", + "properties": { + "id": { + "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", + "type": "string" + }, + "group": { + "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", + "type": "string" + }, + "labels": { + "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", + "type": "array", + "items": { + "type": "string" + } + }, + "render": { + "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" + }, + "condition": { + "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "freeform": { + "description": "Allow freeform text input from the user", + "type": "object", + "properties": { + "key": { + "description": "If this key is present, then 'render' is used to display the value.\nIf this is undefined, the rendering is _always_ shown", + "type": "string" + } + }, + "required": [ + "key" + ] + }, + "mappings": { + "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", + "type": "array", + "items": { + "type": "object", + "properties": { + "if": { + "description": "If this condition is met, then the text under `then` will be shown.\nIf no value matches, and the user selects this mapping as an option, then these tags will be uploaded to OSM.\n\nFor example: {'if': 'diet:vegetarion=yes', 'then':'A vegetarian option is offered here'}\n\nThis can be an substituting-tag as well, e.g. {'if': 'addr:street:={_calculated_nearby_streetname}', 'then': '{_calculated_nearby_streetname}'}", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "then": { + "description": "If the condition `if` is met, the text `then` will be rendered.\nIf not known yet, the user will be presented with `then` as an option\nType: rendered" + }, + "icon": { + "description": "An icon supporting this mapping; typically shown pretty small\nType: icon", + "anyOf": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "A hint to mapcomplete on how to render this icon within the mapping.\nThis is translated to 'mapping-icon-', so defining your own in combination with a custom CSS is possible (but discouraged)", + "type": "string" + } + }, + "required": [ + "class", + "path" + ] + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "if", + "then" + ] + } + } + } + }, + "T": { + "type": "object" + }, + "default_4": { + "description": "The PointRenderingConfig gives all details onto how to render a single point of a feature.\n\nThis can be used if:\n\n- The feature is a point\n- To render something at the centroid of an area, or at the start, end or projected centroid of a way", + "type": "object", + "properties": { + "location": { + "description": "All the locations that this point should be rendered at.\nUsing `location: [\"point\", \"centroid\"] will always render centerpoint", + "type": "array", + "items": { + "type": "string" + } + }, + "icon": { + "description": "The icon for an element.\nNote that this also doubles as the icon for this layer (rendered with the overpass-tags) ánd the icon in the presets.\n\nThe result of the icon is rendered as follows:\nthe resulting string is interpreted as a _list_ of items, separated by \";\". The bottommost layer is the first layer.\nAs a result, on could use a generic pin, then overlay it with a specific icon.\nTo make things even more practical, one can use all SVG's from the folder \"assets/svg\" and _substitute the color_ in it.\nE.g. to draw a red pin, use \"pin:#f00\", to have a green circle with your icon on top, use `circle:#0f0;`\n\nType: icon", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "iconBadges": { + "description": "A list of extra badges to show next to the icon as small badge\nThey will be added as a 25% height icon at the bottom right of the icon, with all the badges in a flex layout.\n\nNote: strings are interpreted as icons, so layering and substituting is supported. You can use `circle:white;./my_icon.svg` to add a background circle", + "type": "array", + "items": { + "type": "object", + "properties": { + "if": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "then": { + "description": "Badge to show\nType: icon", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "if", + "then" + ] + } + }, + "iconSize": { + "description": "A string containing \"width,height\" or \"width,height,anchorpoint\" where anchorpoint is any of 'center', 'top', 'bottom', 'left', 'right', 'bottomleft','topright', ...\nDefault is '40,40,center'", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "rotation": { + "description": "The rotation of an icon, useful for e.g. directions.\nUsage: as if it were a css property for 'rotate', thus has to end with 'deg', e.g. `90deg`, `{direction}deg`, `calc(90deg - {camera:direction}deg)``", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "label": { + "description": "A HTML-fragment that is shown below the icon, for example:\n
{name}
\n\nIf the icon is undefined, then the label is shown in the center of the feature.\nNote that, if the wayhandling hides the icon then no label is shown as well.", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "location" + ] + }, + "default_5": { + "description": "The LineRenderingConfig gives all details onto how to render a single line of a feature.\n\nThis can be used if:\n\n- The feature is a line\n- The feature is an area", + "type": "object", + "properties": { + "color": { + "description": "The color for way-elements and SVG-elements.\nIf the value starts with \"--\", the style of the body element will be queried for the corresponding variable instead", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "width": { + "description": "The stroke-width for way-elements", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": [ + "string", + "number" + ] + } + ] + }, + "dashArray": { + "description": "A dasharray, e.g. \"5 6\"\nThe dasharray defines 'pixels of line, pixels of gap, pixels of line, pixels of gap',\nDefault value: \"\" (empty string == full line)", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "lineCap": { + "description": "The form at the end of a line", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "fill": { + "description": "Wehter or not to fill polygons", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "enum": [ + "no", + "yes" + ], + "type": "string" + } + ] + }, + "fillColor": { + "description": "The color to fill a polygon with.\nIf undefined, this will be slightly more opaque version of the stroke line", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "string" + } + ] + }, + "offset": { + "description": "The number of pixels this line should be moved.\nUse a positive numbe to move to the right, a negative to move to the left (left/right as defined by the drawing direction of the line).\n\nIMPORTANT: MapComplete will already normalize 'key:both:property' and 'key:both' into the corresponding 'key:left' and 'key:right' tagging (same for 'sidewalk=left/right/both' which is rewritten to 'sidewalk:left' and 'sidewalk:right')\nThis simplifies programming. Refer to the CalculatedTags.md-documentation for more details", + "anyOf": [ + { + "$ref": "#/definitions/TagRenderingConfigJson" + }, + { + "type": "number" + } + ] + } + } + }, + "QuestionableTagRenderingConfigJson": { + "description": "A QuestionableTagRenderingConfigJson is a single piece of code which converts one ore more tags into a HTML-snippet.\nIf the desired tags are missing and a question is defined, a question will be shown instead.", + "type": "object", + "properties": { + "question": { + "description": "If it turns out that this tagRendering doesn't match _any_ value, then we show this question.\nIf undefined, the question is never asked and this tagrendering is read-only" + }, + "freeform": { + "description": "Allow freeform text input from the user", + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "type": { + "description": "The type of the text-field, e.g. 'string', 'nat', 'float', 'date',...\nSee Docs/SpecialInputElements.md and UI/Input/ValidatedTextField.ts for supported values", + "type": "string" + }, + "placeholder": { + "description": "A (translated) text that is shown (as gray text) within the textfield" + }, + "helperArgs": { + "description": "Extra parameters to initialize the input helper arguments.\nFor semantics, see the 'SpecialInputElements.md'", + "type": "array", + "items": {} + }, + "addExtraTags": { + "description": "If a value is added with the textfield, these extra tag is addded.\nUseful to add a 'fixme=freeform textfield used - to be checked'", + "type": "array", + "items": { + "type": "string" + } + }, + "inline": { + "description": "When set, influences the way a question is asked.\nInstead of showing a full-widht text field, the text field will be shown within the rendering of the question.\n\nThis combines badly with special input elements, as it'll distort the layout.", + "type": "boolean" + }, + "default": { + "description": "default value to enter if no previous tagging is present.\nNormally undefined (aka do not enter anything)", + "type": "string" + } + }, + "required": [ + "key" + ] + }, + "multiAnswer": { + "description": "If true, use checkboxes instead of radio buttons when asking the question", + "type": "boolean" + }, + "mappings": { + "description": "Allows fixed-tag inputs, shown either as radiobuttons or as checkboxes", + "type": "array", + "items": { + "type": "object", + "properties": { + "if": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "then": { + "description": "Shown if the 'if is fulfilled\nType: rendered" + }, + "icon": { + "description": "An extra icon supporting the choice\nType: icon", + "anyOf": [ + { + "type": "object", + "properties": { + "path": { + "description": "The path to the icon\nType: icon", + "type": "string" + }, + "class": { + "description": "Size of the image", + "type": "string" + } + }, + "required": [ + "class", + "path" + ] + }, + { + "type": "string" + } + ] + }, + "hideInAnswer": { + "description": "In some cases, multiple taggings exist (e.g. a default assumption, or a commonly mapped abbreviation and a fully written variation).\n\nIn the latter case, a correct text should be shown, but only a single, canonical tagging should be selectable by the user.\nIn this case, one of the mappings can be hiden by setting this flag.\n\nTo demonstrate an example making a default assumption:\n\nmappings: [\n {\n if: \"access=\", -- no access tag present, we assume accessible\n then: \"Accessible to the general public\",\n hideInAnswer: true\n },\n {\n if: \"access=yes\",\n then: \"Accessible to the general public\", -- the user selected this, we add that to OSM\n },\n {\n if: \"access=no\",\n then: \"Not accessible to the public\"\n }\n]\n\n\nFor example, for an operator, we have `operator=Agentschap Natuur en Bos`, which is often abbreviated to `operator=ANB`.\nThen, we would add two mappings:\n{\n if: \"operator=Agentschap Natuur en Bos\" -- the non-abbreviated version which should be uploaded\n then: \"Maintained by Agentschap Natuur en Bos\"\n},\n{\n if: \"operator=ANB\", -- we don't want to upload abbreviations\n then: \"Maintained by Agentschap Natuur en Bos\"\n hideInAnswer: true\n}\n\nHide in answer can also be a tagsfilter, e.g. to make sure an option is only shown when appropriate.\nKeep in mind that this is reverse logic: it will be hidden in the answer if the condition is true, it will thus only show in the case of a mismatch\n\ne.g., for toilets: if \"wheelchair=no\", we know there is no wheelchair dedicated room.\nFor the location of the changing table, the option \"in the wheelchair accessible toilet is weird\", so we write:\n\n{\n \"question\": \"Where is the changing table located?\"\n \"mappings\": [\n {\"if\":\"changing_table:location=female\",\"then\":\"In the female restroom\"},\n {\"if\":\"changing_table:location=male\",\"then\":\"In the male restroom\"},\n {\"if\":\"changing_table:location=wheelchair\",\"then\":\"In the wheelchair accessible restroom\", \"hideInAnswer\": \"wheelchair=no\"},\n \n ]\n}\n\nAlso have a look for the meta-tags\n{\n if: \"operator=Agentschap Natuur en Bos\",\n then: \"Maintained by Agentschap Natuur en Bos\",\n hideInAnswer: \"_country!=be\"\n}", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": [ + "string", + "boolean" + ] + } + ] + }, + "ifnot": { + "description": "Only applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "addExtraTags": { + "description": "If chosen as answer, these tags will be applied as well onto the object.\nNot compatible with multiAnswer", + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "if", + "then" + ] + } + }, + "id": { + "description": "The id of the tagrendering, should be an unique string.\nUsed to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise.\n\nUse 'questions' to trigger the question box of this group (if a group is defined)", + "type": "string" + }, + "group": { + "description": "If 'group' is defined on many tagRenderings, these are grouped together when shown. The questions are grouped together as well.\nThe first tagRendering of a group will always be a sticky element.", + "type": "string" + }, + "labels": { + "description": "A list of labels. These are strings that are used for various purposes, e.g. to filter them away", + "type": "array", + "items": { + "type": "string" + } + }, + "render": { + "description": "Renders this value. Note that \"{key}\"-parts are substituted by the corresponding values of the element.\nIf neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value.\n\nNote that this is a HTML-interpreted value, so you can add links as e.g. '{website}' or include images such as `This is of type A
`\ntype: rendered" + }, + "condition": { + "description": "Only show this tagrendering (or question) if the object also matches the following tags.\n\nThis is useful to ask a follow-up question. E.g. if there is a diaper table, then ask a follow-up question on diaper tables...", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + } + }, + "default<(string|QuestionableTagRenderingConfigJson|{builtin:string;override:any;})[]>": { + "type": "object", + "properties": { + "rewrite": { + "type": "object", + "properties": { + "sourceString": { + "type": "array", + "items": { + "type": "string" + } + }, + "into": { + "type": "array", + "items": { + "type": "array", + "items": {} + } + } + }, + "required": [ + "into", + "sourceString" + ] + }, + "renderings": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/QuestionableTagRenderingConfigJson" + }, + { + "type": "object", + "properties": { + "builtin": { + "type": "string" + }, + "override": {} + }, + "required": [ + "builtin", + "override" + ] + }, + { + "type": "string" + } + ] + } + } + }, + "required": [ + "renderings", + "rewrite" + ] + }, + "default_1": { + "type": "object", + "properties": { + "id": { + "description": "An id/name for this filter, used to set the URL parameters", + "type": "string" + }, + "options": { + "description": "The options for a filter\nIf there are multiple options these will be a list of radio buttons\nIf there is only one option this will be a checkbox\nFiltering is done based on the given osmTags that are compared to the objects in that layer.", + "type": "array", + "items": { + "type": "object", + "properties": { + "question": {}, + "osmTags": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "default": { + "type": "boolean" + }, + "fields": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "name" + ] + } + } + }, + "required": [ + "question" + ] + } + } + }, + "required": [ + "id", + "options" + ] + }, + "DeleteConfigJson": { + "type": "object", + "properties": { + "extraDeleteReasons": { + "description": "*\nBy default, three reasons to delete a point are shown:\n\n- The point does not exist anymore\n- The point was a testing point\n- THe point could not be found\n\nHowever, for some layers, there might be different or more specific reasons for deletion which can be user friendly to set, e.g.:\n\n- the shop has closed\n- the climbing route has been closed of for nature conservation reasons\n- ...\n\nThese reasons can be stated here and will be shown in the list of options the user can choose from", + "type": "array", + "items": { + "type": "object", + "properties": { + "explanation": { + "description": "The text that will be shown to the user - translatable" + }, + "changesetMessage": { + "description": "The text that will be uploaded into the changeset or will be used in the fixme in case of a soft deletion\nShould be a few words, in english", + "type": "string" + } + }, + "required": [ + "changesetMessage", + "explanation" + ] + } + }, + "nonDeleteMappings": { + "description": "In some cases, a (starting) contributor might wish to delete a feature even though deletion is not appropriate.\n(The most relevant case are small paths running over private property. These should be marked as 'private' instead of deleted, as the community might trace the path again from aerial imagery, gettting us back to the original situation).\n\nBy adding a 'nonDeleteMapping', an option can be added into the list which will retag the feature.\nIt is important that the feature will be retagged in such a way that it won't be picked up by the layer anymore!", + "type": "array", + "items": { + "type": "object", + "properties": { + "if": { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + "then": {} + }, + "required": [ + "if", + "then" + ] + } + }, + "softDeletionTags": { + "description": "In some cases, the contributor is not allowed to delete the current feature (e.g. because it isn't a point, the point is referenced by a relation or the user isn't experienced enough).\nTo still offer the user a 'delete'-option, the feature is retagged with these tags. This is a soft deletion, as the point isn't actually removed from OSM but rather marked as 'disused'\nIt is important that the feature will be retagged in such a way that it won't be picked up by the layer anymore!\n\nExample (note that \"amenity=\" erases the 'amenity'-key alltogether):\n```\n{\n \"and\": [\"disussed:amenity=public_bookcase\", \"amenity=\"]\n}\n```\n\nor (notice the use of the ':='-tag to copy the old value of 'shop=*' into 'disused:shop='):\n```\n{\n \"and\": [\"disused:shop:={shop}\", \"shop=\"]\n}\n```", + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + }, + "neededChangesets": { + "description": "*\nBy default, the contributor needs 20 previous changesets to delete points edited by others.\nFor some small features (e.g. bicycle racks) this is too much and this requirement can be lowered or dropped, which can be done here.", + "type": "number" + } + } + }, + "default_3": { + "type": "object", + "properties": { + "enableImproveAccuracy": { + "description": "One default reason to move a point is to improve accuracy.\nSet to false to disable this reason", + "type": "boolean" + }, + "enableRelocation": { + "description": "One default reason to move a point is because it has relocated\nSet to false to disable this reason", + "type": "boolean" + } + } + }, + "default_2": { + "type": "object", + "properties": { + "appliesToKey": { + "description": "Every key from this list will be normalized", + "type": "array", + "items": { + "type": "string" + } + }, + "eraseInvalidValues": { + "description": "If set, invalid values will be erased in the MC application (but not in OSM of course!)\nBe careful with setting this", + "type": "boolean" + }, + "applicableUnits": { + "description": "The possible denominations", + "type": "array", + "items": { + "$ref": "#/definitions/ApplicableUnitJson" + } + } + }, + "required": [ + "applicableUnits", + "appliesToKey" + ] } - } }, - "default_3": { - "type": "object", - "properties": { - "enableImproveAccuracy": { - "description": "One default reason to move a point is to improve accuracy.\nSet to false to disable this reason", - "type": "boolean" - }, - "enableRelocation": { - "description": "One default reason to move a point is because it has relocated\nSet to false to disable this reason", - "type": "boolean" - } - } - }, - "default_2": { - "type": "object", - "properties": { - "appliesToKey": { - "description": "Every key from this list will be normalized", - "type": "array", - "items": { - "type": "string" - } - }, - "eraseInvalidValues": { - "description": "If set, invalid values will be erased in the MC application (but not in OSM of course!)\nBe careful with setting this", - "type": "boolean" - }, - "applicableUnits": { - "description": "The possible denominations", - "type": "array", - "items": { - "$ref": "#/definitions/ApplicableUnitJson" - } - } - }, - "required": [ - "applicableUnits", - "appliesToKey" - ] - } - }, - "$schema": "http://json-schema.org/draft-07/schema#" + "$schema": "http://json-schema.org/draft-07/schema#" } \ No newline at end of file diff --git a/Docs/Schemas/UnitConfigJsonJSC.ts b/Docs/Schemas/UnitConfigJsonJSC.ts index 9e8fa3c0d1..8c141bffe5 100644 --- a/Docs/Schemas/UnitConfigJsonJSC.ts +++ b/Docs/Schemas/UnitConfigJsonJSC.ts @@ -1,98 +1,98 @@ export default { - "type": "object", - "properties": { - "appliesToKey": { - "description": "Every key from this list will be normalized", - "type": "array", - "items": { - "type": "string" - } - }, - "eraseInvalidValues": { - "description": "If set, invalid values will be erased in the MC application (but not in OSM of course!)\nBe careful with setting this", - "type": "boolean" - }, - "applicableUnits": { - "description": "The possible denominations", - "type": "array", - "items": { - "$ref": "#/definitions/ApplicableUnitJson" - } - } - }, - "required": [ - "applicableUnits", - "appliesToKey" - ], - "definitions": { - "AndOrTagConfigJson": { - "type": "object", - "properties": { - "and": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { + "type": "object", + "properties": { + "appliesToKey": { + "description": "Every key from this list will be normalized", + "type": "array", + "items": { "type": "string" - } - ] - } + } }, - "or": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/definitions/AndOrTagConfigJson" - }, - { - "type": "string" - } - ] - } + "eraseInvalidValues": { + "description": "If set, invalid values will be erased in the MC application (but not in OSM of course!)\nBe careful with setting this", + "type": "boolean" + }, + "applicableUnits": { + "description": "The possible denominations", + "type": "array", + "items": { + "$ref": "#/definitions/ApplicableUnitJson" + } } - } }, - "ApplicableUnitJson": { - "type": "object", - "properties": { - "canonicalDenomination": { - "description": "The canonical value which will be added to the text.\ne.g. \"m\" for meters\nIf the user inputs '42', the canonical value will be added and it'll become '42m'", - "type": "string" + "required": [ + "applicableUnits", + "appliesToKey" + ], + "definitions": { + "AndOrTagConfigJson": { + "type": "object", + "properties": { + "and": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + }, + "or": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/AndOrTagConfigJson" + }, + { + "type": "string" + } + ] + } + } + } }, - "canonicalDenominationSingular": { - "description": "The canonical denomination in the case that the unit is precisely '1'", - "type": "string" - }, - "alternativeDenomination": { - "description": "A list of alternative values which can occur in the OSM database - used for parsing.", - "type": "array", - "items": { - "type": "string" - } - }, - "human": { - "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"meter\",\n \"fr\": \"metre\"\n}" - }, - "humanSingular": { - "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"minute\",\n \"nl\": \"minuut\"x²\n}" - }, - "prefix": { - "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", - "type": "boolean" - }, - "default": { - "description": "The default interpretation - only one can be set.\nIf none is set, the first unit will be considered the default interpretation of a value without a unit", - "type": "boolean" + "ApplicableUnitJson": { + "type": "object", + "properties": { + "canonicalDenomination": { + "description": "The canonical value which will be added to the text.\ne.g. \"m\" for meters\nIf the user inputs '42', the canonical value will be added and it'll become '42m'", + "type": "string" + }, + "canonicalDenominationSingular": { + "description": "The canonical denomination in the case that the unit is precisely '1'", + "type": "string" + }, + "alternativeDenomination": { + "description": "A list of alternative values which can occur in the OSM database - used for parsing.", + "type": "array", + "items": { + "type": "string" + } + }, + "human": { + "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"meter\",\n \"fr\": \"metre\"\n}" + }, + "humanSingular": { + "description": "The value for humans in the dropdown. This should not use abbreviations and should be translated, e.g.\n{\n \"en\": \"minute\",\n \"nl\": \"minuut\"x²\n}" + }, + "prefix": { + "description": "If set, then the canonical value will be prefixed instead, e.g. for '€'\nNote that if all values use 'prefix', the dropdown might move to before the text field", + "type": "boolean" + }, + "default": { + "description": "The default interpretation - only one can be set.\nIf none is set, the first unit will be considered the default interpretation of a value without a unit", + "type": "boolean" + } + }, + "required": [ + "canonicalDenomination" + ] } - }, - "required": [ - "canonicalDenomination" - ] - } - }, - "$schema": "http://json-schema.org/draft-07/schema#" + }, + "$schema": "http://json-schema.org/draft-07/schema#" } \ No newline at end of file From b119e1ac1d7f1783d8474a84ec67a4e54c2bea13 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Mon, 4 Apr 2022 04:54:54 +0200 Subject: [PATCH 18/37] Import helper: Improve error messages of non-matching presets; fix bug if a value is 'null' in source geojson --- Logic/Tags/And.ts | 6 -- Logic/Tags/Or.ts | 6 -- Logic/Tags/TagUtils.ts | 28 +++++++++ Logic/Tags/TagsFilter.ts | 2 - Logic/Web/QueryParameters.ts | 6 +- UI/ImportFlow/AskMetadata.ts | 1 - UI/ImportFlow/CreateNotes.ts | 6 +- UI/ImportFlow/RequestFile.ts | 13 ++++ UI/ImportFlow/SelectTheme.ts | 93 +++++++++++++++++++++-------- package-lock.json | 14 ++--- package.json | 2 +- tests/Chai.spec.ts | 2 +- tests/scripts/GenerateCache.spec.ts | 5 +- 13 files changed, 131 insertions(+), 53 deletions(-) diff --git a/Logic/Tags/And.ts b/Logic/Tags/And.ts index fa79d3eda0..5a2eecbc9c 100644 --- a/Logic/Tags/And.ts +++ b/Logic/Tags/And.ts @@ -148,12 +148,6 @@ export class And extends TagsFilter { return result; } - AsJson() { - return { - and: this.and.map(a => a.AsJson()) - } - } - optimize(): TagsFilter | boolean { if(this.and.length === 0){ return true diff --git a/Logic/Tags/Or.ts b/Logic/Tags/Or.ts index 07f50629bd..4d3ab20e02 100644 --- a/Logic/Tags/Or.ts +++ b/Logic/Tags/Or.ts @@ -85,12 +85,6 @@ export class Or extends TagsFilter { return result; } - AsJson() { - return { - or: this.or.map(o => o.AsJson()) - } - } - optimize(): TagsFilter | boolean { if(this.or.length === 0){ diff --git a/Logic/Tags/TagUtils.ts b/Logic/Tags/TagUtils.ts index d72008136a..a496580ffe 100644 --- a/Logic/Tags/TagUtils.ts +++ b/Logic/Tags/TagUtils.ts @@ -167,6 +167,34 @@ export class TagUtils { return new Tag(tag[0], tag[1]); } + /** + * Returns wether or not a keys is (probably) a valid key. + * + * // should accept common keys + * TagUtils.isValidKey("name") // => true + * TagUtils.isValidKey("image:0") // => true + * TagUtils.isValidKey("alt_name") // => true + * + * // should refuse short keys + * TagUtils.isValidKey("x") // => false + * TagUtils.isValidKey("xy") // => false + * + * // should refuse a string with >255 characters + * let a255 = "" + * for(let i = 0; i < 255; i++) { a255 += "a"; } + * a255.length // => 255 + * TagUtils.isValidKey(a255) // => true + * TagUtils.isValidKey("a"+a255) // => false + * + * // Should refuse unexpected characters + * TagUtils.isValidKey("with space") // => false + * TagUtils.isValidKey("some$type") // => false + * TagUtils.isValidKey("_name") // => false + */ + public static isValidKey(key: string): boolean { + return key.match(/^[a-z][a-z0-9:_]{2,253}[a-z0-9]$/) !== null + } + /** * Parses a tag configuration (a json) into a TagsFilter * diff --git a/Logic/Tags/TagsFilter.ts b/Logic/Tags/TagsFilter.ts index c505fe1174..f3794436f5 100644 --- a/Logic/Tags/TagsFilter.ts +++ b/Logic/Tags/TagsFilter.ts @@ -26,8 +26,6 @@ export abstract class TagsFilter { */ abstract asChange(properties: any): { k: string, v: string }[] - abstract AsJson() ; - /** * Returns an optimized version (or self) of this tagsFilter */ diff --git a/Logic/Web/QueryParameters.ts b/Logic/Web/QueryParameters.ts index 6dc084305a..02a76dce5a 100644 --- a/Logic/Web/QueryParameters.ts +++ b/Logic/Web/QueryParameters.ts @@ -91,8 +91,10 @@ export class QueryParameters { parts.push(encodeURIComponent(key) + "=" + encodeURIComponent(QueryParameters.knownSources[key].data)) } - // Don't pollute the history every time a parameter changes - history.replaceState(null, "", "?" + parts.join("&") + Hash.Current()); + if(!Utils.runningFromConsole){ + // Don't pollute the history every time a parameter changes + history.replaceState(null, "", "?" + parts.join("&") + Hash.Current()); + } } } \ No newline at end of file diff --git a/UI/ImportFlow/AskMetadata.ts b/UI/ImportFlow/AskMetadata.ts index 203d44b3c7..975d0e6d99 100644 --- a/UI/ImportFlow/AskMetadata.ts +++ b/UI/ImportFlow/AskMetadata.ts @@ -93,7 +93,6 @@ export class AskMetadata extends Combine implements FlowStep<{ return false; } if ([ obj.features, obj.intro, obj.wikilink, obj.source].some(v => v === undefined)){ - console.log("Obj is", obj) return false; } diff --git a/UI/ImportFlow/CreateNotes.ts b/UI/ImportFlow/CreateNotes.ts index f364196f0f..1364d36751 100644 --- a/UI/ImportFlow/CreateNotes.ts +++ b/UI/ImportFlow/CreateNotes.ts @@ -30,10 +30,14 @@ export class CreateNotes extends Combine { const tags: string [] = [] for (const key in f.properties) { + if (f.properties[key] === null || f.properties[key] === undefined) { + console.warn("Null or undefined key for ", f.properties) + continue + } if (f.properties[key] === "") { continue } - tags.push(key + "=" + f.properties[key].replace(/=/, "\\=").replace(/;/g, "\\;").replace(/\n/g, "\\n")) + tags.push(key + "=" + (f.properties[key]+"").replace(/=/, "\\=").replace(/;/g, "\\;").replace(/\n/g, "\\n")) } const lat = f.geometry.coordinates[1] const lon = f.geometry.coordinates[0] diff --git a/UI/ImportFlow/RequestFile.ts b/UI/ImportFlow/RequestFile.ts index eaad85a5ac..e435758470 100644 --- a/UI/ImportFlow/RequestFile.ts +++ b/UI/ImportFlow/RequestFile.ts @@ -10,6 +10,8 @@ import FileSelectorButton from "../Input/FileSelectorButton"; import {FlowStep} from "./FlowStep"; import {parse} from "papaparse"; import {FixedUiElement} from "../Base/FixedUiElement"; +import {del} from "idb-keyval"; +import {TagUtils} from "../../Logic/Tags/TagUtils"; class FileSelector extends InputElementMap }> { constructor(label: BaseUIElement) { @@ -72,6 +74,17 @@ export class RequestFile extends Combine implements FlowStep<{features: any[]}> if (parsed.features.some(f => f.geometry.type != "Point")) { return {error: t.errPointsOnly} } + parsed.features.forEach(f => { + const props = f.properties + for (const key in props) { + if(props[key] === undefined || props[key] === null || props[key] === ""){ + delete props[key] + } + if(!TagUtils.isValidKey(key)){ + return {error: "Probably an invalid key: "+key} + } + } + }) return parsed; } catch (e) { diff --git a/UI/ImportFlow/SelectTheme.ts b/UI/ImportFlow/SelectTheme.ts index 45f0508c7a..1a84aee0f4 100644 --- a/UI/ImportFlow/SelectTheme.ts +++ b/UI/ImportFlow/SelectTheme.ts @@ -13,6 +13,9 @@ import {VariableUiElement} from "../Base/VariableUIElement"; import {FixedUiElement} from "../Base/FixedUiElement"; import Toggleable from "../Base/Toggleable"; import {BBox} from "../../Logic/BBox"; +import BaseUIElement from "../BaseUIElement"; +import PresetConfig from "../../Models/ThemeConfig/PresetConfig"; +import List from "../Base/List"; export default class SelectTheme extends Combine implements FlowStep<{ features: any[], @@ -29,7 +32,7 @@ export default class SelectTheme extends Combine implements FlowStep<{ }>; public readonly IsValid: UIEventSource; - constructor(params: ({ features: any[], layer: LayerConfig, bbox: BBox, })) { + constructor(params: ({ features: any[], layer: LayerConfig, bbox: BBox, })) { let options: InputElement[] = AllKnownLayouts.layoutsList .filter(th => th.layers.some(l => l.id === params.layer.id)) @@ -37,7 +40,7 @@ export default class SelectTheme extends Combine implements FlowStep<{ .map(th => new FixedInputElement( new Combine([ new Img(th.icon).SetClass("block h-12 w-12 br-4"), - new Title( th.title) + new Title(th.title) ]).SetClass("flex items-center"), th.id)) @@ -47,9 +50,8 @@ export default class SelectTheme extends Combine implements FlowStep<{ }) - const applicablePresets = themeRadios.GetValue().map(theme => { - if(theme === undefined){ + if (theme === undefined) { return [] } // we get the layer with the correct ID via the actual theme config, as the actual theme might have different presets due to overrides @@ -60,7 +62,7 @@ export default class SelectTheme extends Combine implements FlowStep<{ const nonMatchedElements = applicablePresets.map(presets => { - if(presets === undefined || presets.length === 0){ + if (presets === undefined || presets.length === 0) { return undefined } return params.features.filter(feat => !presets.some(preset => new And(preset.tags).matchesProperties(feat.properties))) @@ -71,27 +73,15 @@ export default class SelectTheme extends Combine implements FlowStep<{ "All of the following themes will show the import notes. However, the note on OpenStreetMap can link to only one single theme. Choose which theme that the created notes will link to", themeRadios, new VariableUiElement(applicablePresets.map(applicablePresets => { - if(themeRadios.GetValue().data === undefined){ + if (themeRadios.GetValue().data === undefined) { return undefined } - if(applicablePresets === undefined || applicablePresets.length === 0){ + if (applicablePresets === undefined || applicablePresets.length === 0) { return new FixedUiElement("This theme has no presets loaded. As a result, imports won't work here").SetClass("alert") } - },[themeRadios.GetValue()])), - new VariableUiElement(nonMatchedElements.map(unmatched => { - if(unmatched === undefined || unmatched.length === 0){ - return - } - return new Combine([new FixedUiElement(unmatched.length+" objects dont match any presets").SetClass("alert"), - ...applicablePresets.data.map(preset => preset.title.txt +" needs tags "+ preset.tags.map(t => t.asHumanString()).join(" & ")), - , - new Toggleable( new Title( "The following elements don't match any of the presets"), - new Combine( unmatched.map(feat => JSON.stringify(feat.properties))).SetClass("flex flex-col") - ) + }, [themeRadios.GetValue()])), - ]) .SetClass("flex flex-col") - - })) + new VariableUiElement(nonMatchedElements.map(unmatched => SelectTheme.nonMatchedElementsPanel(unmatched, applicablePresets.data), [applicablePresets])) ]); this.SetClass("flex flex-col") @@ -106,13 +96,13 @@ export default class SelectTheme extends Combine implements FlowStep<{ if (obj === undefined) { return false; } - if ([obj.theme, obj.features].some(v => v === undefined)){ + if ([obj.theme, obj.features].some(v => v === undefined)) { return false; } - if(applicablePresets.data === undefined || applicablePresets.data.length === 0){ + if (applicablePresets.data === undefined || applicablePresets.data.length === 0) { return false } - if((nonMatchedElements.data?.length??0) > 0){ + if ((nonMatchedElements.data?.length ?? 0) > 0) { return false; } @@ -121,5 +111,60 @@ export default class SelectTheme extends Combine implements FlowStep<{ }, [applicablePresets]) } + private static nonMatchedElementsPanel(unmatched: any[], applicablePresets: PresetConfig[]): BaseUIElement { + if (unmatched === undefined || unmatched.length === 0) { + return + } + + const applicablePresetsOverview = applicablePresets.map(preset => new Combine([ + preset.title.txt, "needs tags", + new FixedUiElement(preset.tags.map(t => t.asHumanString()).join(" & ")).SetClass("thanks") + ])) + + const unmatchedPanels: BaseUIElement[] = [] + for (const feat of unmatched) { + const parts: BaseUIElement[] = [] + parts.push(new Combine(Object.keys(feat.properties).map(k => + k+"="+feat.properties[k] + )).SetClass("flex flex-col")) + + for (const preset of applicablePresets) { + const tags = new And(preset.tags).asChange({}) + const missing = [] + for (const {k, v} of tags) { + if (preset[k] === undefined) { + missing.push( + `Expected ${k}=${v}, but it is completely missing` + ) + } else if (feat.properties[k] !== v) { + missing.push( + `Property with key ${k} does not have expected value ${v}; instead it is ${feat.properties}` + ) + } + } + + if (missing.length > 0) { + parts.push( + new Combine([ + new FixedUiElement(`Preset ${preset.title.txt} is not applicable:`), + new List(missing) + ]).SetClass("flex flex-col alert") + ) + } + + } + + unmatchedPanels.push(new Combine(parts).SetClass("flex flex-col")) + } + + return new Combine([ + new FixedUiElement(unmatched.length + " objects dont match any presets").SetClass("alert"), + ...applicablePresetsOverview, + new Toggleable(new Title("The following elements don't match any of the presets"), + new Combine(unmatchedPanels)) + ]).SetClass("flex flex-col") + + } + } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 48e04ca737..75394936b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "@types/wikidata-sdk": "^6.1.0", "@types/xml2js": "^0.4.9", "country-language": "^0.1.7", - "doctest-ts-improved": "^0.8.4", + "doctest-ts-improved": "^0.8.5", "email-validator": "^2.0.4", "escape-html": "^1.0.3", "geojson2svg": "^1.3.1", @@ -6024,9 +6024,9 @@ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, "node_modules/doctest-ts-improved": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/doctest-ts-improved/-/doctest-ts-improved-0.8.4.tgz", - "integrity": "sha512-CMVSnyDB00sLkTqHIZ20Z/kHD2XczNHwWkD4UC4retGaSfuP8XG4cnAGwkr8qoQq3mjc3w8O4w3OTWrC4HC2vA==", + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/doctest-ts-improved/-/doctest-ts-improved-0.8.5.tgz", + "integrity": "sha512-4zU8fQV263CU3jAi+K7xohhT9b2ZDGw20M4O7AgzW1IoKklmNkSlHMoKZX6gqN1DAouo08R+MD5aSgACG5ILRw==", "dependencies": { "@types/chai": "^4.3.0", "chai": "^4.3.6", @@ -21413,9 +21413,9 @@ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, "doctest-ts-improved": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/doctest-ts-improved/-/doctest-ts-improved-0.8.4.tgz", - "integrity": "sha512-CMVSnyDB00sLkTqHIZ20Z/kHD2XczNHwWkD4UC4retGaSfuP8XG4cnAGwkr8qoQq3mjc3w8O4w3OTWrC4HC2vA==", + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/doctest-ts-improved/-/doctest-ts-improved-0.8.5.tgz", + "integrity": "sha512-4zU8fQV263CU3jAi+K7xohhT9b2ZDGw20M4O7AgzW1IoKklmNkSlHMoKZX6gqN1DAouo08R+MD5aSgACG5ILRw==", "requires": { "@types/chai": "^4.3.0", "chai": "^4.3.6", diff --git a/package.json b/package.json index d1a39a6e8d..3dbdf1b945 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "@types/wikidata-sdk": "^6.1.0", "@types/xml2js": "^0.4.9", "country-language": "^0.1.7", - "doctest-ts-improved": "^0.8.4", + "doctest-ts-improved": "^0.8.5", "email-validator": "^2.0.4", "escape-html": "^1.0.3", "geojson2svg": "^1.3.1", diff --git a/tests/Chai.spec.ts b/tests/Chai.spec.ts index cc11fcb7f1..b7a2f54db9 100644 --- a/tests/Chai.spec.ts +++ b/tests/Chai.spec.ts @@ -4,7 +4,7 @@ import {Utils} from "../Utils"; describe("TestSuite", () => { - describe("function onder test", () => { + describe("function under test", () => { it("should work", () => { expect("abc").eq("abc") }) diff --git a/tests/scripts/GenerateCache.spec.ts b/tests/scripts/GenerateCache.spec.ts index e24a72d692..e5be78431b 100644 --- a/tests/scripts/GenerateCache.spec.ts +++ b/tests/scripts/GenerateCache.spec.ts @@ -9,9 +9,10 @@ import {main} from "../../scripts/generateCache"; function initDownloads(query: string){ + const d = {"version":0.6,"generator":"Overpass API 0.7.57 93a4d346","osm3s":{"timestamp_osm_base":"2022-02-13T23:54:06Z","copyright":"The data included in this document is from www.openstreetmap.org. The data is made available under ODbL."},"elements":[{"type":"node","id":518224450,"lat":51.1548065,"lon":3.1880118,"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"street_side"}},{"type":"node","id":665418924,"lat":51.1575547,"lon":3.20522,"tags":{"amenity":"parking"}},{"type":"node","id":1168727903,"lat":51.1299141,"lon":3.1776123,"tags":{"amenity":"drinking_water","mapillary":"https://www.mapillary.com/app/?lat=51.129853685131906&lng=3.177603984688602&z=17&pKey=SEyKzIMUeKssni1ZLVe-9A&focus=photo&dateTo=2017-04-02&dateFrom=2017-04-01&x=0.5168826751181941&y=0.6114877557873634&zoom=0"}},{"type":"node","id":1168728245,"lat":51.1290938,"lon":3.1767502,"tags":{"amenity":"drinking_water","mapillary":"https://www.mapillary.com/app/?lat=51.129104406662464&lng=3.176675795895676&z=17&pKey=vSP3D_hWv3XCBtH75GnYUQ&focus=photo&dateTo=2017-04-02&dateFrom=2017-04-01"}},{"type":"node","id":1725842653,"lat":51.153364,"lon":3.2352655,"tags":{"amenity":"bench"}},{"type":"node","id":1744641290,"lat":51.1389321,"lon":3.2385407,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":1746891135,"lat":51.1598841,"lon":3.2361425,"tags":{"amenity":"bench"}},{"type":"node","id":1810326078,"lat":51.1550855,"lon":3.2349358,"tags":{"amenity":"bench"}},{"type":"node","id":1810326092,"lat":51.1552302,"lon":3.234968,"tags":{"amenity":"bench"}},{"type":"node","id":2325437742,"lat":51.1770052,"lon":3.1967794,"tags":{"board_type":"board","information":"board","name":"Tillegembos","tourism":"information"}},{"type":"node","id":2325437743,"lat":51.1787363,"lon":3.1949036,"tags":{"board_type":"board","information":"board","name":"Tillegembos","tourism":"information"}},{"type":"node","id":2325437813,"lat":51.1733102,"lon":3.1895672,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437839,"lat":51.1763436,"lon":3.1984985,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437848,"lat":51.1770966,"lon":3.1963507,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437862,"lat":51.1773439,"lon":3.1948779,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437867,"lat":51.1775994,"lon":3.1888088,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437873,"lat":51.1778384,"lon":3.1913802,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2732486257,"lat":51.129741,"lon":3.1907419,"tags":{"board_type":"nature","information":"board","name":"Doeveren","tourism":"information"}},{"type":"node","id":3774054068,"lat":51.1586662,"lon":3.2271102,"tags":{"amenity":"bench"}},{"type":"node","id":4769106605,"lat":51.138264,"lon":3.1798655,"tags":{"backrest":"yes","leisure":"picnic_table"}},{"type":"node","id":4912238707,"lat":51.1448634,"lon":3.2455986,"tags":{"access":"yes","amenity":"parking","fee":"no","name":"Oostkamp","parking":"Carpool"}},{"type":"node","id":5637212235,"lat":51.1305439,"lon":3.1866873,"tags":{"board_type":"nature","image":"https://i.imgur.com/HehOQL9.jpg","information":"board","name":"Welkom Doeveren","tourism":"information"}},{"type":"node","id":5637224573,"lat":51.1281084,"lon":3.1881726,"tags":{"board_type":"nature","information":"board","name":"Welkom Doeveren","tourism":"information"}},{"type":"node","id":5637230107,"lat":51.1280884,"lon":3.1889798,"tags":{"information":"board","tourism":"information"}},{"type":"node","id":5637743026,"lat":51.1295973,"lon":3.1751122,"tags":{"information":"board","name":"Doeveren Wandelroute","tourism":"information"}},{"type":"node","id":5716130103,"lat":51.1767183,"lon":3.1947867,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":5745783208,"lat":51.1782581,"lon":3.2410111,"tags":{"amenity":"bench"}},{"type":"node","id":5745807545,"lat":51.1784037,"lon":3.2369439,"tags":{"amenity":"bench"}},{"type":"node","id":5745807551,"lat":51.1783278,"lon":3.236678,"tags":{"amenity":"bench"}},{"type":"node","id":6535241426,"lat":51.1693142,"lon":3.1673093,"tags":{"amenity":"bench"}},{"type":"node","id":6535241427,"lat":51.169265,"lon":3.1673159,"tags":{"amenity":"bench"}},{"type":"node","id":6535241428,"lat":51.1692199,"lon":3.1673224,"tags":{"amenity":"bench"}},{"type":"node","id":6535241430,"lat":51.1685726,"lon":3.1678225,"tags":{"bench":"yes","leisure":"picnic_table","material":"wood"}},{"type":"node","id":6536026827,"lat":51.1703142,"lon":3.1691109,"tags":{"leisure":"picnic_table"}},{"type":"node","id":6536026828,"lat":51.1702795,"lon":3.1691552,"tags":{"leisure":"picnic_table"}},{"type":"node","id":6712112244,"lat":51.1595064,"lon":3.2021482,"tags":{"leisure":"picnic_table"}},{"type":"node","id":7304050040,"lat":51.1560908,"lon":3.1748919,"tags":{"amenity":"bench"}},{"type":"node","id":7304050041,"lat":51.1560141,"lon":3.1749533,"tags":{"amenity":"bench"}},{"type":"node","id":7304050042,"lat":51.156032,"lon":3.1749379,"tags":{"amenity":"bench"}},{"type":"node","id":7439979218,"lat":51.1780402,"lon":3.2178666,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":7439979219,"lat":51.1780508,"lon":3.2179033,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":7529262982,"lat":51.1585566,"lon":3.1715528,"tags":{"board_type":"map","information":"board","tourism":"information"}},{"type":"node","id":7529262984,"lat":51.1585786,"lon":3.1715385,"tags":{"leisure":"picnic_table"}},{"type":"node","id":7554879668,"lat":51.1573713,"lon":3.2043731,"tags":{"access":"yes","amenity":"toilets","fee":"no","toilets:disposal":"flush","unisex":"yes","wheelchair":"yes"}},{"type":"node","id":7554879669,"lat":51.1594855,"lon":3.2021507,"tags":{"leisure":"picnic_table"}},{"type":"node","id":7556988723,"lat":51.1330234,"lon":3.1839944,"tags":{"amenity":"bench","material":"wood"}},{"type":"node","id":7575825326,"lat":51.1386553,"lon":3.1797358,"tags":{"amenity":"bench"}},{"type":"node","id":7575825327,"lat":51.1382456,"lon":3.1797422,"tags":{"information":"board","tourism":"information"}},{"type":"node","id":8109498958,"lat":51.1332267,"lon":3.2341272,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":8109498959,"lat":51.1335011,"lon":3.2343954,"tags":{"leisure":"picnic_table"}},{"type":"node","id":8198894646,"lat":51.125688,"lon":3.1856217,"tags":{"image":"https://i.imgur.com/O5kX20u.jpg","information":"board","tourism":"information"}},{"type":"node","id":8199012519,"lat":51.1262245,"lon":3.1802429,"tags":{"image":"https://i.imgur.com/tomw9p5.jpg","information":"board","tourism":"information"}},{"type":"node","id":8199244816,"lat":51.1252874,"lon":3.1837622,"tags":{"amenity":"bench"}},{"type":"node","id":8199301617,"lat":51.1256827,"lon":3.1853543,"tags":{"amenity":"bench","backrest":"no"}},{"type":"node","id":8255488518,"lat":51.1406698,"lon":3.235178,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":9316104741,"lat":51.1330984,"lon":3.2335257,"tags":{"information":"board","tourism":"information"}},{"type":"node","id":9442532340,"lat":51.1763651,"lon":3.1947952,"tags":{"amenity":"bench","backrest":"yes","image":"https://i.imgur.com/eZ0Loii.jpg"}},{"type":"way","id":15242261,"nodes":[150996092,150996093,6754312552,6754312553,6754312550,6754312551,150996094,150996095,150996097,150996098,6754312560,6754312559,6754312558,150996099,6754312557,150996100,6754312555,6754312556,150996101,6754312554,150996092],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":16514228,"nodes":[170464837,170464839,170464840,170464841,170464837],"tags":{"access":"yes","amenity":"parking","fee":"no","maxstay":"4 hours","parking":"surface"}},{"type":"way","id":76706071,"nodes":[903903386,1038557094,1038557233,1038557143,1038557075,903903387,1038557195,903903388,903903390,903904576,903903386],"tags":{"access":"permissive","amenity":"parking"}},{"type":"way","id":89601157,"nodes":[1038557083,1038557078,1038557104,1038557072,1038557108,1038557230,1038557227,1038557102,1038557137,1038575040,1038557191,1038557014,6960473080,1038557035,1038557012,1038557083],"tags":{"amenity":"parking"}},{"type":"way","id":89604999,"nodes":[1038583404,1038583491,1038583375,1038583483,1038583479,1038583398,1038583459,1038583456,1038583446,1038583441,1038583425,1038583501,1038583451,1038583463,1038583476,1038583404],"tags":{"access":"yes","amenity":"parking","capacity":"57","carpool":"yes","description":"carpoolparking","fee":"no","name":"Loppem","parking":"surface"}},{"type":"way","id":92035679,"nodes":[1069177920,6853179264,1069177925,1069177919,6853179269,6853179268,6853179267,6853179215,6853179213,6853179214,1069178133,1069177984,6853179230,6853179228,6853179229,6853179224,6853179225,6853179227,6853179226,6853179216,6853179220,6853179219,6853179218,6853179217,6853179223,6853179221,6853179222,1069177967,1069177852,6853179211,6853179212,6853179210,6853179327,6853179208,6853179209,6853179203,1069177976,6853179207,6853179206,6853179205,6853179204,6853179202,1069177849,6852012579,6852012578,6852012580,6852012577,6852012581,6852012582,6852012583,1069177845,1759437085,1519342743,1519342742,1069178166,1069177853,1069177915,6853179235,6853179234,6853179236,1069177933,6853179237,6853179238,1069178021,6853179246,6853179244,6853179245,6853179240,6853179243,6853179241,6853179242,6853179239,6853179248,6853179249,6853179250,6853179247,1069177873,6853179262,6853179263,6853179260,6853179261,6853179256,6853179259,6853179257,6853179258,1069177920],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":101248451,"nodes":[1168728158,1168728325,1168728159,5637669355,1168728109,1168728158],"tags":{"access":"private","amenity":"parking","name":"Parking Merkenveld"}},{"type":"way","id":101248462,"nodes":[1168727876,1168728288,1168728412,1168728208,1168727876],"tags":{"amenity":"toilets","building":"yes","source:geometry:date":"2019-03-14","source:geometry:ref":"Gbg/6588148"}},{"type":"way","id":131622387,"nodes":[1448421093,1448421099,1448421091,1448421081,1448421093],"tags":{"amenity":"parking","name":"Tudor - Zeeweg","parking":"surface"}},{"type":"way","id":145691934,"nodes":[1590642859,1590642860,1590642858,1590642849,1590642859],"tags":{"amenity":"parking"}},{"type":"way","id":145691937,"nodes":[1590642829,1590642828,1590642830,1590642832,1590642829],"tags":{"amenity":"parking"}},{"type":"way","id":158901716,"nodes":[1710245713,1710245718,1710245707,1710245705,1710245703,1710245715,1710245711,1710245709,1710245701,1710245713],"tags":{"access":"yes","amenity":"parking","capacity":"14","fee":"no","parking":"surface"}},{"type":"way","id":158904558,"nodes":[1710262742,1710262745,1710262735,1710262733,1710262732,1710262743,1710262741,1710262739,1710262744,1710262737,1710262736,1710262731,1710262738,1710262742],"tags":{"access":"yes","alt_name":"Schoolparking","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":158906028,"nodes":[1710276259,1710276251,1810330766,1710276255,1710276261,1710276240,1710276232,1710276257,1710276243,1710276253,1810347217,1710276242,1710276259],"tags":{"access":"yes","amenity":"parking","fee":"no","name":"Parking Sportcentrum De Valkaart","parking":"surface"}},{"type":"way","id":160825858,"nodes":[1728421375,1728421374,1728421379,1728421377,1728421376,1728421378,1728421375],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":162602213,"nodes":[1920143232,7393009684,7393048385,1744641293,1523513488,1744641292,1920143232],"tags":{"amenity":"parking","capacity":"15"}},{"type":"way","id":165489167,"nodes":[4912197370,4912197365,4912197373,4912197364,4912197372,1770289505,4912197362,4912197371,4912197374,4912197363,4912197368,4912197366,4912197369,4912197367,4912197370],"tags":{"access":"yes","amenity":"parking","fee":"no","name":"Bad Neuheimplein","parking":"surface"}},{"type":"way","id":168291852,"nodes":[1795793399,4979389763,1795793409,1795793395,1795793393,1795793397,1795793407,1795793406,1795793408,1795793405,1795793399],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":169875513,"nodes":[1810345951,1810345955,1810345947,1810345944,1810345951],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":170015605,"nodes":[1811673425,1811673421,1811673418,1811673423,1811673425],"tags":{"access":"private","amenity":"parking","name":"gheeraert E40","operator":"Gheeraert"}},{"type":"way","id":170018487,"nodes":[1811699779,1811699778,1811699776,1811699777,1811699779],"tags":{"access":"private","amenity":"parking","name":"Gheeraert vooraan"}},{"type":"way","id":170559194,"nodes":[1817319304,1817319302,1817319297,1817319301,1817319304],"tags":{"access":"private","amenity":"parking","name":"Gheeraert laadkade"}},{"type":"way","id":170559195,"nodes":[1817319299,1817319303,1817319300,1817319292,1817319299],"tags":{"access":"private","amenity":"parking","name":"Gheeraert spoorweg trailers"}},{"type":"way","id":170559196,"nodes":[1817319293,1817319289,1817319291,1817319296,1817319293],"tags":{"access":"private","amenity":"parking","name":"Gheeraert spoorweg trucks"}},{"type":"way","id":170559197,"nodes":[1817319294,1817319298,1817319295,1817319290,1817319294],"tags":{"access":"private","amenity":"parking","name":"Gheeraert zijkant"}},{"type":"way","id":170559292,"nodes":[1817320496,1817320494,1817320493,1817320495,1817320496],"tags":{"access":"private","amenity":"parking","name":"Gheeraert vooraan gebouw"}},{"type":"way","id":170559832,"nodes":[1817324515,1817324509,1817324491,6397031888,4044172008,4044172003,4044171997,4044171962,4044171957,4044171976,1817324489,1817324488,3550860268,1817324505,3550860269,1817324513,1817324515],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":223674368,"nodes":[2325437844,8191691971,8191691973,8191691972,2325437840,8191691970,414025563,2325437844],"tags":{"amenity":"parking","name":"Tillegembos","parking":"surface"}},{"type":"way","id":237214948,"nodes":[2451574741,2451574742,2451574744,1015583939,2451574741],"tags":{"access":"private","amenity":"parking"}},{"type":"way","id":237214949,"nodes":[2451574748,2451574746,2451574747,2451574749,2451574748],"tags":{"access":"private","amenity":"parking"}},{"type":"way","id":237214950,"nodes":[2451569392,1015567837,2451574745,2451574743,2451578121,2451569392],"tags":{"access":"private","amenity":"parking"}},{"type":"way","id":325909586,"nodes":[3325315243,111759500,3325315247,3325315232,3325315230,3325315226,1169056712,3325315243],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":326834162,"nodes":[3335137807,3335137692,3335137795,9163493632,3335137802,3335137812,9163486855,9163486856,3335137823,3335137807],"tags":{"access":"customers","amenity":"parking","operator":"Best Western Weinebrugge","parking":"surface"}},{"type":"way","id":327849054,"nodes":[3346575929,3346575873,3346575876,3346575843,3346575845,3346575891,3346575901,3346575923,3346575928,3346575950,3346575929],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":327849055,"nodes":[3346575945,3346575946,3346575943,3346575933,3346575925,3346575917,3346575903,3346575908,3346575889,3346575886,3346575945],"tags":{"access":"customers","amenity":"parking","parking":"surface"}},{"type":"way","id":327849056,"nodes":[3346575865,3346575853,3346575855,3346575846,3346575840,3346575858,3346575865],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":374677860,"nodes":[3780611504,3780611502,3780611500,3780611503,3780611504],"tags":{"amenity":"parking"}},{"type":"way","id":374677861,"nodes":[3780611495,3780611493,3780611492,3780611494,3780611495],"tags":{"amenity":"parking"}},{"type":"way","id":374677862,"nodes":[3780611498,3780611497,3780611496,3780611499,3780611501,3780611498],"tags":{"amenity":"parking"}},{"type":"way","id":389912371,"nodes":[3930713440,3930713451,3930713447,3930713437,3930713440],"tags":{"amenity":"parking"}},{"type":"way","id":389912372,"nodes":[3930713454,3930713442,3930713435,3930713429,5826811614,3930713426,3930713430,6982605752,6982605754,3930713438,6982605769,6982605766,6982605767,6982605762,6982605764,3930713446,3930713454],"tags":{"access":"customers","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":401995684,"nodes":[4044171963,4044171954,4044171924,4044171936,4044171941,4044171963],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":500067820,"nodes":[4912203166,4912203165,4912203164,4912203163,4912203162,4912203161,4912203160,4912203166],"tags":{"access":"yes","amenity":"parking","parking":"surface"}},{"type":"way","id":500067821,"nodes":[4912203170,4912203169,4912203168,4912203167,4912203170],"tags":{"access":"yes","amenity":"parking","parking":"surface"}},{"type":"way","id":500067822,"nodes":[4912203174,4912203173,4912203172,4912203171,4912203174],"tags":{"access":"yes","amenity":"parking","parking":"surface"}},{"type":"way","id":500067823,"nodes":[4912203179,4912203178,4912203177,4912203176,4912203179],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":500069613,"nodes":[4912214695,4912214685,4912214694,4912214693,4912214692,4912214680,4912214695],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":500071452,"nodes":[4912225068,4912225062,4912225063,4912225053,4912225064,4912214694,4912214685,4912225068],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":500071455,"nodes":[4912225070,4912214681,4912214686,4912225052,4912225051,4912225067,4912225062,4912225068,4912225070],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":500071458,"nodes":[4912214695,4912214680,4912225069,4912225050,1525460846,4912214681,4912225070,4912214695],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":533276307,"nodes":[5173881316,5173881317,5173881318,7054196467,5173881316],"tags":{"amenity":"parking"}},{"type":"way","id":533276308,"nodes":[5173881320,5173881621,5173881622,5173881623,5173881320],"tags":{"amenity":"parking"}},{"type":"way","id":533276309,"nodes":[5173881624,5173881625,5173881626,5173881627,5173881624],"tags":{"amenity":"parking"}},{"type":"way","id":579848581,"nodes":[4043782112,5825400688,5552466020,6997096756,6997096759,6997096758,5552466018,5552466013,5552466014,6997076567,4043782112],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":584455569,"nodes":[5586765933,5586765934,5586765935,5586765936,5586765933],"tags":{"amenity":"parking"}},{"type":"way","id":585977870,"nodes":[5587844460,5599314384,5599314385,1659850846,6870850178,5587844462,5587844461,6870863414,5587844460],"tags":{"amenity":"parking"}},{"type":"way","id":587014342,"nodes":[5607796820,5607798725,5607798721,5607798722,5607796819,5607798723,5607796820],"tags":{"access":"permissive","amenity":"parking","park_ride":"no","parking":"surface","surface":"paved"}},{"type":"way","id":590167103,"nodes":[5635001277,5635001274,5635001275,5635001276,5635001277],"tags":{"amenity":"parking"}},{"type":"way","id":590167113,"nodes":[5635001312,5635001306,7767137237,7767137235,7767137236,7767137234,5635001312],"tags":{"amenity":"parking"}},{"type":"way","id":590167134,"nodes":[5635001374,5635001373,5635001372,5635001371,5635001374],"tags":{"amenity":"parking"}},{"type":"way","id":590167135,"nodes":[5635001378,5635001377,5635001376,5635001375,5635001378],"tags":{"amenity":"parking"}},{"type":"way","id":590167136,"nodes":[5635001382,5635001381,5635001380,5635001379,5635001382],"tags":{"amenity":"parking"}},{"type":"way","id":590167137,"nodes":[5635001386,5882873336,5882873337,5882873338,5882873335,6593340582,6593340583,5882873334,6593340584,5635001385,5635001384,5635001383,5635001386],"tags":{"amenity":"parking"}},{"type":"way","id":590167147,"nodes":[5635001417,5635001414,5635001415,5635001416,5635001417],"tags":{"amenity":"parking"}},{"type":"way","id":601406079,"nodes":[5716136617,5716136618,5716136619,5716136620,5716136617],"tags":{"amenity":"parking"}},{"type":"way","id":632813009,"nodes":[5974489618,1810326044,1810326087,5974489617,5972179348,5972179347,5972179346,5972179345,5972179344,5972179343,5972179331,5974489616,5974489615,5974489614,5974489618],"tags":{"amenity":"parking","name":"Gemeenteplein","parking":"surface"}},{"type":"way","id":668043297,"nodes":[6255587424,6255587425,6255587426,6255587427,6255587424],"tags":{"access":"private","amenity":"parking"}},{"type":"way","id":670104236,"nodes":[6275462768,6275462769,6275462770,6275462771,6275462768],"tags":{"amenity":"parking"}},{"type":"way","id":670104238,"nodes":[6275462772,6275462989,6275462773,6275462774,6275462775,6275462772],"tags":{"amenity":"parking"}},{"type":"way","id":670104239,"nodes":[6275462776,6275462777,6275462778,6275462779,6275462776],"tags":{"amenity":"parking"}},{"type":"way","id":670104241,"nodes":[6275462780,6275462781,6275462782,6275462783,6275462780],"tags":{"amenity":"parking"}},{"type":"way","id":670104242,"nodes":[6275462784,6275462985,6275462988,6275462986,6275462987,6275462784],"tags":{"amenity":"parking"}},{"type":"way","id":671840055,"nodes":[6291339827,6291339828,6291339816,6291339815,6291339822,6291339821,6291339829,6291339830,6291339827],"tags":{"amenity":"parking"}},{"type":"way","id":695825223,"nodes":[1519476746,6533893620,6533893621,6533893622,1519476797,1519476620,1519476746],"tags":{"access":"yes","amenity":"parking"}},{"type":"way","id":695825224,"nodes":[1519476744,6533893624,6533893625,6533893626,1519476698,1519476635,1519476744],"tags":{"access":"yes","amenity":"parking"}},{"type":"way","id":696040917,"nodes":[6536026850,6536026851,6536026852,6536026853,6536026850],"tags":{"amenity":"parking","name":"Kasteel Tudor"}},{"type":"way","id":696043218,"nodes":[6536038234,6536038235,6536038236,6536038237,6536038234],"tags":{"access":"customers","amenity":"parking"}},{"type":"way","id":700675991,"nodes":[6579962064,6579962065,6579962066,6579962068,6579962067,6579962064],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":705278707,"nodes":[6625037999,6625038000,6625038001,6625038002,6625038003,6004375826,6625038005,6625038006,6625037999],"tags":{"amenity":"parking"}},{"type":"way","id":719482833,"nodes":[6754312544,6754312543,6754312542,6754312541,6754312544],"tags":{"access":"yes","amenity":"parking","capacity":"5"}},{"type":"way","id":719482834,"nodes":[6754312565,6754312564,6754312563,6754312562,6754312565],"tags":{"access":"yes","amenity":"parking","capacity":"12"}},{"type":"way","id":737054013,"nodes":[5826811496,5826811497,5826811494,5826811495,5826811496],"tags":{"amenity":"parking"}},{"type":"way","id":737054014,"nodes":[5826810676,5826810673,5826810674,5826810675,5826810676],"tags":{"amenity":"parking"}},{"type":"way","id":737054015,"nodes":[5826810681,5826810678,5826810679,5826810680,5826810681],"tags":{"amenity":"parking"}},{"type":"way","id":737093410,"nodes":[5826811559,5826811536,5826811535,5826811561,5826811560,5826811559],"tags":{"access":"yes","amenity":"parking","capacity":"4","fee":"no","parking":"surface"}},{"type":"way","id":737093411,"nodes":[5826811551,5826811547,5826811548,5826811549,5826811550,5826811551],"tags":{"access":"yes","amenity":"parking","capacity":"4","fee":"no","parking":"surface"}},{"type":"way","id":739652949,"nodes":[6925536542,6925536541,6925536540,6925536539,6925536542],"tags":{"amenity":"parking","capacity":"6","parking":"surface"}},{"type":"way","id":741675236,"nodes":[6943148207,6943148206,6943148205,6943148204,1637742821,6943148203,6943148202,6943148201,6943148200,6943148199,6943148198,6943148197,6943148207],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":742295526,"nodes":[6949357909,6949357908,6949357907,6949357906,6949357909],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":742295527,"nodes":[6949357913,6949357912,6949357911,6949357910,6949357913],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":742295528,"nodes":[6949357917,6949357916,6949357915,6949357914,6949357917],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":742295529,"nodes":[6949357921,6949357920,6949357919,6949357918,6949357921],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":746170866,"nodes":[6982906547,6982906546,6982906545,6982906544,6982906543,6982906542,6982906547],"tags":{"access":"customers","amenity":"parking"}},{"type":"way","id":747880657,"nodes":[3325315397,6997076566,6997076565,6997076563,6997076562,6997076564,3325315395,3325315397],"tags":{"access":"customers","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":763977465,"nodes":[7137343680,7137343681,7137343682,7137343683,7137343680],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":763977466,"nodes":[7137343684,7137383185,7137383186,7137383187,7137343684],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":803821090,"nodes":[7519058290,7519058289,7519058288,7519058287,7519058290],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":803821091,"nodes":[7519058294,7519058293,7519058292,7519058291,7519058294],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":803821092,"nodes":[7519058298,7519058297,7519058296,7519058295,7519058298],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":803821093,"nodes":[7519058302,7519058301,7519058300,7519058299,7519058302],"tags":{"access":"private","amenity":"parking","capacity":"6","parking":"surface"}},{"type":"way","id":804963962,"nodes":[7529417225,7529417226,7529417227,7529417228,7529417229,7529417230,7529417232,7529417225],"tags":{"access":"customers","amenity":"parking","fee":"no","operator":"’t Kiekekot","parking":"surface","surface":"unpaved"}},{"type":"way","id":806875503,"nodes":[4042671969,7545532512,7545532514,7545532513,3359977305,4042671969],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":806963547,"nodes":[7546193222,7546193221,7546193220,7546193219,7546193222],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":865357121,"nodes":[8065883228,8065883227,8065883226,8065883225,8065883228],"tags":{"amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":865357122,"nodes":[8065883233,8065883230,8065883229,8065883232,8065883233],"tags":{"amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":879281221,"nodes":[8179735269,8179735268,8179735267,8179735266,8179735265,8179735264,8179735224,8179735269],"tags":{"access":"customers","amenity":"parking","parking":"surface"}},{"type":"way","id":881770201,"nodes":[8200275847,8200275848,8200275844,8200275853,8200275849,8200275847],"tags":{"amenity":"parking","parking":"surface","surface":"grass"}},{"type":"way","id":978360549,"nodes":[5761770202,5761770204,9052878229,9052878228,5761770202],"tags":{"amenity":"parking"}},{"type":"way","id":1009692722,"nodes":[9316118540,9316118536,9316118531,9316118535,9316118534,9316118533,9316118530,9316118532,3311835478,9316118540],"tags":{"amenity":"parking","parking":"street_side"}},{"type":"relation","id":8188853,"members":[{"type":"way","ref":577572397,"role":"outer"},{"type":"way","ref":577572399,"role":"outer"}],"tags":{"access":"guided","curator":"Luc Maene;Geert De Clercq","email":"lucmaene@hotmail.com;geert.de.clercq1@pandora.be","landuse":"meadow","leisure":"nature_reserve","name":"De Wulgenbroeken","natural":"wetland","operator":"Natuurpunt Brugge","type":"multipolygon","website":"https://natuurpuntbrugge.be/wulgenbroeken/","wetland":"wet_meadow","wikidata":"Q60061498","wikipedia":"nl:Wulgenbroeken"}},{"type":"relation","id":11163488,"members":[{"type":"way","ref":810604915,"role":"outer"},{"type":"way","ref":989393316,"role":"outer"},{"type":"way","ref":389026405,"role":"inner"},{"type":"way","ref":810607458,"role":"outer"}],"tags":{"access":"yes","curator":"Kris Lesage","description":"Wat Doeveren zo uniek maakt, zijn zijn kleine heidegebiedjes met soorten die erg verschillen van de Kempense heide. Doeveren en omstreken was vroeger één groot heidegebied, maar bestaat nu grotendeels uit bossen.","dog":"leashed","email":"doeveren@natuurpuntzedelgem.be","image":"https://i.imgur.com/NEAsQZG.jpg","image:0":"https://i.imgur.com/Dq71hyQ.jpg","image:1":"https://i.imgur.com/mAIiT4f.jpg","image:2":"https://i.imgur.com/dELZU97.jpg","image:3":"https://i.imgur.com/Bso57JC.jpg","image:4":"https://i.imgur.com/9DtcfXo.jpg","image:5":"https://i.imgur.com/0R6eBfk.jpg","image:6":"https://i.imgur.com/b0JpvbR.jpg","leisure":"nature_reserve","name":"Doeveren","operator":"Natuurpunt Zedelgem","phone":"+32 486 25 25 30","type":"multipolygon","website":"https://www.natuurpuntzedelgem.be/gebieden/doeveren/","wikidata":"Q56395754","wikipedia":"nl:Doeveren (natuurgebied)"}},{"type":"relation","id":11790117,"members":[{"type":"way","ref":863373849,"role":"outer"},{"type":"way","ref":777280458,"role":"outer"}],"tags":{"access":"no","description:0":"In gebruik als waterbuffering","leisure":"nature_reserve","name":"Kerkebeek","operator":"Natuurpunt Brugge","type":"multipolygon"}},{"type":"node","id":518224450,"lat":51.1548065,"lon":3.1880118,"timestamp":"2021-08-14T21:49:28Z","version":5,"changeset":109683837,"user":"effem","uid":16437,"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"street_side"}},{"type":"node","id":665418924,"lat":51.1575547,"lon":3.20522,"timestamp":"2012-05-12T20:13:39Z","version":2,"changeset":11580224,"user":"martino260","uid":655442,"tags":{"amenity":"parking"}},{"type":"node","id":1168727903,"lat":51.1299141,"lon":3.1776123,"timestamp":"2017-04-03T08:34:05Z","version":2,"changeset":47403889,"user":"philippec","uid":76884,"tags":{"amenity":"drinking_water","mapillary":"https://www.mapillary.com/app/?lat=51.129853685131906&lng=3.177603984688602&z=17&pKey=SEyKzIMUeKssni1ZLVe-9A&focus=photo&dateTo=2017-04-02&dateFrom=2017-04-01&x=0.5168826751181941&y=0.6114877557873634&zoom=0"}},{"type":"node","id":1168728245,"lat":51.1290938,"lon":3.1767502,"timestamp":"2019-10-07T11:06:57Z","version":3,"changeset":75370316,"user":"Hopperpop","uid":3664604,"tags":{"amenity":"drinking_water","mapillary":"https://www.mapillary.com/app/?lat=51.129104406662464&lng=3.176675795895676&z=17&pKey=vSP3D_hWv3XCBtH75GnYUQ&focus=photo&dateTo=2017-04-02&dateFrom=2017-04-01"}},{"type":"node","id":1725842653,"lat":51.153364,"lon":3.2352655,"timestamp":"2012-07-02T17:33:00Z","version":2,"changeset":12090625,"user":"martino260","uid":655442,"tags":{"amenity":"bench"}},{"type":"node","id":1744641290,"lat":51.1389321,"lon":3.2385407,"timestamp":"2012-09-18T13:29:52Z","version":3,"changeset":13156159,"user":"martino260","uid":655442,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":1746891135,"lat":51.1598841,"lon":3.2361425,"timestamp":"2012-05-09T18:22:11Z","version":1,"changeset":11551825,"user":"martino260","uid":655442,"tags":{"amenity":"bench"}},{"type":"node","id":1810326078,"lat":51.1550855,"lon":3.2349358,"timestamp":"2012-07-02T19:50:15Z","version":1,"changeset":12093439,"user":"martino260","uid":655442,"tags":{"amenity":"bench"}},{"type":"node","id":1810326092,"lat":51.1552302,"lon":3.234968,"timestamp":"2012-07-02T19:50:16Z","version":1,"changeset":12093439,"user":"martino260","uid":655442,"tags":{"amenity":"bench"}},{"type":"node","id":2325437742,"lat":51.1770052,"lon":3.1967794,"timestamp":"2013-05-30T12:19:08Z","version":1,"changeset":16350909,"user":"peeweeke","uid":494726,"tags":{"board_type":"board","information":"board","name":"Tillegembos","tourism":"information"}},{"type":"node","id":2325437743,"lat":51.1787363,"lon":3.1949036,"timestamp":"2013-05-30T12:19:08Z","version":1,"changeset":16350909,"user":"peeweeke","uid":494726,"tags":{"board_type":"board","information":"board","name":"Tillegembos","tourism":"information"}},{"type":"node","id":2325437813,"lat":51.1733102,"lon":3.1895672,"timestamp":"2013-05-30T12:19:09Z","version":1,"changeset":16350909,"user":"peeweeke","uid":494726,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437839,"lat":51.1763436,"lon":3.1984985,"timestamp":"2013-05-30T12:19:10Z","version":1,"changeset":16350909,"user":"peeweeke","uid":494726,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437848,"lat":51.1770966,"lon":3.1963507,"timestamp":"2013-05-30T12:19:10Z","version":1,"changeset":16350909,"user":"peeweeke","uid":494726,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437862,"lat":51.1773439,"lon":3.1948779,"timestamp":"2013-05-30T12:19:10Z","version":1,"changeset":16350909,"user":"peeweeke","uid":494726,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437867,"lat":51.1775994,"lon":3.1888088,"timestamp":"2013-05-30T12:19:11Z","version":1,"changeset":16350909,"user":"peeweeke","uid":494726,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437873,"lat":51.1778384,"lon":3.1913802,"timestamp":"2013-05-30T12:19:11Z","version":1,"changeset":16350909,"user":"peeweeke","uid":494726,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2732486257,"lat":51.129741,"lon":3.1907419,"timestamp":"2014-03-21T21:15:28Z","version":1,"changeset":21234491,"user":"meannder","uid":149496,"tags":{"board_type":"nature","information":"board","name":"Doeveren","tourism":"information"}},{"type":"node","id":3774054068,"lat":51.1586662,"lon":3.2271102,"timestamp":"2015-10-05T20:34:04Z","version":1,"changeset":34456387,"user":"TripleBee","uid":497177,"tags":{"amenity":"bench"}},{"type":"node","id":4769106605,"lat":51.138264,"lon":3.1798655,"timestamp":"2020-05-31T19:49:45Z","version":3,"changeset":86019474,"user":"Hopperpop","uid":3664604,"tags":{"backrest":"yes","leisure":"picnic_table"}},{"type":"node","id":4912238707,"lat":51.1448634,"lon":3.2455986,"timestamp":"2017-06-13T08:12:04Z","version":1,"changeset":49491753,"user":"Jakka","uid":2403313,"tags":{"access":"yes","amenity":"parking","fee":"no","name":"Oostkamp","parking":"Carpool"}},{"type":"node","id":5637212235,"lat":51.1305439,"lon":3.1866873,"timestamp":"2021-11-22T11:54:45Z","version":4,"changeset":114095475,"user":"L'imaginaire","uid":654234,"tags":{"board_type":"nature","image":"https://i.imgur.com/HehOQL9.jpg","information":"board","name":"Welkom Doeveren","tourism":"information"}},{"type":"node","id":5637224573,"lat":51.1281084,"lon":3.1881726,"timestamp":"2020-06-01T22:39:30Z","version":2,"changeset":86065716,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"board_type":"nature","information":"board","name":"Welkom Doeveren","tourism":"information"}},{"type":"node","id":5637230107,"lat":51.1280884,"lon":3.1889798,"timestamp":"2018-05-23T11:55:01Z","version":1,"changeset":59208628,"user":"Jakka","uid":2403313,"tags":{"information":"board","tourism":"information"}},{"type":"node","id":5637743026,"lat":51.1295973,"lon":3.1751122,"timestamp":"2021-10-08T08:53:14Z","version":2,"changeset":112251989,"user":"DieterWesttoer","uid":13062237,"tags":{"information":"board","name":"Doeveren Wandelroute","tourism":"information"}},{"type":"node","id":5716130103,"lat":51.1767183,"lon":3.1947867,"timestamp":"2018-06-24T22:04:21Z","version":1,"changeset":60130942,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":5745783208,"lat":51.1782581,"lon":3.2410111,"timestamp":"2018-07-07T18:42:23Z","version":1,"changeset":60494990,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"amenity":"bench"}},{"type":"node","id":5745807545,"lat":51.1784037,"lon":3.2369439,"timestamp":"2018-07-07T18:58:25Z","version":1,"changeset":60495307,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"amenity":"bench"}},{"type":"node","id":5745807551,"lat":51.1783278,"lon":3.236678,"timestamp":"2018-07-07T18:58:25Z","version":1,"changeset":60495307,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"amenity":"bench"}},{"type":"node","id":6535241426,"lat":51.1693142,"lon":3.1673093,"timestamp":"2019-06-09T13:50:19Z","version":1,"changeset":71071874,"user":"Hopperpop","uid":3664604,"tags":{"amenity":"bench"}},{"type":"node","id":6535241427,"lat":51.169265,"lon":3.1673159,"timestamp":"2019-06-09T13:50:19Z","version":1,"changeset":71071874,"user":"Hopperpop","uid":3664604,"tags":{"amenity":"bench"}},{"type":"node","id":6535241428,"lat":51.1692199,"lon":3.1673224,"timestamp":"2019-06-09T13:50:19Z","version":1,"changeset":71071874,"user":"Hopperpop","uid":3664604,"tags":{"amenity":"bench"}},{"type":"node","id":6535241430,"lat":51.1685726,"lon":3.1678225,"timestamp":"2019-06-09T13:50:19Z","version":1,"changeset":71071874,"user":"Hopperpop","uid":3664604,"tags":{"bench":"yes","leisure":"picnic_table","material":"wood"}},{"type":"node","id":6536026827,"lat":51.1703142,"lon":3.1691109,"timestamp":"2019-06-09T22:54:45Z","version":1,"changeset":71082671,"user":"Hopperpop","uid":3664604,"tags":{"leisure":"picnic_table"}},{"type":"node","id":6536026828,"lat":51.1702795,"lon":3.1691552,"timestamp":"2019-06-09T22:54:45Z","version":1,"changeset":71082671,"user":"Hopperpop","uid":3664604,"tags":{"leisure":"picnic_table"}},{"type":"node","id":6712112244,"lat":51.1595064,"lon":3.2021482,"timestamp":"2020-05-24T21:35:50Z","version":2,"changeset":85695537,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"leisure":"picnic_table"}},{"type":"node","id":7304050040,"lat":51.1560908,"lon":3.1748919,"timestamp":"2020-03-17T19:11:00Z","version":1,"changeset":82315744,"user":"Hopperpop","uid":3664604,"tags":{"amenity":"bench"}},{"type":"node","id":7304050041,"lat":51.1560141,"lon":3.1749533,"timestamp":"2020-03-17T19:11:00Z","version":1,"changeset":82315744,"user":"Hopperpop","uid":3664604,"tags":{"amenity":"bench"}},{"type":"node","id":7304050042,"lat":51.156032,"lon":3.1749379,"timestamp":"2020-03-17T19:11:00Z","version":1,"changeset":82315744,"user":"Hopperpop","uid":3664604,"tags":{"amenity":"bench"}},{"type":"node","id":7439979218,"lat":51.1780402,"lon":3.2178666,"timestamp":"2020-04-24T00:56:14Z","version":1,"changeset":84027933,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":7439979219,"lat":51.1780508,"lon":3.2179033,"timestamp":"2020-04-24T00:56:14Z","version":1,"changeset":84027933,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":7529262982,"lat":51.1585566,"lon":3.1715528,"timestamp":"2020-05-17T16:12:04Z","version":1,"changeset":85340264,"user":"Hopperpop","uid":3664604,"tags":{"board_type":"map","information":"board","tourism":"information"}},{"type":"node","id":7529262984,"lat":51.1585786,"lon":3.1715385,"timestamp":"2020-05-17T16:12:04Z","version":1,"changeset":85340264,"user":"Hopperpop","uid":3664604,"tags":{"leisure":"picnic_table"}},{"type":"node","id":7554879668,"lat":51.1573713,"lon":3.2043731,"timestamp":"2020-05-24T21:35:50Z","version":1,"changeset":85695537,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"access":"yes","amenity":"toilets","fee":"no","toilets:disposal":"flush","unisex":"yes","wheelchair":"yes"}},{"type":"node","id":7554879669,"lat":51.1594855,"lon":3.2021507,"timestamp":"2020-05-24T21:35:50Z","version":1,"changeset":85695537,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"leisure":"picnic_table"}},{"type":"node","id":7556988723,"lat":51.1330234,"lon":3.1839944,"timestamp":"2020-05-25T19:19:56Z","version":1,"changeset":85730259,"user":"Hopperpop","uid":3664604,"tags":{"amenity":"bench","material":"wood"}},{"type":"node","id":7575825326,"lat":51.1386553,"lon":3.1797358,"timestamp":"2020-05-31T19:49:45Z","version":1,"changeset":86019474,"user":"Hopperpop","uid":3664604,"tags":{"amenity":"bench"}},{"type":"node","id":7575825327,"lat":51.1382456,"lon":3.1797422,"timestamp":"2020-05-31T19:49:45Z","version":1,"changeset":86019474,"user":"Hopperpop","uid":3664604,"tags":{"information":"board","tourism":"information"}},{"type":"node","id":8109498958,"lat":51.1332267,"lon":3.2341272,"timestamp":"2020-11-11T20:42:45Z","version":1,"changeset":93951029,"user":"L'imaginaire","uid":654234,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":8109498959,"lat":51.1335011,"lon":3.2343954,"timestamp":"2020-11-11T20:42:45Z","version":1,"changeset":93951029,"user":"L'imaginaire","uid":654234,"tags":{"leisure":"picnic_table"}},{"type":"node","id":8198894646,"lat":51.125688,"lon":3.1856217,"timestamp":"2020-12-06T23:39:34Z","version":3,"changeset":95384686,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"image":"https://i.imgur.com/O5kX20u.jpg","information":"board","tourism":"information"}},{"type":"node","id":8199012519,"lat":51.1262245,"lon":3.1802429,"timestamp":"2020-12-07T00:12:14Z","version":3,"changeset":95385124,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"image":"https://i.imgur.com/tomw9p5.jpg","information":"board","tourism":"information"}},{"type":"node","id":8199244816,"lat":51.1252874,"lon":3.1837622,"timestamp":"2020-12-06T17:14:52Z","version":1,"changeset":95374174,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"amenity":"bench"}},{"type":"node","id":8199301617,"lat":51.1256827,"lon":3.1853543,"timestamp":"2020-12-06T17:14:52Z","version":1,"changeset":95374174,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"amenity":"bench","backrest":"no"}},{"type":"node","id":8255488518,"lat":51.1406698,"lon":3.235178,"timestamp":"2020-12-23T18:20:35Z","version":1,"changeset":96342158,"user":"L'imaginaire","uid":654234,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":9316104741,"lat":51.1330984,"lon":3.2335257,"timestamp":"2021-12-06T18:31:00Z","version":1,"changeset":114629890,"user":"L'imaginaire","uid":654234,"tags":{"information":"board","tourism":"information"}},{"type":"node","id":9442532340,"lat":51.1763651,"lon":3.1947952,"timestamp":"2022-01-23T16:26:28Z","version":2,"changeset":116506336,"user":"L'imaginaire","uid":654234,"tags":{"amenity":"bench","backrest":"yes","image":"https://i.imgur.com/eZ0Loii.jpg"}},{"type":"way","id":15242261,"timestamp":"2020-04-05T07:08:45Z","version":8,"changeset":83089516,"user":"Hopperpop","uid":3664604,"nodes":[150996092,150996093,6754312552,6754312553,6754312550,6754312551,150996094,150996095,150996097,150996098,6754312560,6754312559,6754312558,150996099,6754312557,150996100,6754312555,6754312556,150996101,6754312554,150996092],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":16514228,"timestamp":"2017-06-13T07:14:23Z","version":9,"changeset":49490318,"user":"Jakka","uid":2403313,"nodes":[170464837,170464839,170464840,170464841,170464837],"tags":{"access":"yes","amenity":"parking","fee":"no","maxstay":"4 hours","parking":"surface"}},{"type":"way","id":76706071,"timestamp":"2017-06-17T07:51:31Z","version":4,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[903903386,1038557094,1038557233,1038557143,1038557075,903903387,1038557195,903903388,903903390,903904576,903903386],"tags":{"access":"permissive","amenity":"parking"}},{"type":"way","id":89601157,"timestamp":"2019-11-09T18:40:50Z","version":3,"changeset":76851428,"user":"Hopperpop","uid":3664604,"nodes":[1038557083,1038557078,1038557104,1038557072,1038557108,1038557230,1038557227,1038557102,1038557137,1038575040,1038557191,1038557014,6960473080,1038557035,1038557012,1038557083],"tags":{"amenity":"parking"}},{"type":"way","id":89604999,"timestamp":"2020-01-16T22:01:28Z","version":5,"changeset":79667667,"user":"Hopperpop","uid":3664604,"nodes":[1038583404,1038583491,1038583375,1038583483,1038583479,1038583398,1038583459,1038583456,1038583446,1038583441,1038583425,1038583501,1038583451,1038583463,1038583476,1038583404],"tags":{"access":"yes","amenity":"parking","capacity":"57","carpool":"yes","description":"carpoolparking","fee":"no","name":"Loppem","parking":"surface"}},{"type":"way","id":92035679,"timestamp":"2019-10-05T08:05:33Z","version":7,"changeset":75311122,"user":"skyman81","uid":955688,"nodes":[1069177920,6853179264,1069177925,1069177919,6853179269,6853179268,6853179267,6853179215,6853179213,6853179214,1069178133,1069177984,6853179230,6853179228,6853179229,6853179224,6853179225,6853179227,6853179226,6853179216,6853179220,6853179219,6853179218,6853179217,6853179223,6853179221,6853179222,1069177967,1069177852,6853179211,6853179212,6853179210,6853179327,6853179208,6853179209,6853179203,1069177976,6853179207,6853179206,6853179205,6853179204,6853179202,1069177849,6852012579,6852012578,6852012580,6852012577,6852012581,6852012582,6852012583,1069177845,1759437085,1519342743,1519342742,1069178166,1069177853,1069177915,6853179235,6853179234,6853179236,1069177933,6853179237,6853179238,1069178021,6853179246,6853179244,6853179245,6853179240,6853179243,6853179241,6853179242,6853179239,6853179248,6853179249,6853179250,6853179247,1069177873,6853179262,6853179263,6853179260,6853179261,6853179256,6853179259,6853179257,6853179258,1069177920],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":101248451,"timestamp":"2018-05-23T14:18:27Z","version":2,"changeset":59213416,"user":"Jakka","uid":2403313,"nodes":[1168728158,1168728325,1168728159,5637669355,1168728109,1168728158],"tags":{"access":"private","amenity":"parking","name":"Parking Merkenveld"}},{"type":"way","id":101248462,"timestamp":"2020-05-25T13:53:02Z","version":3,"changeset":85720081,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[1168727876,1168728288,1168728412,1168728208,1168727876],"tags":{"amenity":"toilets","building":"yes","source:geometry:date":"2019-03-14","source:geometry:ref":"Gbg/6588148"}},{"type":"way","id":131622387,"timestamp":"2015-01-09T12:06:51Z","version":2,"changeset":28017707,"user":"TripleBee","uid":497177,"nodes":[1448421093,1448421099,1448421091,1448421081,1448421093],"tags":{"amenity":"parking","name":"Tudor - Zeeweg","parking":"surface"}},{"type":"way","id":145691934,"timestamp":"2012-01-15T12:43:37Z","version":1,"changeset":10397429,"user":"Sanderd17","uid":253266,"nodes":[1590642859,1590642860,1590642858,1590642849,1590642859],"tags":{"amenity":"parking"}},{"type":"way","id":145691937,"timestamp":"2012-01-15T12:43:37Z","version":1,"changeset":10397429,"user":"Sanderd17","uid":253266,"nodes":[1590642829,1590642828,1590642830,1590642832,1590642829],"tags":{"amenity":"parking"}},{"type":"way","id":158901716,"timestamp":"2017-06-13T07:12:20Z","version":2,"changeset":49490264,"user":"Jakka","uid":2403313,"nodes":[1710245713,1710245718,1710245707,1710245705,1710245703,1710245715,1710245711,1710245709,1710245701,1710245713],"tags":{"access":"yes","amenity":"parking","capacity":"14","fee":"no","parking":"surface"}},{"type":"way","id":158904558,"timestamp":"2020-12-22T22:39:41Z","version":4,"changeset":96283379,"user":"M!dgard","uid":763799,"nodes":[1710262742,1710262745,1710262735,1710262733,1710262732,1710262743,1710262741,1710262739,1710262744,1710262737,1710262736,1710262731,1710262738,1710262742],"tags":{"access":"yes","alt_name":"Schoolparking","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":158906028,"timestamp":"2017-06-13T07:27:19Z","version":5,"changeset":49490646,"user":"Jakka","uid":2403313,"nodes":[1710276259,1710276251,1810330766,1710276255,1710276261,1710276240,1710276232,1710276257,1710276243,1710276253,1810347217,1710276242,1710276259],"tags":{"access":"yes","amenity":"parking","fee":"no","name":"Parking Sportcentrum De Valkaart","parking":"surface"}},{"type":"way","id":160825858,"timestamp":"2012-04-23T20:35:52Z","version":1,"changeset":11399632,"user":"martino260","uid":655442,"nodes":[1728421375,1728421374,1728421379,1728421377,1728421376,1728421378,1728421375],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":162602213,"timestamp":"2020-04-11T18:12:16Z","version":8,"changeset":83407731,"user":"JanFi","uid":672253,"nodes":[1920143232,7393009684,7393048385,1744641293,1523513488,1744641292,1920143232],"tags":{"amenity":"parking","capacity":"15"}},{"type":"way","id":165489167,"timestamp":"2020-10-12T19:06:29Z","version":3,"changeset":92371840,"user":"L'imaginaire","uid":654234,"nodes":[4912197370,4912197365,4912197373,4912197364,4912197372,1770289505,4912197362,4912197371,4912197374,4912197363,4912197368,4912197366,4912197369,4912197367,4912197370],"tags":{"access":"yes","amenity":"parking","fee":"no","name":"Bad Neuheimplein","parking":"surface"}},{"type":"way","id":168291852,"timestamp":"2017-07-19T11:17:33Z","version":3,"changeset":50402298,"user":"martino260","uid":655442,"nodes":[1795793399,4979389763,1795793409,1795793395,1795793393,1795793397,1795793407,1795793406,1795793408,1795793405,1795793399],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":169875513,"timestamp":"2017-06-13T07:26:09Z","version":2,"changeset":49490613,"user":"Jakka","uid":2403313,"nodes":[1810345951,1810345955,1810345947,1810345944,1810345951],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":170015605,"timestamp":"2017-06-17T07:51:33Z","version":4,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[1811673425,1811673421,1811673418,1811673423,1811673425],"tags":{"access":"private","amenity":"parking","name":"gheeraert E40","operator":"Gheeraert"}},{"type":"way","id":170018487,"timestamp":"2017-06-17T07:51:33Z","version":3,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[1811699779,1811699778,1811699776,1811699777,1811699779],"tags":{"access":"private","amenity":"parking","name":"Gheeraert vooraan"}},{"type":"way","id":170559194,"timestamp":"2017-06-17T07:51:33Z","version":2,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[1817319304,1817319302,1817319297,1817319301,1817319304],"tags":{"access":"private","amenity":"parking","name":"Gheeraert laadkade"}},{"type":"way","id":170559195,"timestamp":"2017-06-17T07:51:33Z","version":2,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[1817319299,1817319303,1817319300,1817319292,1817319299],"tags":{"access":"private","amenity":"parking","name":"Gheeraert spoorweg trailers"}},{"type":"way","id":170559196,"timestamp":"2017-06-17T07:51:33Z","version":2,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[1817319293,1817319289,1817319291,1817319296,1817319293],"tags":{"access":"private","amenity":"parking","name":"Gheeraert spoorweg trucks"}},{"type":"way","id":170559197,"timestamp":"2017-06-17T07:51:33Z","version":2,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[1817319294,1817319298,1817319295,1817319290,1817319294],"tags":{"access":"private","amenity":"parking","name":"Gheeraert zijkant"}},{"type":"way","id":170559292,"timestamp":"2017-06-17T07:51:33Z","version":2,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[1817320496,1817320494,1817320493,1817320495,1817320496],"tags":{"access":"private","amenity":"parking","name":"Gheeraert vooraan gebouw"}},{"type":"way","id":170559832,"timestamp":"2020-10-07T10:51:41Z","version":6,"changeset":92105788,"user":"effem","uid":16437,"nodes":[1817324515,1817324509,1817324491,6397031888,4044172008,4044172003,4044171997,4044171962,4044171957,4044171976,1817324489,1817324488,3550860268,1817324505,3550860269,1817324513,1817324515],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":223674368,"timestamp":"2020-12-03T18:47:28Z","version":3,"changeset":95244226,"user":"L'imaginaire","uid":654234,"nodes":[2325437844,8191691971,8191691973,8191691972,2325437840,8191691970,414025563,2325437844],"tags":{"amenity":"parking","name":"Tillegembos","parking":"surface"}},{"type":"way","id":237214948,"timestamp":"2017-06-17T07:51:35Z","version":2,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[2451574741,2451574742,2451574744,1015583939,2451574741],"tags":{"access":"private","amenity":"parking"}},{"type":"way","id":237214949,"timestamp":"2017-06-17T07:51:35Z","version":2,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[2451574748,2451574746,2451574747,2451574749,2451574748],"tags":{"access":"private","amenity":"parking"}},{"type":"way","id":237214950,"timestamp":"2017-06-17T07:51:35Z","version":3,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[2451569392,1015567837,2451574745,2451574743,2451578121,2451569392],"tags":{"access":"private","amenity":"parking"}},{"type":"way","id":325909586,"timestamp":"2016-01-05T18:51:49Z","version":2,"changeset":36387330,"user":"JanFi","uid":672253,"nodes":[3325315243,111759500,3325315247,3325315232,3325315230,3325315226,1169056712,3325315243],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":326834162,"timestamp":"2021-10-10T21:49:11Z","version":4,"changeset":112350014,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[3335137807,3335137692,3335137795,9163493632,3335137802,3335137812,9163486855,9163486856,3335137823,3335137807],"tags":{"access":"customers","amenity":"parking","operator":"Best Western Weinebrugge","parking":"surface"}},{"type":"way","id":327849054,"timestamp":"2015-02-12T20:26:22Z","version":1,"changeset":28807613,"user":"escada","uid":436365,"nodes":[3346575929,3346575873,3346575876,3346575843,3346575845,3346575891,3346575901,3346575923,3346575928,3346575950,3346575929],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":327849055,"timestamp":"2016-10-08T21:24:46Z","version":2,"changeset":42742859,"user":"maggot27","uid":118021,"nodes":[3346575945,3346575946,3346575943,3346575933,3346575925,3346575917,3346575903,3346575908,3346575889,3346575886,3346575945],"tags":{"access":"customers","amenity":"parking","parking":"surface"}},{"type":"way","id":327849056,"timestamp":"2015-02-12T20:26:22Z","version":1,"changeset":28807613,"user":"escada","uid":436365,"nodes":[3346575865,3346575853,3346575855,3346575846,3346575840,3346575858,3346575865],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":374677860,"timestamp":"2015-10-10T09:08:20Z","version":1,"changeset":34545536,"user":"Jakka","uid":2403313,"nodes":[3780611504,3780611502,3780611500,3780611503,3780611504],"tags":{"amenity":"parking"}},{"type":"way","id":374677861,"timestamp":"2015-10-10T09:08:20Z","version":1,"changeset":34545536,"user":"Jakka","uid":2403313,"nodes":[3780611495,3780611493,3780611492,3780611494,3780611495],"tags":{"amenity":"parking"}},{"type":"way","id":374677862,"timestamp":"2015-10-10T09:08:20Z","version":1,"changeset":34545536,"user":"Jakka","uid":2403313,"nodes":[3780611498,3780611497,3780611496,3780611499,3780611501,3780611498],"tags":{"amenity":"parking"}},{"type":"way","id":389912371,"timestamp":"2016-01-06T16:51:45Z","version":1,"changeset":36407948,"user":"Spectrokid","uid":19775,"nodes":[3930713440,3930713451,3930713447,3930713437,3930713440],"tags":{"amenity":"parking"}},{"type":"way","id":389912372,"timestamp":"2019-11-16T13:17:09Z","version":4,"changeset":77164376,"user":"Hopperpop","uid":3664604,"nodes":[3930713454,3930713442,3930713435,3930713429,5826811614,3930713426,3930713430,6982605752,6982605754,3930713438,6982605769,6982605766,6982605767,6982605762,6982605764,3930713446,3930713454],"tags":{"access":"customers","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":401995684,"timestamp":"2020-10-07T10:52:00Z","version":3,"changeset":92105972,"user":"effem","uid":16437,"nodes":[4044171963,4044171954,4044171924,4044171936,4044171941,4044171963],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":500067820,"timestamp":"2017-06-13T07:49:12Z","version":1,"changeset":49491219,"user":"Jakka","uid":2403313,"nodes":[4912203166,4912203165,4912203164,4912203163,4912203162,4912203161,4912203160,4912203166],"tags":{"access":"yes","amenity":"parking","parking":"surface"}},{"type":"way","id":500067821,"timestamp":"2017-06-13T07:49:12Z","version":1,"changeset":49491219,"user":"Jakka","uid":2403313,"nodes":[4912203170,4912203169,4912203168,4912203167,4912203170],"tags":{"access":"yes","amenity":"parking","parking":"surface"}},{"type":"way","id":500067822,"timestamp":"2017-06-13T07:49:12Z","version":1,"changeset":49491219,"user":"Jakka","uid":2403313,"nodes":[4912203174,4912203173,4912203172,4912203171,4912203174],"tags":{"access":"yes","amenity":"parking","parking":"surface"}},{"type":"way","id":500067823,"timestamp":"2017-06-13T07:49:12Z","version":1,"changeset":49491219,"user":"Jakka","uid":2403313,"nodes":[4912203179,4912203178,4912203177,4912203176,4912203179],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":500069613,"timestamp":"2018-10-11T09:30:48Z","version":2,"changeset":63409550,"user":"Jakka","uid":2403313,"nodes":[4912214695,4912214685,4912214694,4912214693,4912214692,4912214680,4912214695],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":500071452,"timestamp":"2018-10-11T09:30:48Z","version":2,"changeset":63409550,"user":"Jakka","uid":2403313,"nodes":[4912225068,4912225062,4912225063,4912225053,4912225064,4912214694,4912214685,4912225068],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":500071455,"timestamp":"2018-10-11T09:30:48Z","version":2,"changeset":63409550,"user":"Jakka","uid":2403313,"nodes":[4912225070,4912214681,4912214686,4912225052,4912225051,4912225067,4912225062,4912225068,4912225070],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":500071458,"timestamp":"2018-10-11T09:30:48Z","version":2,"changeset":63409550,"user":"Jakka","uid":2403313,"nodes":[4912214695,4912214680,4912225069,4912225050,1525460846,4912214681,4912225070,4912214695],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":533276307,"timestamp":"2019-12-13T10:02:12Z","version":2,"changeset":78364882,"user":"skyman81","uid":955688,"nodes":[5173881316,5173881317,5173881318,7054196467,5173881316],"tags":{"amenity":"parking"}},{"type":"way","id":533276308,"timestamp":"2017-10-17T23:36:18Z","version":1,"changeset":53027174,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[5173881320,5173881621,5173881622,5173881623,5173881320],"tags":{"amenity":"parking"}},{"type":"way","id":533276309,"timestamp":"2017-10-17T23:36:18Z","version":1,"changeset":53027174,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[5173881624,5173881625,5173881626,5173881627,5173881624],"tags":{"amenity":"parking"}},{"type":"way","id":579848581,"timestamp":"2020-04-05T07:08:57Z","version":6,"changeset":83089516,"user":"Hopperpop","uid":3664604,"nodes":[4043782112,5825400688,5552466020,6997096756,6997096759,6997096758,5552466018,5552466013,5552466014,6997076567,4043782112],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":584455569,"timestamp":"2019-10-31T19:49:18Z","version":2,"changeset":76465627,"user":"Hopperpop","uid":3664604,"nodes":[5586765933,5586765934,5586765935,5586765936,5586765933],"tags":{"amenity":"parking"}},{"type":"way","id":585977870,"timestamp":"2019-10-11T13:28:22Z","version":2,"changeset":75566739,"user":"Hopperpop","uid":3664604,"nodes":[5587844460,5599314384,5599314385,1659850846,6870850178,5587844462,5587844461,6870863414,5587844460],"tags":{"amenity":"parking"}},{"type":"way","id":587014342,"timestamp":"2018-05-09T19:13:29Z","version":1,"changeset":58829130,"user":"Sille Van Landschoot","uid":4852501,"nodes":[5607796820,5607798725,5607798721,5607798722,5607796819,5607798723,5607796820],"tags":{"access":"permissive","amenity":"parking","park_ride":"no","parking":"surface","surface":"paved"}},{"type":"way","id":590167103,"timestamp":"2018-05-22T12:37:36Z","version":1,"changeset":59179114,"user":"ForstEK","uid":1737608,"nodes":[5635001277,5635001274,5635001275,5635001276,5635001277],"tags":{"amenity":"parking"}},{"type":"way","id":590167113,"timestamp":"2020-07-29T17:45:20Z","version":2,"changeset":88691835,"user":"JanFi","uid":672253,"nodes":[5635001312,5635001306,7767137237,7767137235,7767137236,7767137234,5635001312],"tags":{"amenity":"parking"}},{"type":"way","id":590167134,"timestamp":"2018-05-22T12:37:37Z","version":1,"changeset":59179114,"user":"ForstEK","uid":1737608,"nodes":[5635001374,5635001373,5635001372,5635001371,5635001374],"tags":{"amenity":"parking"}},{"type":"way","id":590167135,"timestamp":"2018-05-22T12:37:37Z","version":1,"changeset":59179114,"user":"ForstEK","uid":1737608,"nodes":[5635001378,5635001377,5635001376,5635001375,5635001378],"tags":{"amenity":"parking"}},{"type":"way","id":590167136,"timestamp":"2018-05-22T12:37:37Z","version":1,"changeset":59179114,"user":"ForstEK","uid":1737608,"nodes":[5635001382,5635001381,5635001380,5635001379,5635001382],"tags":{"amenity":"parking"}},{"type":"way","id":590167137,"timestamp":"2019-07-06T15:58:19Z","version":3,"changeset":71962591,"user":"gjosch","uid":1776978,"nodes":[5635001386,5882873336,5882873337,5882873338,5882873335,6593340582,6593340583,5882873334,6593340584,5635001385,5635001384,5635001383,5635001386],"tags":{"amenity":"parking"}},{"type":"way","id":590167147,"timestamp":"2018-05-22T12:37:38Z","version":1,"changeset":59179114,"user":"ForstEK","uid":1737608,"nodes":[5635001417,5635001414,5635001415,5635001416,5635001417],"tags":{"amenity":"parking"}},{"type":"way","id":601406079,"timestamp":"2018-06-24T22:15:06Z","version":1,"changeset":60131072,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[5716136617,5716136618,5716136619,5716136620,5716136617],"tags":{"amenity":"parking"}},{"type":"way","id":632813009,"timestamp":"2018-10-11T09:24:42Z","version":1,"changeset":63409297,"user":"Jakka","uid":2403313,"nodes":[5974489618,1810326044,1810326087,5974489617,5972179348,5972179347,5972179346,5972179345,5972179344,5972179343,5972179331,5974489616,5974489615,5974489614,5974489618],"tags":{"amenity":"parking","name":"Gemeenteplein","parking":"surface"}},{"type":"way","id":668043297,"timestamp":"2019-04-10T18:34:27Z","version":2,"changeset":69093378,"user":"RudolpheDeer","uid":9408828,"nodes":[6255587424,6255587425,6255587426,6255587427,6255587424],"tags":{"access":"private","amenity":"parking"}},{"type":"way","id":670104236,"timestamp":"2019-02-13T00:05:02Z","version":1,"changeset":67147239,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[6275462768,6275462769,6275462770,6275462771,6275462768],"tags":{"amenity":"parking"}},{"type":"way","id":670104238,"timestamp":"2019-02-13T00:05:02Z","version":1,"changeset":67147239,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[6275462772,6275462989,6275462773,6275462774,6275462775,6275462772],"tags":{"amenity":"parking"}},{"type":"way","id":670104239,"timestamp":"2019-02-13T00:05:02Z","version":1,"changeset":67147239,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[6275462776,6275462777,6275462778,6275462779,6275462776],"tags":{"amenity":"parking"}},{"type":"way","id":670104241,"timestamp":"2019-02-13T00:05:02Z","version":1,"changeset":67147239,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[6275462780,6275462781,6275462782,6275462783,6275462780],"tags":{"amenity":"parking"}},{"type":"way","id":670104242,"timestamp":"2019-02-13T00:05:02Z","version":1,"changeset":67147239,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[6275462784,6275462985,6275462988,6275462986,6275462987,6275462784],"tags":{"amenity":"parking"}},{"type":"way","id":671840055,"timestamp":"2019-02-20T15:15:45Z","version":1,"changeset":67395313,"user":"Tim Couwelier","uid":7246683,"nodes":[6291339827,6291339828,6291339816,6291339815,6291339822,6291339821,6291339829,6291339830,6291339827],"tags":{"amenity":"parking"}},{"type":"way","id":695825223,"timestamp":"2019-06-08T15:19:24Z","version":1,"changeset":71053301,"user":"Hopperpop","uid":3664604,"nodes":[1519476746,6533893620,6533893621,6533893622,1519476797,1519476620,1519476746],"tags":{"access":"yes","amenity":"parking"}},{"type":"way","id":695825224,"timestamp":"2019-06-08T15:19:24Z","version":1,"changeset":71053301,"user":"Hopperpop","uid":3664604,"nodes":[1519476744,6533893624,6533893625,6533893626,1519476698,1519476635,1519476744],"tags":{"access":"yes","amenity":"parking"}},{"type":"way","id":696040917,"timestamp":"2019-06-09T23:24:59Z","version":2,"changeset":71082992,"user":"Hopperpop","uid":3664604,"nodes":[6536026850,6536026851,6536026852,6536026853,6536026850],"tags":{"amenity":"parking","name":"Kasteel Tudor"}},{"type":"way","id":696043218,"timestamp":"2019-06-09T23:24:59Z","version":1,"changeset":71082992,"user":"Hopperpop","uid":3664604,"nodes":[6536038234,6536038235,6536038236,6536038237,6536038234],"tags":{"access":"customers","amenity":"parking"}},{"type":"way","id":700675991,"timestamp":"2020-12-18T10:48:20Z","version":2,"changeset":96062619,"user":"Hopperpop","uid":3664604,"nodes":[6579962064,6579962065,6579962066,6579962068,6579962067,6579962064],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":705278707,"timestamp":"2020-09-30T20:36:55Z","version":2,"changeset":91787895,"user":"L'imaginaire","uid":654234,"nodes":[6625037999,6625038000,6625038001,6625038002,6625038003,6004375826,6625038005,6625038006,6625037999],"tags":{"amenity":"parking"}},{"type":"way","id":719482833,"timestamp":"2019-08-28T21:18:49Z","version":1,"changeset":73857967,"user":"Hopperpop","uid":3664604,"nodes":[6754312544,6754312543,6754312542,6754312541,6754312544],"tags":{"access":"yes","amenity":"parking","capacity":"5"}},{"type":"way","id":719482834,"timestamp":"2019-08-28T21:18:49Z","version":1,"changeset":73857967,"user":"Hopperpop","uid":3664604,"nodes":[6754312565,6754312564,6754312563,6754312562,6754312565],"tags":{"access":"yes","amenity":"parking","capacity":"12"}},{"type":"way","id":737054013,"timestamp":"2019-10-20T15:39:32Z","version":1,"changeset":75957554,"user":"Hopperpop","uid":3664604,"nodes":[5826811496,5826811497,5826811494,5826811495,5826811496],"tags":{"amenity":"parking"}},{"type":"way","id":737054014,"timestamp":"2019-10-20T15:39:32Z","version":1,"changeset":75957554,"user":"Hopperpop","uid":3664604,"nodes":[5826810676,5826810673,5826810674,5826810675,5826810676],"tags":{"amenity":"parking"}},{"type":"way","id":737054015,"timestamp":"2019-10-20T15:39:32Z","version":1,"changeset":75957554,"user":"Hopperpop","uid":3664604,"nodes":[5826810681,5826810678,5826810679,5826810680,5826810681],"tags":{"amenity":"parking"}},{"type":"way","id":737093410,"timestamp":"2021-08-14T21:52:07Z","version":2,"changeset":109683899,"user":"effem","uid":16437,"nodes":[5826811559,5826811536,5826811535,5826811561,5826811560,5826811559],"tags":{"access":"yes","amenity":"parking","capacity":"4","fee":"no","parking":"surface"}},{"type":"way","id":737093411,"timestamp":"2021-08-14T21:52:03Z","version":2,"changeset":109683899,"user":"effem","uid":16437,"nodes":[5826811551,5826811547,5826811548,5826811549,5826811550,5826811551],"tags":{"access":"yes","amenity":"parking","capacity":"4","fee":"no","parking":"surface"}},{"type":"way","id":739652949,"timestamp":"2019-10-28T20:18:16Z","version":1,"changeset":76314556,"user":"Hopperpop","uid":3664604,"nodes":[6925536542,6925536541,6925536540,6925536539,6925536542],"tags":{"amenity":"parking","capacity":"6","parking":"surface"}},{"type":"way","id":741675236,"timestamp":"2020-12-17T22:07:55Z","version":4,"changeset":96029554,"user":"Hopperpop","uid":3664604,"nodes":[6943148207,6943148206,6943148205,6943148204,1637742821,6943148203,6943148202,6943148201,6943148200,6943148199,6943148198,6943148197,6943148207],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":742295526,"timestamp":"2019-11-05T19:27:15Z","version":1,"changeset":76664875,"user":"Hopperpop","uid":3664604,"nodes":[6949357909,6949357908,6949357907,6949357906,6949357909],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":742295527,"timestamp":"2019-11-05T19:27:15Z","version":1,"changeset":76664875,"user":"Hopperpop","uid":3664604,"nodes":[6949357913,6949357912,6949357911,6949357910,6949357913],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":742295528,"timestamp":"2019-11-05T19:27:15Z","version":1,"changeset":76664875,"user":"Hopperpop","uid":3664604,"nodes":[6949357917,6949357916,6949357915,6949357914,6949357917],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":742295529,"timestamp":"2019-11-05T19:27:15Z","version":1,"changeset":76664875,"user":"Hopperpop","uid":3664604,"nodes":[6949357921,6949357920,6949357919,6949357918,6949357921],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":746170866,"timestamp":"2019-11-16T15:27:02Z","version":1,"changeset":77167609,"user":"Hopperpop","uid":3664604,"nodes":[6982906547,6982906546,6982906545,6982906544,6982906543,6982906542,6982906547],"tags":{"access":"customers","amenity":"parking"}},{"type":"way","id":747880657,"timestamp":"2021-09-19T12:40:45Z","version":2,"changeset":111407274,"user":"Hopperpop","uid":3664604,"nodes":[3325315397,6997076566,6997076565,6997076563,6997076562,6997076564,3325315395,3325315397],"tags":{"access":"customers","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":763977465,"timestamp":"2020-12-17T21:59:46Z","version":2,"changeset":96029554,"user":"Hopperpop","uid":3664604,"nodes":[7137343680,7137343681,7137343682,7137343683,7137343680],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":763977466,"timestamp":"2020-12-17T21:59:40Z","version":2,"changeset":96029554,"user":"Hopperpop","uid":3664604,"nodes":[7137343684,7137383185,7137383186,7137383187,7137343684],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":803821090,"timestamp":"2020-05-14T17:37:10Z","version":1,"changeset":85215781,"user":"Hopperpop","uid":3664604,"nodes":[7519058290,7519058289,7519058288,7519058287,7519058290],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":803821091,"timestamp":"2020-05-14T17:37:10Z","version":1,"changeset":85215781,"user":"Hopperpop","uid":3664604,"nodes":[7519058294,7519058293,7519058292,7519058291,7519058294],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":803821092,"timestamp":"2020-05-14T17:37:10Z","version":1,"changeset":85215781,"user":"Hopperpop","uid":3664604,"nodes":[7519058298,7519058297,7519058296,7519058295,7519058298],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":803821093,"timestamp":"2020-05-14T17:37:10Z","version":1,"changeset":85215781,"user":"Hopperpop","uid":3664604,"nodes":[7519058302,7519058301,7519058300,7519058299,7519058302],"tags":{"access":"private","amenity":"parking","capacity":"6","parking":"surface"}},{"type":"way","id":804963962,"timestamp":"2020-05-17T17:09:31Z","version":1,"changeset":85342199,"user":"Hopperpop","uid":3664604,"nodes":[7529417225,7529417226,7529417227,7529417228,7529417229,7529417230,7529417232,7529417225],"tags":{"access":"customers","amenity":"parking","fee":"no","operator":"’t Kiekekot","parking":"surface","surface":"unpaved"}},{"type":"way","id":806875503,"timestamp":"2020-05-21T15:48:37Z","version":1,"changeset":85563652,"user":"Hopperpop","uid":3664604,"nodes":[4042671969,7545532512,7545532514,7545532513,3359977305,4042671969],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":806963547,"timestamp":"2020-05-21T21:16:34Z","version":1,"changeset":85574048,"user":"Hopperpop","uid":3664604,"nodes":[7546193222,7546193221,7546193220,7546193219,7546193222],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":865357121,"timestamp":"2020-10-30T14:45:23Z","version":1,"changeset":93296961,"user":"L'imaginaire","uid":654234,"nodes":[8065883228,8065883227,8065883226,8065883225,8065883228],"tags":{"amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":865357122,"timestamp":"2020-10-30T14:45:23Z","version":1,"changeset":93296961,"user":"L'imaginaire","uid":654234,"nodes":[8065883233,8065883230,8065883229,8065883232,8065883233],"tags":{"amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":879281221,"timestamp":"2020-11-30T14:18:18Z","version":1,"changeset":95050429,"user":"M!dgard","uid":763799,"nodes":[8179735269,8179735268,8179735267,8179735266,8179735265,8179735264,8179735224,8179735269],"tags":{"access":"customers","amenity":"parking","parking":"surface"}},{"type":"way","id":881770201,"timestamp":"2020-12-07T00:46:56Z","version":1,"changeset":95385582,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[8200275847,8200275848,8200275844,8200275853,8200275849,8200275847],"tags":{"amenity":"parking","parking":"surface","surface":"grass"}},{"type":"way","id":978360549,"timestamp":"2021-09-01T08:53:08Z","version":1,"changeset":110553113,"user":"JanFi","uid":672253,"nodes":[5761770202,5761770204,9052878229,9052878228,5761770202],"tags":{"amenity":"parking"}},{"type":"way","id":1009692722,"timestamp":"2021-12-06T18:34:20Z","version":1,"changeset":114629990,"user":"L'imaginaire","uid":654234,"nodes":[9316118540,9316118536,9316118531,9316118535,9316118534,9316118533,9316118530,9316118532,3311835478,9316118540],"tags":{"amenity":"parking","parking":"street_side"}},{"type":"relation","id":8188853,"timestamp":"2020-07-05T12:38:48Z","version":13,"changeset":87554177,"user":"Pieter Vander Vennet","uid":3818858,"members":[{"type":"way","ref":577572397,"role":"outer"},{"type":"way","ref":577572399,"role":"outer"}],"tags":{"access":"guided","curator":"Luc Maene;Geert De Clercq","email":"lucmaene@hotmail.com;geert.de.clercq1@pandora.be","landuse":"meadow","leisure":"nature_reserve","name":"De Wulgenbroeken","natural":"wetland","operator":"Natuurpunt Brugge","type":"multipolygon","website":"https://natuurpuntbrugge.be/wulgenbroeken/","wetland":"wet_meadow","wikidata":"Q60061498","wikipedia":"nl:Wulgenbroeken"}},{"type":"relation","id":11163488,"timestamp":"2021-10-04T14:09:47Z","version":15,"changeset":112079863,"user":"DieterWesttoer","uid":13062237,"members":[{"type":"way","ref":810604915,"role":"outer"},{"type":"way","ref":989393316,"role":"outer"},{"type":"way","ref":389026405,"role":"inner"},{"type":"way","ref":810607458,"role":"outer"}],"tags":{"access":"yes","curator":"Kris Lesage","description":"Wat Doeveren zo uniek maakt, zijn zijn kleine heidegebiedjes met soorten die erg verschillen van de Kempense heide. Doeveren en omstreken was vroeger één groot heidegebied, maar bestaat nu grotendeels uit bossen.","dog":"leashed","email":"doeveren@natuurpuntzedelgem.be","image":"https://i.imgur.com/NEAsQZG.jpg","image:0":"https://i.imgur.com/Dq71hyQ.jpg","image:1":"https://i.imgur.com/mAIiT4f.jpg","image:2":"https://i.imgur.com/dELZU97.jpg","image:3":"https://i.imgur.com/Bso57JC.jpg","image:4":"https://i.imgur.com/9DtcfXo.jpg","image:5":"https://i.imgur.com/0R6eBfk.jpg","image:6":"https://i.imgur.com/b0JpvbR.jpg","leisure":"nature_reserve","name":"Doeveren","operator":"Natuurpunt Zedelgem","phone":"+32 486 25 25 30","type":"multipolygon","website":"https://www.natuurpuntzedelgem.be/gebieden/doeveren/","wikidata":"Q56395754","wikipedia":"nl:Doeveren (natuurgebied)"}},{"type":"relation","id":11790117,"timestamp":"2020-10-24T19:11:01Z","version":1,"changeset":92997462,"user":"Pieter Vander Vennet","uid":3818858,"members":[{"type":"way","ref":863373849,"role":"outer"},{"type":"way","ref":777280458,"role":"outer"}],"tags":{"access":"no","description:0":"In gebruik als waterbuffering","leisure":"nature_reserve","name":"Kerkebeek","operator":"Natuurpunt Brugge","type":"multipolygon"}},{"type":"node","id":1038638696,"lat":51.1197075,"lon":3.1827007},{"type":"node","id":7578975029,"lat":51.1199041,"lon":3.1828945},{"type":"node","id":7578975030,"lat":51.1201514,"lon":3.1831942},{"type":"node","id":1038638743,"lat":51.1202445,"lon":3.1894878},{"type":"node","id":7578975002,"lat":51.1202598,"lon":3.1897155},{"type":"node","id":7578975007,"lat":51.1199771,"lon":3.1863015},{"type":"node","id":7578975008,"lat":51.1199523,"lon":3.1863031},{"type":"node","id":7578975009,"lat":51.1199279,"lon":3.1859524},{"type":"node","id":1168728109,"lat":51.1275839,"lon":3.1765505},{"type":"node","id":1168728158,"lat":51.1278835,"lon":3.1763986},{"type":"node","id":1168728159,"lat":51.1276298,"lon":3.1767808},{"type":"node","id":5637669355,"lat":51.1276039,"lon":3.1766509},{"type":"node","id":1038638723,"lat":51.1272818,"lon":3.184601},{"type":"node","id":7554434438,"lat":51.1225298,"lon":3.1847624},{"type":"node","id":7578865273,"lat":51.122084,"lon":3.1846859},{"type":"node","id":7578975032,"lat":51.1215762,"lon":3.1842866},{"type":"node","id":1168727876,"lat":51.1290569,"lon":3.1766033},{"type":"node","id":1168728208,"lat":51.1289763,"lon":3.1767696},{"type":"node","id":1168728288,"lat":51.1291195,"lon":3.1766799},{"type":"node","id":1168728325,"lat":51.1279295,"lon":3.1766288},{"type":"node","id":1168728412,"lat":51.1290389,"lon":3.1768463},{"type":"node","id":1038638712,"lat":51.1282367,"lon":3.1840296},{"type":"node","id":1168727824,"lat":51.1312478,"lon":3.182233},{"type":"node","id":3922375256,"lat":51.1301155,"lon":3.1848042},{"type":"node","id":3922380071,"lat":51.1304048,"lon":3.1838954},{"type":"node","id":3922380081,"lat":51.1305694,"lon":3.1845093},{"type":"node","id":3922380086,"lat":51.1306445,"lon":3.1848152},{"type":"node","id":3922380092,"lat":51.1307378,"lon":3.1849591},{"type":"node","id":7577430793,"lat":51.1289492,"lon":3.1836032},{"type":"node","id":7578975024,"lat":51.1299598,"lon":3.1841704},{"type":"node","id":7578975028,"lat":51.1322547,"lon":3.1833542},{"type":"node","id":7578975049,"lat":51.1313772,"lon":3.1838431},{"type":"node","id":9167054153,"lat":51.1310258,"lon":3.1823668},{"type":"node","id":9167054154,"lat":51.13145,"lon":3.1841492},{"type":"node","id":9167054156,"lat":51.1316731,"lon":3.1850331},{"type":"node","id":9274761589,"lat":51.1297088,"lon":3.1831312},{"type":"node","id":9274761596,"lat":51.1296735,"lon":3.1831518},{"type":"node","id":929120698,"lat":51.1276376,"lon":3.1903134},{"type":"node","id":1038638592,"lat":51.1264889,"lon":3.19027},{"type":"node","id":1038638661,"lat":51.1258582,"lon":3.1854626},{"type":"node","id":1038638721,"lat":51.125636,"lon":3.1855855},{"type":"node","id":1038638753,"lat":51.123845,"lon":3.1880289},{"type":"node","id":3921878998,"lat":51.1255719,"lon":3.1902463},{"type":"node","id":3921879004,"lat":51.1275463,"lon":3.188843},{"type":"node","id":3921879011,"lat":51.1271626,"lon":3.1872368},{"type":"node","id":3921879019,"lat":51.1277666,"lon":3.1868505},{"type":"node","id":7554434436,"lat":51.1252645,"lon":3.1852941},{"type":"node","id":7578865274,"lat":51.1230564,"lon":3.187978},{"type":"node","id":7578865275,"lat":51.1226417,"lon":3.188075},{"type":"node","id":7578904489,"lat":51.1247504,"lon":3.1900249},{"type":"node","id":7578974988,"lat":51.1223221,"lon":3.1906513},{"type":"node","id":7578974989,"lat":51.1224255,"lon":3.1905646},{"type":"node","id":7578974990,"lat":51.1224672,"lon":3.1905195},{"type":"node","id":7578974991,"lat":51.1228709,"lon":3.1901867},{"type":"node","id":7578974992,"lat":51.1229568,"lon":3.1901459},{"type":"node","id":7578974995,"lat":51.123814,"lon":3.1899138},{"type":"node","id":7578974996,"lat":51.1239199,"lon":3.189925},{"type":"node","id":7578974997,"lat":51.1244111,"lon":3.1899686},{"type":"node","id":7578974998,"lat":51.1248503,"lon":3.190215},{"type":"node","id":7578974999,"lat":51.1247917,"lon":3.1900516},{"type":"node","id":7578975000,"lat":51.1248293,"lon":3.1900978},{"type":"node","id":7578975001,"lat":51.1248444,"lon":3.1901483},{"type":"node","id":7578975035,"lat":51.1250798,"lon":3.1851611},{"type":"node","id":7578975045,"lat":51.1278881,"lon":3.1882941},{"type":"node","id":9199177059,"lat":51.1256647,"lon":3.1855696},{"type":"node","id":7578987409,"lat":51.1232707,"lon":3.1920382},{"type":"node","id":7578987413,"lat":51.1260416,"lon":3.1973652},{"type":"node","id":7578987414,"lat":51.1263443,"lon":3.1973775},{"type":"node","id":7578987416,"lat":51.1278708,"lon":3.1974134},{"type":"node","id":7578987417,"lat":51.126749,"lon":3.197258},{"type":"node","id":1675648152,"lat":51.1281877,"lon":3.1903323},{"type":"node","id":2732486274,"lat":51.1302553,"lon":3.1886305},{"type":"node","id":3921879018,"lat":51.1280809,"lon":3.188102},{"type":"node","id":3922380061,"lat":51.1301929,"lon":3.1895402},{"type":"node","id":3922380083,"lat":51.1305788,"lon":3.1884337},{"type":"node","id":3922380095,"lat":51.130784,"lon":3.1852632},{"type":"node","id":7578865281,"lat":51.1283938,"lon":3.1903716},{"type":"node","id":7578865283,"lat":51.1288414,"lon":3.1904911},{"type":"node","id":7578960079,"lat":51.1303025,"lon":3.1855669},{"type":"node","id":7578975012,"lat":51.1294792,"lon":3.1906231},{"type":"node","id":7578975015,"lat":51.1297374,"lon":3.1907018},{"type":"node","id":7578975016,"lat":51.1300451,"lon":3.1907679},{"type":"node","id":7578975018,"lat":51.1305785,"lon":3.186668},{"type":"node","id":7578975019,"lat":51.130956,"lon":3.1881852},{"type":"node","id":7578975021,"lat":51.1303082,"lon":3.1855908},{"type":"node","id":7578975026,"lat":51.1310167,"lon":3.1861981},{"type":"node","id":7578975027,"lat":51.1318642,"lon":3.1857905},{"type":"node","id":7578975040,"lat":51.1280348,"lon":3.1889503},{"type":"node","id":7578975044,"lat":51.1279308,"lon":3.1875031},{"type":"node","id":7578975046,"lat":51.1279329,"lon":3.1881992},{"type":"node","id":9167054157,"lat":51.1308023,"lon":3.1852517},{"type":"node","id":9274761591,"lat":51.1310994,"lon":3.1862668},{"type":"node","id":9274761592,"lat":51.1310643,"lon":3.1862655},{"type":"node","id":9274761593,"lat":51.1310386,"lon":3.1862393},{"type":"node","id":7578987418,"lat":51.128003,"lon":3.1959031},{"type":"node","id":7578987419,"lat":51.1282167,"lon":3.193723},{"type":"node","id":5745833239,"lat":51.1258572,"lon":3.1996713},{"type":"node","id":5745833240,"lat":51.1257519,"lon":3.1995939},{"type":"node","id":5745833241,"lat":51.1253365,"lon":3.1991234},{"type":"node","id":7578987410,"lat":51.1243814,"lon":3.1988516},{"type":"node","id":7578987411,"lat":51.1243992,"lon":3.1989686},{"type":"node","id":7578987412,"lat":51.1259883,"lon":3.1997074},{"type":"node","id":7578987415,"lat":51.1260745,"lon":3.1997142},{"type":"node","id":1590642829,"lat":51.1333867,"lon":3.2308055},{"type":"node","id":1590642832,"lat":51.1334371,"lon":3.2308262},{"type":"node","id":1590642849,"lat":51.1336392,"lon":3.2305316},{"type":"node","id":1590642858,"lat":51.133659,"lon":3.2303991},{"type":"node","id":1590642859,"lat":51.1336899,"lon":3.2305508},{"type":"node","id":1590642860,"lat":51.1337096,"lon":3.2304183},{"type":"node","id":1590642828,"lat":51.1333653,"lon":3.2309374},{"type":"node","id":1590642830,"lat":51.1334157,"lon":3.2309581},{"type":"node","id":3311835478,"lat":51.133195,"lon":3.2334351},{"type":"node","id":9316118530,"lat":51.1331607,"lon":3.2333604},{"type":"node","id":9316118531,"lat":51.1330927,"lon":3.2334241},{"type":"node","id":9316118532,"lat":51.1331767,"lon":3.233347},{"type":"node","id":9316118533,"lat":51.133147,"lon":3.2333808},{"type":"node","id":9316118534,"lat":51.1331302,"lon":3.2334006},{"type":"node","id":9316118535,"lat":51.1331127,"lon":3.2334144},{"type":"node","id":9316118536,"lat":51.1330784,"lon":3.2334281},{"type":"node","id":9316118540,"lat":51.1330946,"lon":3.2335103},{"type":"node","id":6579962064,"lat":51.1367061,"lon":3.1640546},{"type":"node","id":6579962065,"lat":51.1361156,"lon":3.1646435},{"type":"node","id":6579962066,"lat":51.1357413,"lon":3.1637334},{"type":"node","id":6579962067,"lat":51.1359511,"lon":3.1637408},{"type":"node","id":6579962068,"lat":51.1359389,"lon":3.1638093},{"type":"node","id":7546193219,"lat":51.1456739,"lon":3.1637073},{"type":"node","id":7546193220,"lat":51.1455706,"lon":3.1643444},{"type":"node","id":7546193221,"lat":51.1456623,"lon":3.1643821},{"type":"node","id":7546193222,"lat":51.1457656,"lon":3.1637451},{"type":"node","id":3359977305,"lat":51.1464982,"lon":3.1689911},{"type":"node","id":4042671969,"lat":51.1461398,"lon":3.169233},{"type":"node","id":7545532512,"lat":51.1463103,"lon":3.169498},{"type":"node","id":7545532513,"lat":51.1466008,"lon":3.1695349},{"type":"node","id":7545532514,"lat":51.1464331,"lon":3.16962},{"type":"node","id":8200275848,"lat":51.1409105,"lon":3.1800288},{"type":"node","id":8200275844,"lat":51.1416967,"lon":3.1797728},{"type":"node","id":8200275847,"lat":51.1411211,"lon":3.1805153},{"type":"node","id":8200275849,"lat":51.1417397,"lon":3.1802115},{"type":"node","id":8200275853,"lat":51.1417351,"lon":3.1801651},{"type":"node","id":111759500,"lat":51.1483444,"lon":3.1886487},{"type":"node","id":1169056712,"lat":51.1482974,"lon":3.1884805},{"type":"node","id":3325315226,"lat":51.147926,"lon":3.1887015},{"type":"node","id":3325315230,"lat":51.1479856,"lon":3.1889124},{"type":"node","id":3325315232,"lat":51.1480454,"lon":3.1891027},{"type":"node","id":3325315243,"lat":51.1483285,"lon":3.1885919},{"type":"node","id":3325315247,"lat":51.1484007,"lon":3.1888131},{"type":"node","id":5826810673,"lat":51.1512507,"lon":3.1914885},{"type":"node","id":5826810674,"lat":51.15126,"lon":3.1914533},{"type":"node","id":5826810675,"lat":51.1510883,"lon":3.1912776},{"type":"node","id":5826810676,"lat":51.151057,"lon":3.1912906},{"type":"node","id":5826810678,"lat":51.1509897,"lon":3.1911759},{"type":"node","id":5826810679,"lat":51.1510025,"lon":3.1911334},{"type":"node","id":5826810680,"lat":51.1509352,"lon":3.1908874},{"type":"node","id":5826810681,"lat":51.1509074,"lon":3.1908689},{"type":"node","id":5826811494,"lat":51.1512125,"lon":3.1911315},{"type":"node","id":5826811495,"lat":51.1512055,"lon":3.191187},{"type":"node","id":5826811496,"lat":51.151296,"lon":3.1914182},{"type":"node","id":5826811497,"lat":51.1513261,"lon":3.1914182},{"type":"node","id":5826811535,"lat":51.1517839,"lon":3.1959375},{"type":"node","id":5826811536,"lat":51.1518581,"lon":3.1959708},{"type":"node","id":5826811547,"lat":51.1515913,"lon":3.196115},{"type":"node","id":5826811548,"lat":51.1516307,"lon":3.1961465},{"type":"node","id":5826811549,"lat":51.1516435,"lon":3.1961076},{"type":"node","id":5826811550,"lat":51.1516087,"lon":3.1959541},{"type":"node","id":5826811551,"lat":51.1515437,"lon":3.1959024},{"type":"node","id":5826811559,"lat":51.1517896,"lon":3.1957717},{"type":"node","id":5826811560,"lat":51.1517417,"lon":3.1957528},{"type":"node","id":5826811561,"lat":51.1517365,"lon":3.1957872},{"type":"node","id":3325315395,"lat":51.1544187,"lon":3.1856685},{"type":"node","id":3325315397,"lat":51.1545358,"lon":3.1860117},{"type":"node","id":3930713426,"lat":51.1571474,"lon":3.1889324},{"type":"node","id":3930713429,"lat":51.1573669,"lon":3.1883265},{"type":"node","id":3930713430,"lat":51.1573202,"lon":3.1890776},{"type":"node","id":3930713435,"lat":51.1574561,"lon":3.1883916},{"type":"node","id":3930713437,"lat":51.1574971,"lon":3.1893349},{"type":"node","id":3930713438,"lat":51.1574907,"lon":3.1884223},{"type":"node","id":3930713440,"lat":51.1575693,"lon":3.1890951},{"type":"node","id":3930713442,"lat":51.1575932,"lon":3.1879961},{"type":"node","id":3930713446,"lat":51.1577118,"lon":3.1885611},{"type":"node","id":3930713447,"lat":51.157698,"lon":3.1894886},{"type":"node","id":3930713451,"lat":51.1577702,"lon":3.1892488},{"type":"node","id":3930713454,"lat":51.1577969,"lon":3.1882567},{"type":"node","id":4043782112,"lat":51.1549447,"lon":3.1864571},{"type":"node","id":5552466013,"lat":51.1545783,"lon":3.1874672},{"type":"node","id":5552466014,"lat":51.1543143,"lon":3.1873045},{"type":"node","id":5552466018,"lat":51.1545999,"lon":3.1873846},{"type":"node","id":5552466020,"lat":51.1548079,"lon":3.1868846},{"type":"node","id":5825400688,"lat":51.1549303,"lon":3.1867969},{"type":"node","id":5826811614,"lat":51.1572659,"lon":3.1885288},{"type":"node","id":6949357906,"lat":51.1572911,"lon":3.1915323},{"type":"node","id":6949357909,"lat":51.1573109,"lon":3.1914572},{"type":"node","id":6949357910,"lat":51.1574373,"lon":3.1913744},{"type":"node","id":6949357911,"lat":51.1574179,"lon":3.1914502},{"type":"node","id":6949357912,"lat":51.1575109,"lon":3.1915112},{"type":"node","id":6949357913,"lat":51.1575304,"lon":3.1914354},{"type":"node","id":6949357914,"lat":51.1574638,"lon":3.1912712},{"type":"node","id":6949357915,"lat":51.1574444,"lon":3.1913473},{"type":"node","id":6949357916,"lat":51.1575599,"lon":3.191423},{"type":"node","id":6949357917,"lat":51.1575803,"lon":3.1913473},{"type":"node","id":6949357918,"lat":51.157501,"lon":3.1911303},{"type":"node","id":6949357919,"lat":51.1574808,"lon":3.1912058},{"type":"node","id":6949357920,"lat":51.1577374,"lon":3.1913724},{"type":"node","id":6949357921,"lat":51.1577563,"lon":3.1912987},{"type":"node","id":6982605752,"lat":51.1574664,"lon":3.1885975},{"type":"node","id":6982605754,"lat":51.1574428,"lon":3.1885793},{"type":"node","id":6982605762,"lat":51.1576066,"lon":3.1884793},{"type":"node","id":6982605764,"lat":51.1576853,"lon":3.18854},{"type":"node","id":6982605766,"lat":51.1575125,"lon":3.1884502},{"type":"node","id":6982605767,"lat":51.1575959,"lon":3.1885145},{"type":"node","id":6982605769,"lat":51.1575152,"lon":3.1884412},{"type":"node","id":6982906542,"lat":51.1591649,"lon":3.1904238},{"type":"node","id":6982906543,"lat":51.1592937,"lon":3.1905221},{"type":"node","id":6982906544,"lat":51.1593438,"lon":3.1903659},{"type":"node","id":6982906545,"lat":51.1593158,"lon":3.1903453},{"type":"node","id":6982906546,"lat":51.1593351,"lon":3.1902852},{"type":"node","id":6982906547,"lat":51.1592385,"lon":3.1902052},{"type":"node","id":6997076562,"lat":51.1546633,"lon":3.1858333},{"type":"node","id":6997076563,"lat":51.1546293,"lon":3.1858642},{"type":"node","id":6997076564,"lat":51.154594,"lon":3.1856715},{"type":"node","id":6997076565,"lat":51.1546727,"lon":3.1859889},{"type":"node","id":6997076566,"lat":51.1545545,"lon":3.1860687},{"type":"node","id":6997076567,"lat":51.1543063,"lon":3.1869337},{"type":"node","id":6997096756,"lat":51.1547387,"lon":3.1868376},{"type":"node","id":6997096758,"lat":51.1546899,"lon":3.1870707},{"type":"node","id":6997096759,"lat":51.1546751,"lon":3.1870601},{"type":"node","id":7137343680,"lat":51.1558646,"lon":3.1876808},{"type":"node","id":7137343681,"lat":51.1558466,"lon":3.1877456},{"type":"node","id":7137343682,"lat":51.1555824,"lon":3.187559},{"type":"node","id":7137343683,"lat":51.1556004,"lon":3.1874941},{"type":"node","id":7137343684,"lat":51.1555549,"lon":3.1874612},{"type":"node","id":7137383185,"lat":51.1555369,"lon":3.1875268},{"type":"node","id":7137383186,"lat":51.1553925,"lon":3.1874261},{"type":"node","id":7137383187,"lat":51.1554105,"lon":3.1873604},{"type":"node","id":7519058287,"lat":51.1555296,"lon":3.1858152},{"type":"node","id":7519058288,"lat":51.1555027,"lon":3.1858752},{"type":"node","id":7519058289,"lat":51.1556329,"lon":3.1860234},{"type":"node","id":7519058290,"lat":51.1556597,"lon":3.1859634},{"type":"node","id":7519058291,"lat":51.1557039,"lon":3.1860155},{"type":"node","id":7519058292,"lat":51.1556789,"lon":3.1860736},{"type":"node","id":7519058293,"lat":51.1558105,"lon":3.1862177},{"type":"node","id":7519058294,"lat":51.1558355,"lon":3.1861597},{"type":"node","id":7519058295,"lat":51.1557209,"lon":3.185828},{"type":"node","id":7519058296,"lat":51.1556932,"lon":3.1858902},{"type":"node","id":7519058297,"lat":51.1558686,"lon":3.1860888},{"type":"node","id":7519058298,"lat":51.1558963,"lon":3.1860265},{"type":"node","id":7519058299,"lat":51.1555421,"lon":3.1856365},{"type":"node","id":7519058300,"lat":51.1555168,"lon":3.1856923},{"type":"node","id":7519058301,"lat":51.1556479,"lon":3.1858437},{"type":"node","id":7519058302,"lat":51.1556732,"lon":3.1857879},{"type":"node","id":150996092,"lat":51.1554945,"lon":3.1954639},{"type":"node","id":150996093,"lat":51.155531,"lon":3.1953168},{"type":"node","id":150996094,"lat":51.1554912,"lon":3.1943936},{"type":"node","id":150996095,"lat":51.155456,"lon":3.1942488},{"type":"node","id":150996097,"lat":51.155432,"lon":3.1942095},{"type":"node","id":150996098,"lat":51.155397,"lon":3.1941906},{"type":"node","id":150996099,"lat":51.1552938,"lon":3.1945134},{"type":"node","id":150996100,"lat":51.1552701,"lon":3.1949002},{"type":"node","id":150996101,"lat":51.1553901,"lon":3.1953415},{"type":"node","id":1015567837,"lat":51.1603457,"lon":3.1926746},{"type":"node","id":1015583939,"lat":51.1598982,"lon":3.1934595},{"type":"node","id":1659850846,"lat":51.1562462,"lon":3.1925019},{"type":"node","id":1811699776,"lat":51.1604859,"lon":3.1920734},{"type":"node","id":1811699777,"lat":51.1605587,"lon":3.1917984},{"type":"node","id":1817319289,"lat":51.1599853,"lon":3.1935159},{"type":"node","id":1817319290,"lat":51.1600476,"lon":3.1933385},{"type":"node","id":1817319291,"lat":51.1600745,"lon":3.1934309},{"type":"node","id":1817319292,"lat":51.1602073,"lon":3.1941751},{"type":"node","id":1817319293,"lat":51.160208,"lon":3.1941098},{"type":"node","id":1817319294,"lat":51.1602178,"lon":3.1935425},{"type":"node","id":1817319295,"lat":51.1602385,"lon":3.19297},{"type":"node","id":1817319296,"lat":51.1602972,"lon":3.1940248},{"type":"node","id":1817319297,"lat":51.1603313,"lon":3.193809},{"type":"node","id":1817319298,"lat":51.1603427,"lon":3.1930326},{"type":"node","id":1817319299,"lat":51.1603716,"lon":3.1940192},{"type":"node","id":1817319300,"lat":51.1603777,"lon":3.1946319},{"type":"node","id":1817319301,"lat":51.1604665,"lon":3.193304},{"type":"node","id":1817319302,"lat":51.1604758,"lon":3.1939077},{"type":"node","id":1817319303,"lat":51.1605421,"lon":3.194476},{"type":"node","id":1817319304,"lat":51.1606037,"lon":3.1933895},{"type":"node","id":1817320493,"lat":51.1604248,"lon":3.1927398},{"type":"node","id":1817320494,"lat":51.1604851,"lon":3.192495},{"type":"node","id":2451569392,"lat":51.1598651,"lon":3.1919974},{"type":"node","id":2451574741,"lat":51.1594995,"lon":3.1924908},{"type":"node","id":2451574742,"lat":51.1596217,"lon":3.1923259},{"type":"node","id":2451574743,"lat":51.1597161,"lon":3.1922023},{"type":"node","id":2451574744,"lat":51.1600391,"lon":3.1932123},{"type":"node","id":2451574745,"lat":51.1601904,"lon":3.192947},{"type":"node","id":2451574746,"lat":51.1603862,"lon":3.1925461},{"type":"node","id":2451574747,"lat":51.1604272,"lon":3.19257},{"type":"node","id":2451574748,"lat":51.1604837,"lon":3.1921535},{"type":"node","id":2451574749,"lat":51.1605266,"lon":3.1921769},{"type":"node","id":2451578121,"lat":51.159758,"lon":3.1921448},{"type":"node","id":5587844460,"lat":51.1562664,"lon":3.1919544},{"type":"node","id":5587844461,"lat":51.15612,"lon":3.1920681},{"type":"node","id":5587844462,"lat":51.1561808,"lon":3.1922614},{"type":"node","id":5599314384,"lat":51.1563882,"lon":3.1923707},{"type":"node","id":5599314385,"lat":51.1563587,"lon":3.1924465},{"type":"node","id":6754312541,"lat":51.154716,"lon":3.1952084},{"type":"node","id":6754312542,"lat":51.1547723,"lon":3.1953372},{"type":"node","id":6754312543,"lat":51.1548078,"lon":3.1952983},{"type":"node","id":6754312544,"lat":51.1547519,"lon":3.1951702},{"type":"node","id":6754312550,"lat":51.1555879,"lon":3.1950341},{"type":"node","id":6754312551,"lat":51.1556025,"lon":3.194956},{"type":"node","id":6754312552,"lat":51.1555664,"lon":3.1952408},{"type":"node","id":6754312553,"lat":51.1556188,"lon":3.1951751},{"type":"node","id":6754312554,"lat":51.1554565,"lon":3.195427},{"type":"node","id":6754312555,"lat":51.1552894,"lon":3.1950649},{"type":"node","id":6754312556,"lat":51.1553277,"lon":3.1951991},{"type":"node","id":6754312557,"lat":51.1552774,"lon":3.1947027},{"type":"node","id":6754312558,"lat":51.1553131,"lon":3.1943816},{"type":"node","id":6754312559,"lat":51.1553397,"lon":3.1942577},{"type":"node","id":6754312560,"lat":51.1553697,"lon":3.1942084},{"type":"node","id":6754312562,"lat":51.1548064,"lon":3.1954209},{"type":"node","id":6754312563,"lat":51.1548266,"lon":3.1954893},{"type":"node","id":6754312564,"lat":51.1550417,"lon":3.1953175},{"type":"node","id":6754312565,"lat":51.1550193,"lon":3.1952538},{"type":"node","id":6870850178,"lat":51.1561935,"lon":3.1923019},{"type":"node","id":6870863414,"lat":51.1562489,"lon":3.1919675},{"type":"node","id":6949357907,"lat":51.1575239,"lon":3.1916859},{"type":"node","id":6949357908,"lat":51.1575439,"lon":3.1916101},{"type":"node","id":1448421081,"lat":51.167491,"lon":3.1713256},{"type":"node","id":1448421091,"lat":51.1677042,"lon":3.1714548},{"type":"node","id":1448421093,"lat":51.1677455,"lon":3.1702529},{"type":"node","id":1448421099,"lat":51.1679647,"lon":3.1703977},{"type":"node","id":6536026850,"lat":51.1711159,"lon":3.1669401},{"type":"node","id":6536026851,"lat":51.1712692,"lon":3.167296},{"type":"node","id":6536026852,"lat":51.1711296,"lon":3.1674712},{"type":"node","id":6536026853,"lat":51.1709602,"lon":3.1671189},{"type":"node","id":6536038234,"lat":51.1711913,"lon":3.165543},{"type":"node","id":6536038235,"lat":51.1711301,"lon":3.1656263},{"type":"node","id":6536038236,"lat":51.1712318,"lon":3.1658161},{"type":"node","id":6536038237,"lat":51.171293,"lon":3.1657327},{"type":"node","id":1038583451,"lat":51.1625071,"lon":3.191602},{"type":"node","id":4044171936,"lat":51.1609177,"lon":3.1911926},{"type":"node","id":4044171941,"lat":51.1609801,"lon":3.191229},{"type":"node","id":4044171963,"lat":51.1611962,"lon":3.1913534},{"type":"node","id":903903386,"lat":51.1618084,"lon":3.1932127},{"type":"node","id":903903387,"lat":51.1623536,"lon":3.1936011},{"type":"node","id":903903388,"lat":51.1624429,"lon":3.1931156},{"type":"node","id":903903390,"lat":51.1618641,"lon":3.1930197},{"type":"node","id":903904576,"lat":51.1618211,"lon":3.1931711},{"type":"node","id":1038557012,"lat":51.16155,"lon":3.1931121},{"type":"node","id":1038557014,"lat":51.1613774,"lon":3.1930711},{"type":"node","id":1038557035,"lat":51.1615349,"lon":3.1931712},{"type":"node","id":1038557072,"lat":51.1616138,"lon":3.1927483},{"type":"node","id":1038557075,"lat":51.162286,"lon":3.1935989},{"type":"node","id":1038557078,"lat":51.1616517,"lon":3.1928439},{"type":"node","id":1038557083,"lat":51.1616055,"lon":3.1930249},{"type":"node","id":1038557094,"lat":51.1618993,"lon":3.193299},{"type":"node","id":1038557102,"lat":51.1613235,"lon":3.1927138},{"type":"node","id":1038557104,"lat":51.1615987,"lon":3.1928077},{"type":"node","id":1038557108,"lat":51.1615113,"lon":3.1926816},{"type":"node","id":1038557137,"lat":51.1608873,"lon":3.1924416},{"type":"node","id":1038557143,"lat":51.1622248,"lon":3.193662},{"type":"node","id":1038557191,"lat":51.1608171,"lon":3.1926951},{"type":"node","id":1038557195,"lat":51.162409,"lon":3.1933428},{"type":"node","id":1038557227,"lat":51.1613767,"lon":3.1925113},{"type":"node","id":1038557230,"lat":51.1615281,"lon":3.1926132},{"type":"node","id":1038557233,"lat":51.1619765,"lon":3.1933723},{"type":"node","id":1038575040,"lat":51.1608523,"lon":3.1925679},{"type":"node","id":1038583375,"lat":51.1625113,"lon":3.1926776},{"type":"node","id":1038583398,"lat":51.1624305,"lon":3.1925743},{"type":"node","id":1038583404,"lat":51.1627055,"lon":3.191826},{"type":"node","id":1038583425,"lat":51.1624272,"lon":3.1916637},{"type":"node","id":1038583441,"lat":51.1621479,"lon":3.1921546},{"type":"node","id":1038583446,"lat":51.1622018,"lon":3.1921814},{"type":"node","id":1038583456,"lat":51.162174,"lon":3.1922806},{"type":"node","id":1038583459,"lat":51.162259,"lon":3.1924885},{"type":"node","id":1038583463,"lat":51.162661,"lon":3.1917442},{"type":"node","id":1038583476,"lat":51.1626425,"lon":3.1918448},{"type":"node","id":1038583479,"lat":51.1624196,"lon":3.1926561},{"type":"node","id":1038583483,"lat":51.1625037,"lon":3.1927232},{"type":"node","id":1038583491,"lat":51.1625701,"lon":3.1926387},{"type":"node","id":1038583501,"lat":51.1624928,"lon":3.1917013},{"type":"node","id":1811673418,"lat":51.1618484,"lon":3.1950253},{"type":"node","id":1811673421,"lat":51.1619875,"lon":3.1951427},{"type":"node","id":1811673423,"lat":51.162144,"lon":3.193835},{"type":"node","id":1811673425,"lat":51.1622452,"lon":3.1939149},{"type":"node","id":1811699778,"lat":51.1608187,"lon":3.1922973},{"type":"node","id":1811699779,"lat":51.1608915,"lon":3.1920223},{"type":"node","id":1817320495,"lat":51.1607269,"lon":3.192929},{"type":"node","id":1817320496,"lat":51.1607872,"lon":3.1926841},{"type":"node","id":1817324488,"lat":51.1615575,"lon":3.1921423},{"type":"node","id":1817324489,"lat":51.1612682,"lon":3.1920196},{"type":"node","id":1817324491,"lat":51.1617501,"lon":3.1918468},{"type":"node","id":1817324505,"lat":51.1618272,"lon":3.1921231},{"type":"node","id":1817324509,"lat":51.1618658,"lon":3.191793},{"type":"node","id":1817324513,"lat":51.1619814,"lon":3.1920002},{"type":"node","id":1817324515,"lat":51.161985,"lon":3.191793},{"type":"node","id":3550860268,"lat":51.1617349,"lon":3.1921922},{"type":"node","id":3550860269,"lat":51.1619403,"lon":3.1920686},{"type":"node","id":4044171924,"lat":51.1608199,"lon":3.1916126},{"type":"node","id":4044171954,"lat":51.1610853,"lon":3.191781},{"type":"node","id":4044171957,"lat":51.1611433,"lon":3.1918701},{"type":"node","id":4044171962,"lat":51.1611926,"lon":3.1916807},{"type":"node","id":4044171976,"lat":51.1612826,"lon":3.1919582},{"type":"node","id":4044171997,"lat":51.1613568,"lon":3.1917787},{"type":"node","id":4044172003,"lat":51.1613248,"lon":3.1919027},{"type":"node","id":4044172008,"lat":51.1614345,"lon":3.1919767},{"type":"node","id":6397031888,"lat":51.1615029,"lon":3.1919851},{"type":"node","id":6960473080,"lat":51.1614227,"lon":3.1931004},{"type":"node","id":3335137692,"lat":51.1698302,"lon":3.1965654},{"type":"node","id":3335137795,"lat":51.1698788,"lon":3.1970728},{"type":"node","id":3335137802,"lat":51.1700082,"lon":3.1971734},{"type":"node","id":3335137807,"lat":51.1701139,"lon":3.1965001},{"type":"node","id":3335137812,"lat":51.1703247,"lon":3.197352},{"type":"node","id":3335137823,"lat":51.1703133,"lon":3.1966232},{"type":"node","id":6255587427,"lat":51.1694775,"lon":3.1980047},{"type":"node","id":9163486855,"lat":51.1703854,"lon":3.1970901},{"type":"node","id":9163486856,"lat":51.1702114,"lon":3.1969688},{"type":"node","id":9163493632,"lat":51.1699473,"lon":3.197063},{"type":"node","id":414025563,"lat":51.1768198,"lon":3.1839265},{"type":"node","id":2325437840,"lat":51.1765747,"lon":3.1839745},{"type":"node","id":2325437844,"lat":51.1768286,"lon":3.1825946},{"type":"node","id":8191691970,"lat":51.1767611,"lon":3.1839766},{"type":"node","id":8191691971,"lat":51.1767812,"lon":3.1826167},{"type":"node","id":8191691972,"lat":51.1765804,"lon":3.1826583},{"type":"node","id":8191691973,"lat":51.1766324,"lon":3.182616},{"type":"node","id":5716136617,"lat":51.1773127,"lon":3.1969033},{"type":"node","id":5716136618,"lat":51.1771859,"lon":3.1969078},{"type":"node","id":5716136619,"lat":51.177203,"lon":3.1981369},{"type":"node","id":5716136620,"lat":51.1773298,"lon":3.1981324},{"type":"node","id":6004375826,"lat":51.1786839,"lon":3.1952389},{"type":"node","id":6625037999,"lat":51.1788016,"lon":3.1950645},{"type":"node","id":6625038000,"lat":51.1789916,"lon":3.1966631},{"type":"node","id":6625038001,"lat":51.1789003,"lon":3.1966838},{"type":"node","id":6625038002,"lat":51.1788554,"lon":3.1963547},{"type":"node","id":6625038003,"lat":51.1788165,"lon":3.1963622},{"type":"node","id":6625038005,"lat":51.1785124,"lon":3.1952362},{"type":"node","id":6625038006,"lat":51.1784779,"lon":3.1950618},{"type":"node","id":6925536539,"lat":51.1522475,"lon":3.1985416},{"type":"node","id":6925536540,"lat":51.1522635,"lon":3.1986187},{"type":"node","id":6925536541,"lat":51.1523922,"lon":3.1985517},{"type":"node","id":6925536542,"lat":51.1523766,"lon":3.1984746},{"type":"node","id":1637742821,"lat":51.158524,"lon":3.199021},{"type":"node","id":5586765933,"lat":51.1566667,"lon":3.2008881},{"type":"node","id":5586765934,"lat":51.1564286,"lon":3.2012575},{"type":"node","id":5586765935,"lat":51.1562496,"lon":3.2008579},{"type":"node","id":5586765936,"lat":51.1564982,"lon":3.200522},{"type":"node","id":6943148197,"lat":51.1581916,"lon":3.1989071},{"type":"node","id":6943148198,"lat":51.1582377,"lon":3.1989899},{"type":"node","id":6943148199,"lat":51.1581859,"lon":3.1990728},{"type":"node","id":6943148200,"lat":51.1583257,"lon":3.199295},{"type":"node","id":6943148201,"lat":51.1583563,"lon":3.199246},{"type":"node","id":6943148202,"lat":51.1583988,"lon":3.1993135},{"type":"node","id":6943148203,"lat":51.1585529,"lon":3.1990669},{"type":"node","id":6943148204,"lat":51.1586554,"lon":3.1988109},{"type":"node","id":6943148205,"lat":51.1585617,"lon":3.1986619},{"type":"node","id":6943148206,"lat":51.1586782,"lon":3.1984755},{"type":"node","id":6943148207,"lat":51.1585692,"lon":3.1982996},{"type":"node","id":8065883225,"lat":51.1366029,"lon":3.233506},{"type":"node","id":8065883226,"lat":51.1364627,"lon":3.2335338},{"type":"node","id":8065883227,"lat":51.1363922,"lon":3.2326314},{"type":"node","id":8065883228,"lat":51.1365324,"lon":3.2326036},{"type":"node","id":8065883229,"lat":51.1374344,"lon":3.2333338},{"type":"node","id":8065883230,"lat":51.1373632,"lon":3.2324534},{"type":"node","id":8065883232,"lat":51.1375819,"lon":3.2333035},{"type":"node","id":8065883233,"lat":51.1375107,"lon":3.232423},{"type":"node","id":1795793393,"lat":51.1475704,"lon":3.233832},{"type":"node","id":3346575840,"lat":51.146485,"lon":3.2349284},{"type":"node","id":3346575846,"lat":51.1465127,"lon":3.2355341},{"type":"node","id":3346575853,"lat":51.1466617,"lon":3.2349708},{"type":"node","id":3346575855,"lat":51.1466787,"lon":3.2355171},{"type":"node","id":3346575858,"lat":51.1466968,"lon":3.2342532},{"type":"node","id":3346575865,"lat":51.1468756,"lon":3.2344143},{"type":"node","id":3346575873,"lat":51.1469706,"lon":3.2366779},{"type":"node","id":3346575929,"lat":51.1474307,"lon":3.2366434},{"type":"node","id":1523513488,"lat":51.1398248,"lon":3.2392608},{"type":"node","id":1744641292,"lat":51.1395814,"lon":3.2390365},{"type":"node","id":1744641293,"lat":51.1397822,"lon":3.2393867},{"type":"node","id":1920143232,"lat":51.1394724,"lon":3.2390121},{"type":"node","id":7393009684,"lat":51.1394307,"lon":3.2390001},{"type":"node","id":7393048385,"lat":51.1394135,"lon":3.2390524},{"type":"node","id":3346575843,"lat":51.1465041,"lon":3.2376453},{"type":"node","id":3346575845,"lat":51.146508,"lon":3.2378517},{"type":"node","id":3346575876,"lat":51.1470052,"lon":3.237604},{"type":"node","id":3346575886,"lat":51.147098,"lon":3.2412975},{"type":"node","id":3346575889,"lat":51.1471585,"lon":3.2428761},{"type":"node","id":3346575891,"lat":51.1471715,"lon":3.2377865},{"type":"node","id":3346575901,"lat":51.1472492,"lon":3.2398591},{"type":"node","id":3346575903,"lat":51.1472654,"lon":3.242623},{"type":"node","id":3346575908,"lat":51.1472751,"lon":3.2428571},{"type":"node","id":3346575917,"lat":51.1473518,"lon":3.2426093},{"type":"node","id":3346575923,"lat":51.1473906,"lon":3.2398205},{"type":"node","id":3346575925,"lat":51.147408,"lon":3.2424474},{"type":"node","id":3346575928,"lat":51.1474263,"lon":3.24062},{"type":"node","id":3346575933,"lat":51.1474728,"lon":3.2421565},{"type":"node","id":3346575943,"lat":51.1475354,"lon":3.2418174},{"type":"node","id":3346575945,"lat":51.1475494,"lon":3.2412786},{"type":"node","id":3346575946,"lat":51.1475667,"lon":3.2415454},{"type":"node","id":6291339815,"lat":51.1434669,"lon":3.2496811},{"type":"node","id":6291339816,"lat":51.1434103,"lon":3.2497287},{"type":"node","id":6291339821,"lat":51.1435685,"lon":3.2496576},{"type":"node","id":6291339822,"lat":51.1434825,"lon":3.2497283},{"type":"node","id":6291339827,"lat":51.1437401,"lon":3.2490327},{"type":"node","id":6291339828,"lat":51.1433037,"lon":3.2494123},{"type":"node","id":6291339829,"lat":51.1436099,"lon":3.2497855},{"type":"node","id":6291339830,"lat":51.1439041,"lon":3.249535},{"type":"node","id":170464837,"lat":51.1533286,"lon":3.236239},{"type":"node","id":170464839,"lat":51.1532379,"lon":3.2364578},{"type":"node","id":1710262731,"lat":51.1513274,"lon":3.2373199},{"type":"node","id":1710262732,"lat":51.1508759,"lon":3.2370371},{"type":"node","id":1710262733,"lat":51.1509316,"lon":3.2370599},{"type":"node","id":1710262735,"lat":51.1510166,"lon":3.2370123},{"type":"node","id":1710262738,"lat":51.1512751,"lon":3.2372984},{"type":"node","id":1710262742,"lat":51.1513127,"lon":3.237065},{"type":"node","id":1710262743,"lat":51.1508201,"lon":3.2373832},{"type":"node","id":1710262745,"lat":51.151027,"lon":3.2369479},{"type":"node","id":1795793395,"lat":51.1476158,"lon":3.2338163},{"type":"node","id":1795793397,"lat":51.1475842,"lon":3.2344427},{"type":"node","id":1795793399,"lat":51.1477641,"lon":3.233033},{"type":"node","id":1795793405,"lat":51.1477717,"lon":3.2338665},{"type":"node","id":1795793406,"lat":51.1480775,"lon":3.2344787},{"type":"node","id":1795793407,"lat":51.1478893,"lon":3.2344203},{"type":"node","id":1795793408,"lat":51.1481719,"lon":3.2342485},{"type":"node","id":1795793409,"lat":51.147607,"lon":3.2330256},{"type":"node","id":4979389763,"lat":51.1476223,"lon":3.2330288},{"type":"node","id":8179735224,"lat":51.156047,"lon":3.2252534},{"type":"node","id":8179735264,"lat":51.1560464,"lon":3.2252785},{"type":"node","id":8179735265,"lat":51.1558544,"lon":3.2252597},{"type":"node","id":8179735266,"lat":51.1556789,"lon":3.2252522},{"type":"node","id":8179735267,"lat":51.1555253,"lon":3.2252547},{"type":"node","id":8179735268,"lat":51.1555747,"lon":3.2250024},{"type":"node","id":8179735269,"lat":51.1560527,"lon":3.2250198},{"type":"node","id":1525460846,"lat":51.1550489,"lon":3.2347709},{"type":"node","id":1810326044,"lat":51.1547625,"lon":3.2355098},{"type":"node","id":1810326087,"lat":51.1547809,"lon":3.2353708},{"type":"node","id":4912203160,"lat":51.1554941,"lon":3.2364781},{"type":"node","id":4912203161,"lat":51.1554192,"lon":3.2369649},{"type":"node","id":4912203162,"lat":51.1554175,"lon":3.2371071},{"type":"node","id":4912203163,"lat":51.1554301,"lon":3.2372063},{"type":"node","id":4912203164,"lat":51.1553847,"lon":3.2372197},{"type":"node","id":4912203165,"lat":51.1553763,"lon":3.2369502},{"type":"node","id":4912203166,"lat":51.1554512,"lon":3.236462},{"type":"node","id":4912203167,"lat":51.1555218,"lon":3.2366455},{"type":"node","id":4912203168,"lat":51.1554742,"lon":3.2369592},{"type":"node","id":4912203169,"lat":51.155516,"lon":3.2369752},{"type":"node","id":4912203170,"lat":51.1555635,"lon":3.2366616},{"type":"node","id":4912203171,"lat":51.1556125,"lon":3.2360775},{"type":"node","id":4912203172,"lat":51.155547,"lon":3.2364923},{"type":"node","id":4912203173,"lat":51.1555893,"lon":3.2365092},{"type":"node","id":4912203174,"lat":51.1556547,"lon":3.2360945},{"type":"node","id":4912203176,"lat":51.1554841,"lon":3.2362949},{"type":"node","id":4912203177,"lat":51.1553752,"lon":3.2362591},{"type":"node","id":4912203178,"lat":51.1553968,"lon":3.2360924},{"type":"node","id":4912203179,"lat":51.1555056,"lon":3.2361281},{"type":"node","id":4912214680,"lat":51.1553544,"lon":3.2348128},{"type":"node","id":4912214681,"lat":51.1550186,"lon":3.2346814},{"type":"node","id":4912214685,"lat":51.1554486,"lon":3.2338965},{"type":"node","id":4912214686,"lat":51.1550098,"lon":3.2346405},{"type":"node","id":4912214692,"lat":51.155386,"lon":3.2347722},{"type":"node","id":4912214693,"lat":51.1555155,"lon":3.2338415},{"type":"node","id":4912214694,"lat":51.1554587,"lon":3.2338214},{"type":"node","id":4912214695,"lat":51.1553292,"lon":3.2347521},{"type":"node","id":4912225050,"lat":51.1553136,"lon":3.234866},{"type":"node","id":4912225051,"lat":51.1551036,"lon":3.2337751},{"type":"node","id":4912225052,"lat":51.1549825,"lon":3.2346307},{"type":"node","id":4912225053,"lat":51.1551894,"lon":3.2336789},{"type":"node","id":4912225062,"lat":51.1551528,"lon":3.233747},{"type":"node","id":4912225063,"lat":51.1551831,"lon":3.2337249},{"type":"node","id":4912225064,"lat":51.1554653,"lon":3.2337755},{"type":"node","id":4912225067,"lat":51.1551309,"lon":3.2337849},{"type":"node","id":4912225068,"lat":51.1551727,"lon":3.2337999},{"type":"node","id":4912225069,"lat":51.1553182,"lon":3.2348322},{"type":"node","id":4912225070,"lat":51.1550516,"lon":3.2346556},{"type":"node","id":5972179331,"lat":51.154488,"lon":3.2350802},{"type":"node","id":5972179343,"lat":51.1545781,"lon":3.2351138},{"type":"node","id":5972179344,"lat":51.1546444,"lon":3.2351409},{"type":"node","id":5972179345,"lat":51.1546431,"lon":3.2351485},{"type":"node","id":5972179346,"lat":51.1547126,"lon":3.2351739},{"type":"node","id":5972179347,"lat":51.154714,"lon":3.2351659},{"type":"node","id":5972179348,"lat":51.1547795,"lon":3.235188},{"type":"node","id":5974489614,"lat":51.1546386,"lon":3.2355125},{"type":"node","id":5974489615,"lat":51.1544914,"lon":3.2353516},{"type":"node","id":5974489616,"lat":51.1544813,"lon":3.2351384},{"type":"node","id":5974489617,"lat":51.1548024,"lon":3.2352003},{"type":"node","id":5974489618,"lat":51.154732,"lon":3.2356091},{"type":"node","id":7529417225,"lat":51.159095,"lon":3.2366844},{"type":"node","id":7529417226,"lat":51.1589926,"lon":3.2372825},{"type":"node","id":7529417227,"lat":51.1588687,"lon":3.2372286},{"type":"node","id":7529417228,"lat":51.1589264,"lon":3.2368918},{"type":"node","id":7529417229,"lat":51.1588879,"lon":3.236875},{"type":"node","id":7529417230,"lat":51.1589326,"lon":3.2366138},{"type":"node","id":7529417232,"lat":51.159019,"lon":3.2366513},{"type":"node","id":170464840,"lat":51.1531619,"lon":3.2376814},{"type":"node","id":170464841,"lat":51.1532306,"lon":3.2376888},{"type":"node","id":1710245701,"lat":51.1528676,"lon":3.2390068},{"type":"node","id":1710245703,"lat":51.1527703,"lon":3.239403},{"type":"node","id":1710245705,"lat":51.1527888,"lon":3.2390966},{"type":"node","id":1710245707,"lat":51.1526357,"lon":3.2390543},{"type":"node","id":1710245709,"lat":51.1528763,"lon":3.2390382},{"type":"node","id":1710245711,"lat":51.1528928,"lon":3.2390631},{"type":"node","id":1710245713,"lat":51.1528729,"lon":3.2389738},{"type":"node","id":1710245715,"lat":51.1528645,"lon":3.2394083},{"type":"node","id":1710245718,"lat":51.1526407,"lon":3.2389524},{"type":"node","id":1710262736,"lat":51.1512857,"lon":3.2375783},{"type":"node","id":1710262737,"lat":51.151234,"lon":3.2375571},{"type":"node","id":1710262739,"lat":51.151183,"lon":3.2375939},{"type":"node","id":1710262741,"lat":51.1511924,"lon":3.2375358},{"type":"node","id":1710262744,"lat":51.1512252,"lon":3.2376112},{"type":"node","id":3346575950,"lat":51.1475926,"lon":3.2406028},{"type":"node","id":1728421374,"lat":51.1554436,"lon":3.2438233},{"type":"node","id":1728421375,"lat":51.15594,"lon":3.2438649},{"type":"node","id":1728421377,"lat":51.15559,"lon":3.2439695},{"type":"node","id":1728421379,"lat":51.1554335,"lon":3.243944},{"type":"node","id":1770289505,"lat":51.1565437,"lon":3.2437924},{"type":"node","id":4912197362,"lat":51.1565535,"lon":3.2438327},{"type":"node","id":4912197363,"lat":51.1562818,"lon":3.2438374},{"type":"node","id":4912197364,"lat":51.1565321,"lon":3.2435757},{"type":"node","id":4912197365,"lat":51.1565279,"lon":3.2433181},{"type":"node","id":4912197366,"lat":51.1562804,"lon":3.2435833},{"type":"node","id":4912197367,"lat":51.1562798,"lon":3.2431702},{"type":"node","id":4912197368,"lat":51.1562813,"lon":3.2437497},{"type":"node","id":4912197369,"lat":51.1562802,"lon":3.243488},{"type":"node","id":4912197370,"lat":51.1565257,"lon":3.2431702},{"type":"node","id":4912197371,"lat":51.1565542,"lon":3.2439044},{"type":"node","id":4912197372,"lat":51.1565308,"lon":3.2437482},{"type":"node","id":4912197373,"lat":51.1565294,"lon":3.2434893},{"type":"node","id":4912197374,"lat":51.1562835,"lon":3.2439005},{"type":"node","id":1710276232,"lat":51.1572435,"lon":3.2451269},{"type":"node","id":1710276240,"lat":51.156984,"lon":3.2453481},{"type":"node","id":1710276242,"lat":51.1567167,"lon":3.2452913},{"type":"node","id":1710276243,"lat":51.1570484,"lon":3.2451},{"type":"node","id":1710276251,"lat":51.1562241,"lon":3.2457572},{"type":"node","id":1710276253,"lat":51.156868,"lon":3.2451689},{"type":"node","id":1710276255,"lat":51.1563873,"lon":3.2456553},{"type":"node","id":1710276257,"lat":51.1572402,"lon":3.2450303},{"type":"node","id":1710276259,"lat":51.1561703,"lon":3.2454299},{"type":"node","id":1710276261,"lat":51.1564411,"lon":3.2457304},{"type":"node","id":1728421376,"lat":51.1555858,"lon":3.2441572},{"type":"node","id":1728421378,"lat":51.1559348,"lon":3.2441264},{"type":"node","id":1810330766,"lat":51.1562599,"lon":3.2457349},{"type":"node","id":1810345944,"lat":51.1572859,"lon":3.2458614},{"type":"node","id":1810345947,"lat":51.1568366,"lon":3.2461909},{"type":"node","id":1810345951,"lat":51.1572074,"lon":3.2455895},{"type":"node","id":1810345955,"lat":51.1567582,"lon":3.245919},{"type":"node","id":1810347217,"lat":51.1568783,"lon":3.2452387},{"type":"node","id":6255587424,"lat":51.1699788,"lon":3.1988617},{"type":"node","id":6255587425,"lat":51.1695322,"lon":3.1995447},{"type":"node","id":6255587426,"lat":51.1690026,"lon":3.1986489},{"type":"node","id":5173881316,"lat":51.1728811,"lon":3.210692},{"type":"node","id":5173881317,"lat":51.1728829,"lon":3.21077},{"type":"node","id":5173881318,"lat":51.1726197,"lon":3.2107914},{"type":"node","id":5173881320,"lat":51.1728794,"lon":3.2108575},{"type":"node","id":5173881621,"lat":51.1728791,"lon":3.2109364},{"type":"node","id":5173881622,"lat":51.1727133,"lon":3.2109488},{"type":"node","id":5173881623,"lat":51.1727117,"lon":3.2108703},{"type":"node","id":5173881624,"lat":51.1728613,"lon":3.211069},{"type":"node","id":5173881625,"lat":51.1728601,"lon":3.2111406},{"type":"node","id":5173881626,"lat":51.1727019,"lon":3.2111316},{"type":"node","id":5173881627,"lat":51.1727041,"lon":3.2110597},{"type":"node","id":6275462772,"lat":51.1733576,"lon":3.2110928},{"type":"node","id":6275462773,"lat":51.1733528,"lon":3.2112295},{"type":"node","id":6275462774,"lat":51.1735278,"lon":3.2112449},{"type":"node","id":6275462775,"lat":51.1735325,"lon":3.2111082},{"type":"node","id":6275462776,"lat":51.1736659,"lon":3.2112568},{"type":"node","id":6275462777,"lat":51.1736113,"lon":3.2112529},{"type":"node","id":6275462784,"lat":51.1735598,"lon":3.2109277},{"type":"node","id":6275462985,"lat":51.1734626,"lon":3.2109229},{"type":"node","id":6275462986,"lat":51.1734599,"lon":3.2110592},{"type":"node","id":6275462987,"lat":51.1735572,"lon":3.211064},{"type":"node","id":6275462988,"lat":51.1734613,"lon":3.2109904},{"type":"node","id":6275462989,"lat":51.173357,"lon":3.2111476},{"type":"node","id":7054196467,"lat":51.1726209,"lon":3.2107131},{"type":"node","id":8042845810,"lat":51.1737696,"lon":3.206708},{"type":"node","id":8042845811,"lat":51.1734466,"lon":3.2056148},{"type":"node","id":5952389321,"lat":51.1668901,"lon":3.2166736},{"type":"node","id":5952389322,"lat":51.1664592,"lon":3.2166337},{"type":"node","id":5952389323,"lat":51.1659941,"lon":3.2166018},{"type":"node","id":5172938444,"lat":51.1667283,"lon":3.2192609},{"type":"node","id":5536609426,"lat":51.1664884,"lon":3.2184803},{"type":"node","id":5536620510,"lat":51.1668363,"lon":3.2197448},{"type":"node","id":5536620511,"lat":51.1671911,"lon":3.2210959},{"type":"node","id":5952389320,"lat":51.1665059,"lon":3.2183884},{"type":"node","id":5536620506,"lat":51.1675299,"lon":3.2170283},{"type":"node","id":5536620507,"lat":51.1672585,"lon":3.2168071},{"type":"node","id":6275462778,"lat":51.1736042,"lon":3.2115044},{"type":"node","id":6275462779,"lat":51.1736588,"lon":3.2115083},{"type":"node","id":6275462780,"lat":51.1735687,"lon":3.2112964},{"type":"node","id":6275462781,"lat":51.1735211,"lon":3.2112937},{"type":"node","id":6275462782,"lat":51.1735156,"lon":3.2115423},{"type":"node","id":6275462783,"lat":51.1735632,"lon":3.211545},{"type":"node","id":5536620505,"lat":51.1683944,"lon":3.2180288},{"type":"node","id":5536620512,"lat":51.1673641,"lon":3.2217199},{"type":"node","id":5536620513,"lat":51.1675007,"lon":3.2221772},{"type":"node","id":5536620514,"lat":51.1679104,"lon":3.2236675},{"type":"node","id":5536620516,"lat":51.1679955,"lon":3.224005},{"type":"node","id":5536620824,"lat":51.1700823,"lon":3.2236258},{"type":"node","id":5536620826,"lat":51.171324,"lon":3.2230929},{"type":"node","id":5536620827,"lat":51.1717731,"lon":3.2213846},{"type":"node","id":5536620828,"lat":51.170726,"lon":3.2202369},{"type":"node","id":5536620829,"lat":51.1706206,"lon":3.2201178},{"type":"node","id":5536620830,"lat":51.170049,"lon":3.2215441},{"type":"node","id":5536620831,"lat":51.1699442,"lon":3.2215294},{"type":"node","id":5536620832,"lat":51.1683757,"lon":3.2194636},{"type":"node","id":6067483781,"lat":51.1675243,"lon":3.222207},{"type":"node","id":6067483782,"lat":51.1713888,"lon":3.2231705},{"type":"node","id":7794736251,"lat":51.1688401,"lon":3.2184325},{"type":"node","id":1069177852,"lat":51.1789546,"lon":3.2021791},{"type":"node","id":1069177853,"lat":51.1801636,"lon":3.2031369},{"type":"node","id":1069177873,"lat":51.1791663,"lon":3.2034541},{"type":"node","id":1069177915,"lat":51.1799187,"lon":3.2029579},{"type":"node","id":1069177919,"lat":51.1786053,"lon":3.2030903},{"type":"node","id":1069177920,"lat":51.1790417,"lon":3.2033998},{"type":"node","id":1069177925,"lat":51.1788415,"lon":3.2032442},{"type":"node","id":1069177933,"lat":51.1798479,"lon":3.2029364},{"type":"node","id":1069177967,"lat":51.178467,"lon":3.2025563},{"type":"node","id":1069177976,"lat":51.1791427,"lon":3.2026954},{"type":"node","id":1069177984,"lat":51.1783718,"lon":3.2028231},{"type":"node","id":1069178021,"lat":51.1793534,"lon":3.2033094},{"type":"node","id":1069178133,"lat":51.1784113,"lon":3.2028156},{"type":"node","id":6853179202,"lat":51.1792037,"lon":3.2026994},{"type":"node","id":6853179203,"lat":51.1790601,"lon":3.2026755},{"type":"node","id":6853179204,"lat":51.1791861,"lon":3.2027108},{"type":"node","id":6853179205,"lat":51.1791741,"lon":3.2027122},{"type":"node","id":6853179206,"lat":51.1791634,"lon":3.2027102},{"type":"node","id":6853179207,"lat":51.1791526,"lon":3.2027048},{"type":"node","id":6853179208,"lat":51.1790128,"lon":3.202488},{"type":"node","id":6853179209,"lat":51.1790434,"lon":3.2026225},{"type":"node","id":6853179210,"lat":51.1789811,"lon":3.2023837},{"type":"node","id":6853179211,"lat":51.1789744,"lon":3.2022415},{"type":"node","id":6853179212,"lat":51.1789438,"lon":3.2022643},{"type":"node","id":6853179213,"lat":51.1784216,"lon":3.2028567},{"type":"node","id":6853179214,"lat":51.1784157,"lon":3.2028375},{"type":"node","id":6853179215,"lat":51.1784506,"lon":3.2029294},{"type":"node","id":6853179216,"lat":51.1783884,"lon":3.2026704},{"type":"node","id":6853179217,"lat":51.178422,"lon":3.2026034},{"type":"node","id":6853179218,"lat":51.1784117,"lon":3.2026185},{"type":"node","id":6853179219,"lat":51.1784021,"lon":3.2026354},{"type":"node","id":6853179220,"lat":51.1783957,"lon":3.2026505},{"type":"node","id":6853179221,"lat":51.178443,"lon":3.2025785},{"type":"node","id":6853179222,"lat":51.1784546,"lon":3.202567},{"type":"node","id":6853179223,"lat":51.1784321,"lon":3.2025906},{"type":"node","id":6853179224,"lat":51.1783719,"lon":3.2027464},{"type":"node","id":6853179225,"lat":51.1783749,"lon":3.2027238},{"type":"node","id":6853179226,"lat":51.1783827,"lon":3.2026894},{"type":"node","id":6853179227,"lat":51.1783784,"lon":3.2027066},{"type":"node","id":6853179228,"lat":51.1783697,"lon":3.2027864},{"type":"node","id":6853179229,"lat":51.1783704,"lon":3.2027651},{"type":"node","id":6853179230,"lat":51.1783703,"lon":3.2028048},{"type":"node","id":6853179234,"lat":51.1798837,"lon":3.2029379},{"type":"node","id":6853179235,"lat":51.1798988,"lon":3.2029445},{"type":"node","id":6853179236,"lat":51.1798661,"lon":3.2029354},{"type":"node","id":6853179237,"lat":51.1798345,"lon":3.2029407},{"type":"node","id":6853179238,"lat":51.1798207,"lon":3.2029479},{"type":"node","id":6853179239,"lat":51.1792634,"lon":3.2033377},{"type":"node","id":6853179240,"lat":51.1793019,"lon":3.2033359},{"type":"node","id":6853179241,"lat":51.1792828,"lon":3.20334},{"type":"node","id":6853179242,"lat":51.1792732,"lon":3.2033393},{"type":"node","id":6853179243,"lat":51.1792921,"lon":3.2033388},{"type":"node","id":6853179244,"lat":51.1793279,"lon":3.2033257},{"type":"node","id":6853179245,"lat":51.1793153,"lon":3.2033313},{"type":"node","id":6853179246,"lat":51.1793413,"lon":3.2033182},{"type":"node","id":6853179247,"lat":51.1792384,"lon":3.2033981},{"type":"node","id":6853179248,"lat":51.1792572,"lon":3.2033605},{"type":"node","id":6853179249,"lat":51.1792512,"lon":3.2033774},{"type":"node","id":6853179250,"lat":51.1792456,"lon":3.2033888},{"type":"node","id":6853179256,"lat":51.1790996,"lon":3.2034514},{"type":"node","id":6853179257,"lat":51.1790731,"lon":3.2034317},{"type":"node","id":6853179258,"lat":51.1790581,"lon":3.2034168},{"type":"node","id":6853179259,"lat":51.1790862,"lon":3.2034422},{"type":"node","id":6853179260,"lat":51.179133,"lon":3.2034648},{"type":"node","id":6853179261,"lat":51.1791191,"lon":3.203461},{"type":"node","id":6853179262,"lat":51.1791546,"lon":3.2034608},{"type":"node","id":6853179263,"lat":51.1791443,"lon":3.2034639},{"type":"node","id":6853179264,"lat":51.1789437,"lon":3.2033089},{"type":"node","id":6853179267,"lat":51.1785146,"lon":3.2030128},{"type":"node","id":6853179268,"lat":51.1785517,"lon":3.2030489},{"type":"node","id":6853179269,"lat":51.1785863,"lon":3.2030773},{"type":"node","id":6853179327,"lat":51.1789936,"lon":3.2024248},{"type":"node","id":7252820961,"lat":51.175521,"lon":3.2045972},{"type":"node","id":7252863798,"lat":51.1754304,"lon":3.2044959},{"type":"node","id":8042845806,"lat":51.1753353,"lon":3.2041851},{"type":"node","id":8042845807,"lat":51.175363,"lon":3.2043314},{"type":"node","id":8042845812,"lat":51.1752711,"lon":3.2040127},{"type":"node","id":4036885076,"lat":51.1740632,"lon":3.2050437},{"type":"node","id":4036899624,"lat":51.1767493,"lon":3.2082945},{"type":"node","id":5607796819,"lat":51.1782483,"lon":3.2091883},{"type":"node","id":5607796820,"lat":51.1785128,"lon":3.2086016},{"type":"node","id":5607798721,"lat":51.1786474,"lon":3.2090453},{"type":"node","id":5607798722,"lat":51.1782874,"lon":3.2093115},{"type":"node","id":5607798723,"lat":51.178141,"lon":3.2088491},{"type":"node","id":5607798725,"lat":51.1785713,"lon":3.2087945},{"type":"node","id":5728443539,"lat":51.1753294,"lon":3.2097039},{"type":"node","id":5728443540,"lat":51.1752216,"lon":3.2089278},{"type":"node","id":6275462768,"lat":51.174424,"lon":3.2105467},{"type":"node","id":6275462769,"lat":51.1743524,"lon":3.2105548},{"type":"node","id":6275462770,"lat":51.1743644,"lon":3.2108257},{"type":"node","id":6275462771,"lat":51.1744361,"lon":3.2108176},{"type":"node","id":7252820962,"lat":51.1756015,"lon":3.204854},{"type":"node","id":7252820963,"lat":51.1755802,"lon":3.204928},{"type":"node","id":7252820964,"lat":51.1755132,"lon":3.2049422},{"type":"node","id":7252820965,"lat":51.1754719,"lon":3.2050156},{"type":"node","id":7252820966,"lat":51.1754575,"lon":3.2051212},{"type":"node","id":7252820967,"lat":51.1755143,"lon":3.2052892},{"type":"node","id":7252820968,"lat":51.1755533,"lon":3.2055086},{"type":"node","id":7252820969,"lat":51.1755563,"lon":3.2060065},{"type":"node","id":7252820970,"lat":51.175491,"lon":3.2064409},{"type":"node","id":7252820971,"lat":51.1753674,"lon":3.2068348},{"type":"node","id":7252820972,"lat":51.1751944,"lon":3.2070531},{"type":"node","id":7252820973,"lat":51.1751195,"lon":3.2071478},{"type":"node","id":7252820974,"lat":51.1750834,"lon":3.2072467},{"type":"node","id":7252820975,"lat":51.1750963,"lon":3.2073579},{"type":"node","id":7252820976,"lat":51.1751376,"lon":3.2074032},{"type":"node","id":7252820977,"lat":51.175215,"lon":3.2073826},{"type":"node","id":7252820978,"lat":51.1752848,"lon":3.2073785},{"type":"node","id":7252820979,"lat":51.1754252,"lon":3.2073858},{"type":"node","id":7252820980,"lat":51.1754615,"lon":3.2074926},{"type":"node","id":7252820981,"lat":51.1754259,"lon":3.20756},{"type":"node","id":7252820982,"lat":51.17537,"lon":3.2076668},{"type":"node","id":7252820983,"lat":51.1753304,"lon":3.2078901},{"type":"node","id":7252820984,"lat":51.1753152,"lon":3.2079319},{"type":"node","id":7252874885,"lat":51.1754423,"lon":3.2080951},{"type":"node","id":7252874886,"lat":51.1754991,"lon":3.2083134},{"type":"node","id":7252874887,"lat":51.1755307,"lon":3.2084864},{"type":"node","id":7252874888,"lat":51.1755729,"lon":3.2087064},{"type":"node","id":7252874889,"lat":51.1753248,"lon":3.2088635},{"type":"node","id":7252874890,"lat":51.1752645,"lon":3.2092365},{"type":"node","id":7252874891,"lat":51.1747746,"lon":3.2093558},{"type":"node","id":8042845789,"lat":51.1748587,"lon":3.209526},{"type":"node","id":8042845790,"lat":51.1749489,"lon":3.2096774},{"type":"node","id":8042845791,"lat":51.1750595,"lon":3.2097458},{"type":"node","id":8042845792,"lat":51.1753557,"lon":3.2077924},{"type":"node","id":8042845793,"lat":51.1754621,"lon":3.2074425},{"type":"node","id":8042845794,"lat":51.1754531,"lon":3.2074092},{"type":"node","id":8042845795,"lat":51.1754729,"lon":3.2051839},{"type":"node","id":8042845796,"lat":51.1754907,"lon":3.2052089},{"type":"node","id":8042845797,"lat":51.1755084,"lon":3.2052355},{"type":"node","id":8042845798,"lat":51.1755235,"lon":3.2053482},{"type":"node","id":8042845799,"lat":51.1755387,"lon":3.2053805},{"type":"node","id":8042845800,"lat":51.1755584,"lon":3.2057251},{"type":"node","id":8042845801,"lat":51.1755536,"lon":3.205762},{"type":"node","id":8042845802,"lat":51.1755492,"lon":3.2061312},{"type":"node","id":8042845803,"lat":51.1755305,"lon":3.2062755},{"type":"node","id":8042845804,"lat":51.1754335,"lon":3.2066603},{"type":"node","id":8042845805,"lat":51.1755929,"lon":3.2047843},{"type":"node","id":8042845808,"lat":51.1746278,"lon":3.2090183},{"type":"node","id":8042845809,"lat":51.1740796,"lon":3.2076268},{"type":"node","id":8042845844,"lat":51.1768218,"lon":3.20861},{"type":"node","id":8042845845,"lat":51.1767935,"lon":3.2085031},{"type":"node","id":8042845846,"lat":51.1769413,"lon":3.2089936},{"type":"node","id":8042845847,"lat":51.1757541,"lon":3.2096988},{"type":"node","id":8042845848,"lat":51.1757421,"lon":3.2096812},{"type":"node","id":8042845849,"lat":51.1757312,"lon":3.2096924},{"type":"node","id":8042845850,"lat":51.1757202,"lon":3.2096478},{"type":"node","id":8042845851,"lat":51.1756902,"lon":3.2096207},{"type":"node","id":8042845852,"lat":51.1756712,"lon":3.2096143},{"type":"node","id":8042845853,"lat":51.1756602,"lon":3.2095745},{"type":"node","id":8042845854,"lat":51.1756552,"lon":3.2095537},{"type":"node","id":8042845855,"lat":51.1756657,"lon":3.2095174},{"type":"node","id":8042845856,"lat":51.175658,"lon":3.20908},{"type":"node","id":8042845857,"lat":51.1756525,"lon":3.2093366},{"type":"node","id":8042845858,"lat":51.1756466,"lon":3.2088282},{"type":"node","id":8042845859,"lat":51.1756582,"lon":3.2089151},{"type":"node","id":8042845860,"lat":51.1765521,"lon":3.20839},{"type":"node","id":1069177845,"lat":51.1809357,"lon":3.2035366},{"type":"node","id":1069177849,"lat":51.1803975,"lon":3.2017749},{"type":"node","id":1069178166,"lat":51.1804195,"lon":3.2033098},{"type":"node","id":1519342742,"lat":51.1805239,"lon":3.2032684},{"type":"node","id":1519342743,"lat":51.18064,"lon":3.2036951},{"type":"node","id":1759437085,"lat":51.1806986,"lon":3.2036647},{"type":"node","id":6852012577,"lat":51.1804541,"lon":3.2017867},{"type":"node","id":6852012578,"lat":51.1804124,"lon":3.2018177},{"type":"node","id":6852012579,"lat":51.1804106,"lon":3.2018165},{"type":"node","id":6852012580,"lat":51.1804143,"lon":3.2018177},{"type":"node","id":6852012581,"lat":51.1808363,"lon":3.2030295},{"type":"node","id":6852012582,"lat":51.1807955,"lon":3.2030595},{"type":"node","id":6852012583,"lat":51.180798,"lon":3.2030712},{"type":"node","id":1519476620,"lat":51.1786696,"lon":3.2199463},{"type":"node","id":1519476635,"lat":51.179306,"lon":3.2193119},{"type":"node","id":1519476698,"lat":51.1795485,"lon":3.2192221},{"type":"node","id":1519476744,"lat":51.1791125,"lon":3.2194529},{"type":"node","id":1519476746,"lat":51.178483,"lon":3.2203218},{"type":"node","id":1519476797,"lat":51.1788731,"lon":3.2196593},{"type":"node","id":3780611492,"lat":51.1761568,"lon":3.2238485},{"type":"node","id":3780611493,"lat":51.1762213,"lon":3.223901},{"type":"node","id":3780611494,"lat":51.1762626,"lon":3.2237172},{"type":"node","id":3780611495,"lat":51.1763208,"lon":3.2237628},{"type":"node","id":3780611496,"lat":51.1763248,"lon":3.2236414},{"type":"node","id":3780611497,"lat":51.1763881,"lon":3.2236926},{"type":"node","id":3780611498,"lat":51.1764876,"lon":3.2235544},{"type":"node","id":3780611499,"lat":51.1766551,"lon":3.2232337},{"type":"node","id":3780611500,"lat":51.176687,"lon":3.2231945},{"type":"node","id":3780611501,"lat":51.1767105,"lon":3.2232776},{"type":"node","id":3780611502,"lat":51.176751,"lon":3.2232465},{"type":"node","id":3780611503,"lat":51.1767812,"lon":3.2230729},{"type":"node","id":3780611504,"lat":51.1768505,"lon":3.2231083},{"type":"node","id":6533893620,"lat":51.178521,"lon":3.2203687},{"type":"node","id":6533893621,"lat":51.1786845,"lon":3.220025},{"type":"node","id":6533893622,"lat":51.1789011,"lon":3.2197183},{"type":"node","id":6533893624,"lat":51.1791343,"lon":3.2195235},{"type":"node","id":6533893625,"lat":51.1793269,"lon":3.2193854},{"type":"node","id":6533893626,"lat":51.1795596,"lon":3.219299},{"type":"node","id":5536620518,"lat":51.1683264,"lon":3.224863},{"type":"node","id":5536620519,"lat":51.1684352,"lon":3.2251117},{"type":"node","id":5536620520,"lat":51.1685675,"lon":3.2254022},{"type":"node","id":5536620821,"lat":51.1687379,"lon":3.2258223},{"type":"node","id":5536620822,"lat":51.1693682,"lon":3.2250177},{"type":"node","id":5536620823,"lat":51.1693734,"lon":3.225049},{"type":"node","id":5536620825,"lat":51.1707605,"lon":3.2244639},{"type":"node","id":5536620837,"lat":51.1697793,"lon":3.2260181},{"type":"node","id":5536620838,"lat":51.1699712,"lon":3.2262338},{"type":"node","id":5536620839,"lat":51.1701247,"lon":3.2263242},{"type":"node","id":5536620840,"lat":51.1704719,"lon":3.2266478},{"type":"node","id":5536620841,"lat":51.1701028,"lon":3.2281081},{"type":"node","id":5536620842,"lat":51.1698158,"lon":3.2276446},{"type":"node","id":5536620843,"lat":51.1696441,"lon":3.2273837},{"type":"node","id":5536620844,"lat":51.1695154,"lon":3.2272009},{"type":"node","id":5536620845,"lat":51.169536,"lon":3.2271664},{"type":"node","id":5536620846,"lat":51.1694515,"lon":3.2270181},{"type":"node","id":5635001306,"lat":51.1737078,"lon":3.2354437},{"type":"node","id":5635001371,"lat":51.1722128,"lon":3.2340273},{"type":"node","id":5635001372,"lat":51.1723921,"lon":3.2343394},{"type":"node","id":5635001373,"lat":51.1724213,"lon":3.2342967},{"type":"node","id":5635001374,"lat":51.1722421,"lon":3.2339846},{"type":"node","id":5635001375,"lat":51.1728995,"lon":3.2339319},{"type":"node","id":5635001376,"lat":51.1729253,"lon":3.2339922},{"type":"node","id":5635001377,"lat":51.1723583,"lon":3.2340816},{"type":"node","id":5635001378,"lat":51.1723268,"lon":3.2340173},{"type":"node","id":5635001379,"lat":51.172885,"lon":3.2337993},{"type":"node","id":5635001380,"lat":51.1728611,"lon":3.2338706},{"type":"node","id":5635001381,"lat":51.1723325,"lon":3.2339419},{"type":"node","id":5635001382,"lat":51.1723464,"lon":3.2338696},{"type":"node","id":5882873334,"lat":51.1736186,"lon":3.2330966},{"type":"node","id":5882873335,"lat":51.1735451,"lon":3.2327633},{"type":"node","id":5882873336,"lat":51.1737001,"lon":3.2327438},{"type":"node","id":5882873337,"lat":51.1736796,"lon":3.2318764},{"type":"node","id":5882873338,"lat":51.1735265,"lon":3.2318782},{"type":"node","id":6593340582,"lat":51.1727872,"lon":3.2328745},{"type":"node","id":6593340583,"lat":51.1728013,"lon":3.2332051},{"type":"node","id":6593340584,"lat":51.1736743,"lon":3.2331435},{"type":"node","id":7767137235,"lat":51.1735198,"lon":3.2355568},{"type":"node","id":7767137236,"lat":51.1735366,"lon":3.2355246},{"type":"node","id":7767137237,"lat":51.1735198,"lon":3.2356399},{"type":"node","id":5635001274,"lat":51.1751425,"lon":3.2346144},{"type":"node","id":5635001275,"lat":51.1751696,"lon":3.2347601},{"type":"node","id":5635001276,"lat":51.1750553,"lon":3.2348141},{"type":"node","id":5635001277,"lat":51.1750282,"lon":3.2346684},{"type":"node","id":5635001312,"lat":51.174002,"lon":3.2349367},{"type":"node","id":5635001383,"lat":51.1740709,"lon":3.233056},{"type":"node","id":5635001384,"lat":51.1740249,"lon":3.2330598},{"type":"node","id":5635001385,"lat":51.1740265,"lon":3.2331313},{"type":"node","id":5635001386,"lat":51.1740597,"lon":3.2327202},{"type":"node","id":5635001414,"lat":51.174281,"lon":3.2336147},{"type":"node","id":5635001415,"lat":51.174081,"lon":3.2338914},{"type":"node","id":5635001416,"lat":51.1740489,"lon":3.2338323},{"type":"node","id":5635001417,"lat":51.1742489,"lon":3.2335556},{"type":"node","id":5761770202,"lat":51.1783111,"lon":3.2342484},{"type":"node","id":5761770204,"lat":51.1782819,"lon":3.2339616},{"type":"node","id":7767137234,"lat":51.1739713,"lon":3.2348766},{"type":"node","id":9052878228,"lat":51.1781206,"lon":3.234323},{"type":"node","id":9052878229,"lat":51.1781054,"lon":3.2339448},{"type":"way","id":810604915,"nodes":[1168727824,9167054153,9274761589,9274761596,7577430793,1038638712,1038638723,1038638661,9199177059,1038638721,7554434436,7578975035,7554434438,7578865273,7578975032,7578975030,7578975029,1038638696,7578975009,7578975008,7578975007,1038638743,7578975002,7578974988,7578974989,7578974990,7578974991,7578974992,7578865275,7578865274,1038638753,7578974995,7578974996,7578974997,7578904489,7578974999,7578975000,7578975001,7578974998,3921878998,1038638592,929120698,1675648152,7578865281,7578865283,7578975012,7578975015,7578975016,3922380061,2732486274,3922380083,7578975019,7578975018,7578975021,7578960079,3922375256,7578975024,3922380071]},{"type":"way","id":989393316,"nodes":[3922380071,3922380081,3922380086,3922380092,3922380095,9167054157,7578975026,9274761593,9274761592,9274761591,7578975027,9167054156,9167054154,7578975049,7578975028,1168727824]},{"type":"way","id":389026405,"nodes":[3921879019,7578975044,3921879018,7578975046,7578975045,7578975040,3921879004,3921879011,3921879019]},{"type":"way","id":810607458,"nodes":[7578987409,7578987410,7578987411,5745833241,5745833240,5745833239,7578987412,7578987415,7578987413,7578987414,7578987417,7578987416,7578987418,7578987419,7578987409]},{"type":"way","id":777280458,"nodes":[8042845812,8042845806,8042845807,7252863798,7252820961,8042845805,7252820962,7252820963,7252820964,7252820965,7252820966,8042845795,8042845796,8042845797,7252820967,8042845798,8042845799,7252820968,8042845800,8042845801,7252820969,8042845802,8042845803,7252820970,8042845804,7252820971,7252820972,7252820973,7252820974,7252820975,7252820976,7252820977,7252820978,7252820979,8042845794,8042845793,7252820980,7252820981,7252820982,8042845792,7252820983,7252820984,7252874885,7252874886,7252874887,7252874888,7252874889,5728443540,7252874890,5728443539,8042845791,8042845790,8042845789,7252874891,8042845808,8042845809,8042845810,8042845811,4036885076,8042845812]},{"type":"way","id":577572397,"nodes":[5536620518,5536620519,5536620520,5536620821,5536620822,5536620823,5536620824,5536620825,5536620826,6067483782,5536620827,5536620828,5536620829,5536620830,5536620831,5536620832,7794736251,5536620505,5536620506,5536620507,5952389321,5952389322,5952389323,5536609426,5952389320,5172938444,5536620510,5536620511,5536620512,5536620513,6067483781,5536620514,5536620516,5536620518]},{"type":"way","id":863373849,"nodes":[4036899624,8042845845,8042845844,8042845846,8042845847,8042845848,8042845849,8042845850,8042845851,8042845852,8042845853,8042845854,8042845855,8042845857,8042845856,8042845859,8042845858,8042845860,4036899624]},{"type":"way","id":577572399,"nodes":[5536620837,5536620838,5536620839,5536620840,5536620841,5536620842,5536620843,5536620844,5536620845,5536620846,5536620837]}]}; + Utils.injectJsonDownloadForTests( - "https://overpass-api.de/api/interpreter?data=%5Bout%3Ajson%5D%5Btimeout%3A60%5D%5Bbbox%3A51.124212757826875%2C3.1640625%2C51.17934297928927%2C3.251953125%5D%3B"+query , - {"version":0.6,"generator":"Overpass API 0.7.57 93a4d346","osm3s":{"timestamp_osm_base":"2022-02-13T23:54:06Z","copyright":"The data included in this document is from www.openstreetmap.org. The data is made available under ODbL."},"elements":[{"type":"node","id":518224450,"lat":51.1548065,"lon":3.1880118,"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"street_side"}},{"type":"node","id":665418924,"lat":51.1575547,"lon":3.20522,"tags":{"amenity":"parking"}},{"type":"node","id":1168727903,"lat":51.1299141,"lon":3.1776123,"tags":{"amenity":"drinking_water","mapillary":"https://www.mapillary.com/app/?lat=51.129853685131906&lng=3.177603984688602&z=17&pKey=SEyKzIMUeKssni1ZLVe-9A&focus=photo&dateTo=2017-04-02&dateFrom=2017-04-01&x=0.5168826751181941&y=0.6114877557873634&zoom=0"}},{"type":"node","id":1168728245,"lat":51.1290938,"lon":3.1767502,"tags":{"amenity":"drinking_water","mapillary":"https://www.mapillary.com/app/?lat=51.129104406662464&lng=3.176675795895676&z=17&pKey=vSP3D_hWv3XCBtH75GnYUQ&focus=photo&dateTo=2017-04-02&dateFrom=2017-04-01"}},{"type":"node","id":1725842653,"lat":51.153364,"lon":3.2352655,"tags":{"amenity":"bench"}},{"type":"node","id":1744641290,"lat":51.1389321,"lon":3.2385407,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":1746891135,"lat":51.1598841,"lon":3.2361425,"tags":{"amenity":"bench"}},{"type":"node","id":1810326078,"lat":51.1550855,"lon":3.2349358,"tags":{"amenity":"bench"}},{"type":"node","id":1810326092,"lat":51.1552302,"lon":3.234968,"tags":{"amenity":"bench"}},{"type":"node","id":2325437742,"lat":51.1770052,"lon":3.1967794,"tags":{"board_type":"board","information":"board","name":"Tillegembos","tourism":"information"}},{"type":"node","id":2325437743,"lat":51.1787363,"lon":3.1949036,"tags":{"board_type":"board","information":"board","name":"Tillegembos","tourism":"information"}},{"type":"node","id":2325437813,"lat":51.1733102,"lon":3.1895672,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437839,"lat":51.1763436,"lon":3.1984985,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437848,"lat":51.1770966,"lon":3.1963507,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437862,"lat":51.1773439,"lon":3.1948779,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437867,"lat":51.1775994,"lon":3.1888088,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437873,"lat":51.1778384,"lon":3.1913802,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2732486257,"lat":51.129741,"lon":3.1907419,"tags":{"board_type":"nature","information":"board","name":"Doeveren","tourism":"information"}},{"type":"node","id":3774054068,"lat":51.1586662,"lon":3.2271102,"tags":{"amenity":"bench"}},{"type":"node","id":4769106605,"lat":51.138264,"lon":3.1798655,"tags":{"backrest":"yes","leisure":"picnic_table"}},{"type":"node","id":4912238707,"lat":51.1448634,"lon":3.2455986,"tags":{"access":"yes","amenity":"parking","fee":"no","name":"Oostkamp","parking":"Carpool"}},{"type":"node","id":5637212235,"lat":51.1305439,"lon":3.1866873,"tags":{"board_type":"nature","image":"https://i.imgur.com/HehOQL9.jpg","information":"board","name":"Welkom Doeveren","tourism":"information"}},{"type":"node","id":5637224573,"lat":51.1281084,"lon":3.1881726,"tags":{"board_type":"nature","information":"board","name":"Welkom Doeveren","tourism":"information"}},{"type":"node","id":5637230107,"lat":51.1280884,"lon":3.1889798,"tags":{"information":"board","tourism":"information"}},{"type":"node","id":5637743026,"lat":51.1295973,"lon":3.1751122,"tags":{"information":"board","name":"Doeveren Wandelroute","tourism":"information"}},{"type":"node","id":5716130103,"lat":51.1767183,"lon":3.1947867,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":5745783208,"lat":51.1782581,"lon":3.2410111,"tags":{"amenity":"bench"}},{"type":"node","id":5745807545,"lat":51.1784037,"lon":3.2369439,"tags":{"amenity":"bench"}},{"type":"node","id":5745807551,"lat":51.1783278,"lon":3.236678,"tags":{"amenity":"bench"}},{"type":"node","id":6535241426,"lat":51.1693142,"lon":3.1673093,"tags":{"amenity":"bench"}},{"type":"node","id":6535241427,"lat":51.169265,"lon":3.1673159,"tags":{"amenity":"bench"}},{"type":"node","id":6535241428,"lat":51.1692199,"lon":3.1673224,"tags":{"amenity":"bench"}},{"type":"node","id":6535241430,"lat":51.1685726,"lon":3.1678225,"tags":{"bench":"yes","leisure":"picnic_table","material":"wood"}},{"type":"node","id":6536026827,"lat":51.1703142,"lon":3.1691109,"tags":{"leisure":"picnic_table"}},{"type":"node","id":6536026828,"lat":51.1702795,"lon":3.1691552,"tags":{"leisure":"picnic_table"}},{"type":"node","id":6712112244,"lat":51.1595064,"lon":3.2021482,"tags":{"leisure":"picnic_table"}},{"type":"node","id":7304050040,"lat":51.1560908,"lon":3.1748919,"tags":{"amenity":"bench"}},{"type":"node","id":7304050041,"lat":51.1560141,"lon":3.1749533,"tags":{"amenity":"bench"}},{"type":"node","id":7304050042,"lat":51.156032,"lon":3.1749379,"tags":{"amenity":"bench"}},{"type":"node","id":7439979218,"lat":51.1780402,"lon":3.2178666,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":7439979219,"lat":51.1780508,"lon":3.2179033,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":7529262982,"lat":51.1585566,"lon":3.1715528,"tags":{"board_type":"map","information":"board","tourism":"information"}},{"type":"node","id":7529262984,"lat":51.1585786,"lon":3.1715385,"tags":{"leisure":"picnic_table"}},{"type":"node","id":7554879668,"lat":51.1573713,"lon":3.2043731,"tags":{"access":"yes","amenity":"toilets","fee":"no","toilets:disposal":"flush","unisex":"yes","wheelchair":"yes"}},{"type":"node","id":7554879669,"lat":51.1594855,"lon":3.2021507,"tags":{"leisure":"picnic_table"}},{"type":"node","id":7556988723,"lat":51.1330234,"lon":3.1839944,"tags":{"amenity":"bench","material":"wood"}},{"type":"node","id":7575825326,"lat":51.1386553,"lon":3.1797358,"tags":{"amenity":"bench"}},{"type":"node","id":7575825327,"lat":51.1382456,"lon":3.1797422,"tags":{"information":"board","tourism":"information"}},{"type":"node","id":8109498958,"lat":51.1332267,"lon":3.2341272,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":8109498959,"lat":51.1335011,"lon":3.2343954,"tags":{"leisure":"picnic_table"}},{"type":"node","id":8198894646,"lat":51.125688,"lon":3.1856217,"tags":{"image":"https://i.imgur.com/O5kX20u.jpg","information":"board","tourism":"information"}},{"type":"node","id":8199012519,"lat":51.1262245,"lon":3.1802429,"tags":{"image":"https://i.imgur.com/tomw9p5.jpg","information":"board","tourism":"information"}},{"type":"node","id":8199244816,"lat":51.1252874,"lon":3.1837622,"tags":{"amenity":"bench"}},{"type":"node","id":8199301617,"lat":51.1256827,"lon":3.1853543,"tags":{"amenity":"bench","backrest":"no"}},{"type":"node","id":8255488518,"lat":51.1406698,"lon":3.235178,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":9316104741,"lat":51.1330984,"lon":3.2335257,"tags":{"information":"board","tourism":"information"}},{"type":"node","id":9442532340,"lat":51.1763651,"lon":3.1947952,"tags":{"amenity":"bench","backrest":"yes","image":"https://i.imgur.com/eZ0Loii.jpg"}},{"type":"way","id":15242261,"nodes":[150996092,150996093,6754312552,6754312553,6754312550,6754312551,150996094,150996095,150996097,150996098,6754312560,6754312559,6754312558,150996099,6754312557,150996100,6754312555,6754312556,150996101,6754312554,150996092],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":16514228,"nodes":[170464837,170464839,170464840,170464841,170464837],"tags":{"access":"yes","amenity":"parking","fee":"no","maxstay":"4 hours","parking":"surface"}},{"type":"way","id":76706071,"nodes":[903903386,1038557094,1038557233,1038557143,1038557075,903903387,1038557195,903903388,903903390,903904576,903903386],"tags":{"access":"permissive","amenity":"parking"}},{"type":"way","id":89601157,"nodes":[1038557083,1038557078,1038557104,1038557072,1038557108,1038557230,1038557227,1038557102,1038557137,1038575040,1038557191,1038557014,6960473080,1038557035,1038557012,1038557083],"tags":{"amenity":"parking"}},{"type":"way","id":89604999,"nodes":[1038583404,1038583491,1038583375,1038583483,1038583479,1038583398,1038583459,1038583456,1038583446,1038583441,1038583425,1038583501,1038583451,1038583463,1038583476,1038583404],"tags":{"access":"yes","amenity":"parking","capacity":"57","carpool":"yes","description":"carpoolparking","fee":"no","name":"Loppem","parking":"surface"}},{"type":"way","id":92035679,"nodes":[1069177920,6853179264,1069177925,1069177919,6853179269,6853179268,6853179267,6853179215,6853179213,6853179214,1069178133,1069177984,6853179230,6853179228,6853179229,6853179224,6853179225,6853179227,6853179226,6853179216,6853179220,6853179219,6853179218,6853179217,6853179223,6853179221,6853179222,1069177967,1069177852,6853179211,6853179212,6853179210,6853179327,6853179208,6853179209,6853179203,1069177976,6853179207,6853179206,6853179205,6853179204,6853179202,1069177849,6852012579,6852012578,6852012580,6852012577,6852012581,6852012582,6852012583,1069177845,1759437085,1519342743,1519342742,1069178166,1069177853,1069177915,6853179235,6853179234,6853179236,1069177933,6853179237,6853179238,1069178021,6853179246,6853179244,6853179245,6853179240,6853179243,6853179241,6853179242,6853179239,6853179248,6853179249,6853179250,6853179247,1069177873,6853179262,6853179263,6853179260,6853179261,6853179256,6853179259,6853179257,6853179258,1069177920],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":101248451,"nodes":[1168728158,1168728325,1168728159,5637669355,1168728109,1168728158],"tags":{"access":"private","amenity":"parking","name":"Parking Merkenveld"}},{"type":"way","id":101248462,"nodes":[1168727876,1168728288,1168728412,1168728208,1168727876],"tags":{"amenity":"toilets","building":"yes","source:geometry:date":"2019-03-14","source:geometry:ref":"Gbg/6588148"}},{"type":"way","id":131622387,"nodes":[1448421093,1448421099,1448421091,1448421081,1448421093],"tags":{"amenity":"parking","name":"Tudor - Zeeweg","parking":"surface"}},{"type":"way","id":145691934,"nodes":[1590642859,1590642860,1590642858,1590642849,1590642859],"tags":{"amenity":"parking"}},{"type":"way","id":145691937,"nodes":[1590642829,1590642828,1590642830,1590642832,1590642829],"tags":{"amenity":"parking"}},{"type":"way","id":158901716,"nodes":[1710245713,1710245718,1710245707,1710245705,1710245703,1710245715,1710245711,1710245709,1710245701,1710245713],"tags":{"access":"yes","amenity":"parking","capacity":"14","fee":"no","parking":"surface"}},{"type":"way","id":158904558,"nodes":[1710262742,1710262745,1710262735,1710262733,1710262732,1710262743,1710262741,1710262739,1710262744,1710262737,1710262736,1710262731,1710262738,1710262742],"tags":{"access":"yes","alt_name":"Schoolparking","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":158906028,"nodes":[1710276259,1710276251,1810330766,1710276255,1710276261,1710276240,1710276232,1710276257,1710276243,1710276253,1810347217,1710276242,1710276259],"tags":{"access":"yes","amenity":"parking","fee":"no","name":"Parking Sportcentrum De Valkaart","parking":"surface"}},{"type":"way","id":160825858,"nodes":[1728421375,1728421374,1728421379,1728421377,1728421376,1728421378,1728421375],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":162602213,"nodes":[1920143232,7393009684,7393048385,1744641293,1523513488,1744641292,1920143232],"tags":{"amenity":"parking","capacity":"15"}},{"type":"way","id":165489167,"nodes":[4912197370,4912197365,4912197373,4912197364,4912197372,1770289505,4912197362,4912197371,4912197374,4912197363,4912197368,4912197366,4912197369,4912197367,4912197370],"tags":{"access":"yes","amenity":"parking","fee":"no","name":"Bad Neuheimplein","parking":"surface"}},{"type":"way","id":168291852,"nodes":[1795793399,4979389763,1795793409,1795793395,1795793393,1795793397,1795793407,1795793406,1795793408,1795793405,1795793399],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":169875513,"nodes":[1810345951,1810345955,1810345947,1810345944,1810345951],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":170015605,"nodes":[1811673425,1811673421,1811673418,1811673423,1811673425],"tags":{"access":"private","amenity":"parking","name":"gheeraert E40","operator":"Gheeraert"}},{"type":"way","id":170018487,"nodes":[1811699779,1811699778,1811699776,1811699777,1811699779],"tags":{"access":"private","amenity":"parking","name":"Gheeraert vooraan"}},{"type":"way","id":170559194,"nodes":[1817319304,1817319302,1817319297,1817319301,1817319304],"tags":{"access":"private","amenity":"parking","name":"Gheeraert laadkade"}},{"type":"way","id":170559195,"nodes":[1817319299,1817319303,1817319300,1817319292,1817319299],"tags":{"access":"private","amenity":"parking","name":"Gheeraert spoorweg trailers"}},{"type":"way","id":170559196,"nodes":[1817319293,1817319289,1817319291,1817319296,1817319293],"tags":{"access":"private","amenity":"parking","name":"Gheeraert spoorweg trucks"}},{"type":"way","id":170559197,"nodes":[1817319294,1817319298,1817319295,1817319290,1817319294],"tags":{"access":"private","amenity":"parking","name":"Gheeraert zijkant"}},{"type":"way","id":170559292,"nodes":[1817320496,1817320494,1817320493,1817320495,1817320496],"tags":{"access":"private","amenity":"parking","name":"Gheeraert vooraan gebouw"}},{"type":"way","id":170559832,"nodes":[1817324515,1817324509,1817324491,6397031888,4044172008,4044172003,4044171997,4044171962,4044171957,4044171976,1817324489,1817324488,3550860268,1817324505,3550860269,1817324513,1817324515],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":223674368,"nodes":[2325437844,8191691971,8191691973,8191691972,2325437840,8191691970,414025563,2325437844],"tags":{"amenity":"parking","name":"Tillegembos","parking":"surface"}},{"type":"way","id":237214948,"nodes":[2451574741,2451574742,2451574744,1015583939,2451574741],"tags":{"access":"private","amenity":"parking"}},{"type":"way","id":237214949,"nodes":[2451574748,2451574746,2451574747,2451574749,2451574748],"tags":{"access":"private","amenity":"parking"}},{"type":"way","id":237214950,"nodes":[2451569392,1015567837,2451574745,2451574743,2451578121,2451569392],"tags":{"access":"private","amenity":"parking"}},{"type":"way","id":325909586,"nodes":[3325315243,111759500,3325315247,3325315232,3325315230,3325315226,1169056712,3325315243],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":326834162,"nodes":[3335137807,3335137692,3335137795,9163493632,3335137802,3335137812,9163486855,9163486856,3335137823,3335137807],"tags":{"access":"customers","amenity":"parking","operator":"Best Western Weinebrugge","parking":"surface"}},{"type":"way","id":327849054,"nodes":[3346575929,3346575873,3346575876,3346575843,3346575845,3346575891,3346575901,3346575923,3346575928,3346575950,3346575929],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":327849055,"nodes":[3346575945,3346575946,3346575943,3346575933,3346575925,3346575917,3346575903,3346575908,3346575889,3346575886,3346575945],"tags":{"access":"customers","amenity":"parking","parking":"surface"}},{"type":"way","id":327849056,"nodes":[3346575865,3346575853,3346575855,3346575846,3346575840,3346575858,3346575865],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":374677860,"nodes":[3780611504,3780611502,3780611500,3780611503,3780611504],"tags":{"amenity":"parking"}},{"type":"way","id":374677861,"nodes":[3780611495,3780611493,3780611492,3780611494,3780611495],"tags":{"amenity":"parking"}},{"type":"way","id":374677862,"nodes":[3780611498,3780611497,3780611496,3780611499,3780611501,3780611498],"tags":{"amenity":"parking"}},{"type":"way","id":389912371,"nodes":[3930713440,3930713451,3930713447,3930713437,3930713440],"tags":{"amenity":"parking"}},{"type":"way","id":389912372,"nodes":[3930713454,3930713442,3930713435,3930713429,5826811614,3930713426,3930713430,6982605752,6982605754,3930713438,6982605769,6982605766,6982605767,6982605762,6982605764,3930713446,3930713454],"tags":{"access":"customers","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":401995684,"nodes":[4044171963,4044171954,4044171924,4044171936,4044171941,4044171963],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":500067820,"nodes":[4912203166,4912203165,4912203164,4912203163,4912203162,4912203161,4912203160,4912203166],"tags":{"access":"yes","amenity":"parking","parking":"surface"}},{"type":"way","id":500067821,"nodes":[4912203170,4912203169,4912203168,4912203167,4912203170],"tags":{"access":"yes","amenity":"parking","parking":"surface"}},{"type":"way","id":500067822,"nodes":[4912203174,4912203173,4912203172,4912203171,4912203174],"tags":{"access":"yes","amenity":"parking","parking":"surface"}},{"type":"way","id":500067823,"nodes":[4912203179,4912203178,4912203177,4912203176,4912203179],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":500069613,"nodes":[4912214695,4912214685,4912214694,4912214693,4912214692,4912214680,4912214695],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":500071452,"nodes":[4912225068,4912225062,4912225063,4912225053,4912225064,4912214694,4912214685,4912225068],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":500071455,"nodes":[4912225070,4912214681,4912214686,4912225052,4912225051,4912225067,4912225062,4912225068,4912225070],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":500071458,"nodes":[4912214695,4912214680,4912225069,4912225050,1525460846,4912214681,4912225070,4912214695],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":533276307,"nodes":[5173881316,5173881317,5173881318,7054196467,5173881316],"tags":{"amenity":"parking"}},{"type":"way","id":533276308,"nodes":[5173881320,5173881621,5173881622,5173881623,5173881320],"tags":{"amenity":"parking"}},{"type":"way","id":533276309,"nodes":[5173881624,5173881625,5173881626,5173881627,5173881624],"tags":{"amenity":"parking"}},{"type":"way","id":579848581,"nodes":[4043782112,5825400688,5552466020,6997096756,6997096759,6997096758,5552466018,5552466013,5552466014,6997076567,4043782112],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":584455569,"nodes":[5586765933,5586765934,5586765935,5586765936,5586765933],"tags":{"amenity":"parking"}},{"type":"way","id":585977870,"nodes":[5587844460,5599314384,5599314385,1659850846,6870850178,5587844462,5587844461,6870863414,5587844460],"tags":{"amenity":"parking"}},{"type":"way","id":587014342,"nodes":[5607796820,5607798725,5607798721,5607798722,5607796819,5607798723,5607796820],"tags":{"access":"permissive","amenity":"parking","park_ride":"no","parking":"surface","surface":"paved"}},{"type":"way","id":590167103,"nodes":[5635001277,5635001274,5635001275,5635001276,5635001277],"tags":{"amenity":"parking"}},{"type":"way","id":590167113,"nodes":[5635001312,5635001306,7767137237,7767137235,7767137236,7767137234,5635001312],"tags":{"amenity":"parking"}},{"type":"way","id":590167134,"nodes":[5635001374,5635001373,5635001372,5635001371,5635001374],"tags":{"amenity":"parking"}},{"type":"way","id":590167135,"nodes":[5635001378,5635001377,5635001376,5635001375,5635001378],"tags":{"amenity":"parking"}},{"type":"way","id":590167136,"nodes":[5635001382,5635001381,5635001380,5635001379,5635001382],"tags":{"amenity":"parking"}},{"type":"way","id":590167137,"nodes":[5635001386,5882873336,5882873337,5882873338,5882873335,6593340582,6593340583,5882873334,6593340584,5635001385,5635001384,5635001383,5635001386],"tags":{"amenity":"parking"}},{"type":"way","id":590167147,"nodes":[5635001417,5635001414,5635001415,5635001416,5635001417],"tags":{"amenity":"parking"}},{"type":"way","id":601406079,"nodes":[5716136617,5716136618,5716136619,5716136620,5716136617],"tags":{"amenity":"parking"}},{"type":"way","id":632813009,"nodes":[5974489618,1810326044,1810326087,5974489617,5972179348,5972179347,5972179346,5972179345,5972179344,5972179343,5972179331,5974489616,5974489615,5974489614,5974489618],"tags":{"amenity":"parking","name":"Gemeenteplein","parking":"surface"}},{"type":"way","id":668043297,"nodes":[6255587424,6255587425,6255587426,6255587427,6255587424],"tags":{"access":"private","amenity":"parking"}},{"type":"way","id":670104236,"nodes":[6275462768,6275462769,6275462770,6275462771,6275462768],"tags":{"amenity":"parking"}},{"type":"way","id":670104238,"nodes":[6275462772,6275462989,6275462773,6275462774,6275462775,6275462772],"tags":{"amenity":"parking"}},{"type":"way","id":670104239,"nodes":[6275462776,6275462777,6275462778,6275462779,6275462776],"tags":{"amenity":"parking"}},{"type":"way","id":670104241,"nodes":[6275462780,6275462781,6275462782,6275462783,6275462780],"tags":{"amenity":"parking"}},{"type":"way","id":670104242,"nodes":[6275462784,6275462985,6275462988,6275462986,6275462987,6275462784],"tags":{"amenity":"parking"}},{"type":"way","id":671840055,"nodes":[6291339827,6291339828,6291339816,6291339815,6291339822,6291339821,6291339829,6291339830,6291339827],"tags":{"amenity":"parking"}},{"type":"way","id":695825223,"nodes":[1519476746,6533893620,6533893621,6533893622,1519476797,1519476620,1519476746],"tags":{"access":"yes","amenity":"parking"}},{"type":"way","id":695825224,"nodes":[1519476744,6533893624,6533893625,6533893626,1519476698,1519476635,1519476744],"tags":{"access":"yes","amenity":"parking"}},{"type":"way","id":696040917,"nodes":[6536026850,6536026851,6536026852,6536026853,6536026850],"tags":{"amenity":"parking","name":"Kasteel Tudor"}},{"type":"way","id":696043218,"nodes":[6536038234,6536038235,6536038236,6536038237,6536038234],"tags":{"access":"customers","amenity":"parking"}},{"type":"way","id":700675991,"nodes":[6579962064,6579962065,6579962066,6579962068,6579962067,6579962064],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":705278707,"nodes":[6625037999,6625038000,6625038001,6625038002,6625038003,6004375826,6625038005,6625038006,6625037999],"tags":{"amenity":"parking"}},{"type":"way","id":719482833,"nodes":[6754312544,6754312543,6754312542,6754312541,6754312544],"tags":{"access":"yes","amenity":"parking","capacity":"5"}},{"type":"way","id":719482834,"nodes":[6754312565,6754312564,6754312563,6754312562,6754312565],"tags":{"access":"yes","amenity":"parking","capacity":"12"}},{"type":"way","id":737054013,"nodes":[5826811496,5826811497,5826811494,5826811495,5826811496],"tags":{"amenity":"parking"}},{"type":"way","id":737054014,"nodes":[5826810676,5826810673,5826810674,5826810675,5826810676],"tags":{"amenity":"parking"}},{"type":"way","id":737054015,"nodes":[5826810681,5826810678,5826810679,5826810680,5826810681],"tags":{"amenity":"parking"}},{"type":"way","id":737093410,"nodes":[5826811559,5826811536,5826811535,5826811561,5826811560,5826811559],"tags":{"access":"yes","amenity":"parking","capacity":"4","fee":"no","parking":"surface"}},{"type":"way","id":737093411,"nodes":[5826811551,5826811547,5826811548,5826811549,5826811550,5826811551],"tags":{"access":"yes","amenity":"parking","capacity":"4","fee":"no","parking":"surface"}},{"type":"way","id":739652949,"nodes":[6925536542,6925536541,6925536540,6925536539,6925536542],"tags":{"amenity":"parking","capacity":"6","parking":"surface"}},{"type":"way","id":741675236,"nodes":[6943148207,6943148206,6943148205,6943148204,1637742821,6943148203,6943148202,6943148201,6943148200,6943148199,6943148198,6943148197,6943148207],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":742295526,"nodes":[6949357909,6949357908,6949357907,6949357906,6949357909],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":742295527,"nodes":[6949357913,6949357912,6949357911,6949357910,6949357913],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":742295528,"nodes":[6949357917,6949357916,6949357915,6949357914,6949357917],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":742295529,"nodes":[6949357921,6949357920,6949357919,6949357918,6949357921],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":746170866,"nodes":[6982906547,6982906546,6982906545,6982906544,6982906543,6982906542,6982906547],"tags":{"access":"customers","amenity":"parking"}},{"type":"way","id":747880657,"nodes":[3325315397,6997076566,6997076565,6997076563,6997076562,6997076564,3325315395,3325315397],"tags":{"access":"customers","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":763977465,"nodes":[7137343680,7137343681,7137343682,7137343683,7137343680],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":763977466,"nodes":[7137343684,7137383185,7137383186,7137383187,7137343684],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":803821090,"nodes":[7519058290,7519058289,7519058288,7519058287,7519058290],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":803821091,"nodes":[7519058294,7519058293,7519058292,7519058291,7519058294],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":803821092,"nodes":[7519058298,7519058297,7519058296,7519058295,7519058298],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":803821093,"nodes":[7519058302,7519058301,7519058300,7519058299,7519058302],"tags":{"access":"private","amenity":"parking","capacity":"6","parking":"surface"}},{"type":"way","id":804963962,"nodes":[7529417225,7529417226,7529417227,7529417228,7529417229,7529417230,7529417232,7529417225],"tags":{"access":"customers","amenity":"parking","fee":"no","operator":"’t Kiekekot","parking":"surface","surface":"unpaved"}},{"type":"way","id":806875503,"nodes":[4042671969,7545532512,7545532514,7545532513,3359977305,4042671969],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":806963547,"nodes":[7546193222,7546193221,7546193220,7546193219,7546193222],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":865357121,"nodes":[8065883228,8065883227,8065883226,8065883225,8065883228],"tags":{"amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":865357122,"nodes":[8065883233,8065883230,8065883229,8065883232,8065883233],"tags":{"amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":879281221,"nodes":[8179735269,8179735268,8179735267,8179735266,8179735265,8179735264,8179735224,8179735269],"tags":{"access":"customers","amenity":"parking","parking":"surface"}},{"type":"way","id":881770201,"nodes":[8200275847,8200275848,8200275844,8200275853,8200275849,8200275847],"tags":{"amenity":"parking","parking":"surface","surface":"grass"}},{"type":"way","id":978360549,"nodes":[5761770202,5761770204,9052878229,9052878228,5761770202],"tags":{"amenity":"parking"}},{"type":"way","id":1009692722,"nodes":[9316118540,9316118536,9316118531,9316118535,9316118534,9316118533,9316118530,9316118532,3311835478,9316118540],"tags":{"amenity":"parking","parking":"street_side"}},{"type":"relation","id":8188853,"members":[{"type":"way","ref":577572397,"role":"outer"},{"type":"way","ref":577572399,"role":"outer"}],"tags":{"access":"guided","curator":"Luc Maene;Geert De Clercq","email":"lucmaene@hotmail.com;geert.de.clercq1@pandora.be","landuse":"meadow","leisure":"nature_reserve","name":"De Wulgenbroeken","natural":"wetland","operator":"Natuurpunt Brugge","type":"multipolygon","website":"https://natuurpuntbrugge.be/wulgenbroeken/","wetland":"wet_meadow","wikidata":"Q60061498","wikipedia":"nl:Wulgenbroeken"}},{"type":"relation","id":11163488,"members":[{"type":"way","ref":810604915,"role":"outer"},{"type":"way","ref":989393316,"role":"outer"},{"type":"way","ref":389026405,"role":"inner"},{"type":"way","ref":810607458,"role":"outer"}],"tags":{"access":"yes","curator":"Kris Lesage","description":"Wat Doeveren zo uniek maakt, zijn zijn kleine heidegebiedjes met soorten die erg verschillen van de Kempense heide. Doeveren en omstreken was vroeger één groot heidegebied, maar bestaat nu grotendeels uit bossen.","dog":"leashed","email":"doeveren@natuurpuntzedelgem.be","image":"https://i.imgur.com/NEAsQZG.jpg","image:0":"https://i.imgur.com/Dq71hyQ.jpg","image:1":"https://i.imgur.com/mAIiT4f.jpg","image:2":"https://i.imgur.com/dELZU97.jpg","image:3":"https://i.imgur.com/Bso57JC.jpg","image:4":"https://i.imgur.com/9DtcfXo.jpg","image:5":"https://i.imgur.com/0R6eBfk.jpg","image:6":"https://i.imgur.com/b0JpvbR.jpg","leisure":"nature_reserve","name":"Doeveren","operator":"Natuurpunt Zedelgem","phone":"+32 486 25 25 30","type":"multipolygon","website":"https://www.natuurpuntzedelgem.be/gebieden/doeveren/","wikidata":"Q56395754","wikipedia":"nl:Doeveren (natuurgebied)"}},{"type":"relation","id":11790117,"members":[{"type":"way","ref":863373849,"role":"outer"},{"type":"way","ref":777280458,"role":"outer"}],"tags":{"access":"no","description:0":"In gebruik als waterbuffering","leisure":"nature_reserve","name":"Kerkebeek","operator":"Natuurpunt Brugge","type":"multipolygon"}},{"type":"node","id":518224450,"lat":51.1548065,"lon":3.1880118,"timestamp":"2021-08-14T21:49:28Z","version":5,"changeset":109683837,"user":"effem","uid":16437,"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"street_side"}},{"type":"node","id":665418924,"lat":51.1575547,"lon":3.20522,"timestamp":"2012-05-12T20:13:39Z","version":2,"changeset":11580224,"user":"martino260","uid":655442,"tags":{"amenity":"parking"}},{"type":"node","id":1168727903,"lat":51.1299141,"lon":3.1776123,"timestamp":"2017-04-03T08:34:05Z","version":2,"changeset":47403889,"user":"philippec","uid":76884,"tags":{"amenity":"drinking_water","mapillary":"https://www.mapillary.com/app/?lat=51.129853685131906&lng=3.177603984688602&z=17&pKey=SEyKzIMUeKssni1ZLVe-9A&focus=photo&dateTo=2017-04-02&dateFrom=2017-04-01&x=0.5168826751181941&y=0.6114877557873634&zoom=0"}},{"type":"node","id":1168728245,"lat":51.1290938,"lon":3.1767502,"timestamp":"2019-10-07T11:06:57Z","version":3,"changeset":75370316,"user":"Hopperpop","uid":3664604,"tags":{"amenity":"drinking_water","mapillary":"https://www.mapillary.com/app/?lat=51.129104406662464&lng=3.176675795895676&z=17&pKey=vSP3D_hWv3XCBtH75GnYUQ&focus=photo&dateTo=2017-04-02&dateFrom=2017-04-01"}},{"type":"node","id":1725842653,"lat":51.153364,"lon":3.2352655,"timestamp":"2012-07-02T17:33:00Z","version":2,"changeset":12090625,"user":"martino260","uid":655442,"tags":{"amenity":"bench"}},{"type":"node","id":1744641290,"lat":51.1389321,"lon":3.2385407,"timestamp":"2012-09-18T13:29:52Z","version":3,"changeset":13156159,"user":"martino260","uid":655442,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":1746891135,"lat":51.1598841,"lon":3.2361425,"timestamp":"2012-05-09T18:22:11Z","version":1,"changeset":11551825,"user":"martino260","uid":655442,"tags":{"amenity":"bench"}},{"type":"node","id":1810326078,"lat":51.1550855,"lon":3.2349358,"timestamp":"2012-07-02T19:50:15Z","version":1,"changeset":12093439,"user":"martino260","uid":655442,"tags":{"amenity":"bench"}},{"type":"node","id":1810326092,"lat":51.1552302,"lon":3.234968,"timestamp":"2012-07-02T19:50:16Z","version":1,"changeset":12093439,"user":"martino260","uid":655442,"tags":{"amenity":"bench"}},{"type":"node","id":2325437742,"lat":51.1770052,"lon":3.1967794,"timestamp":"2013-05-30T12:19:08Z","version":1,"changeset":16350909,"user":"peeweeke","uid":494726,"tags":{"board_type":"board","information":"board","name":"Tillegembos","tourism":"information"}},{"type":"node","id":2325437743,"lat":51.1787363,"lon":3.1949036,"timestamp":"2013-05-30T12:19:08Z","version":1,"changeset":16350909,"user":"peeweeke","uid":494726,"tags":{"board_type":"board","information":"board","name":"Tillegembos","tourism":"information"}},{"type":"node","id":2325437813,"lat":51.1733102,"lon":3.1895672,"timestamp":"2013-05-30T12:19:09Z","version":1,"changeset":16350909,"user":"peeweeke","uid":494726,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437839,"lat":51.1763436,"lon":3.1984985,"timestamp":"2013-05-30T12:19:10Z","version":1,"changeset":16350909,"user":"peeweeke","uid":494726,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437848,"lat":51.1770966,"lon":3.1963507,"timestamp":"2013-05-30T12:19:10Z","version":1,"changeset":16350909,"user":"peeweeke","uid":494726,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437862,"lat":51.1773439,"lon":3.1948779,"timestamp":"2013-05-30T12:19:10Z","version":1,"changeset":16350909,"user":"peeweeke","uid":494726,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437867,"lat":51.1775994,"lon":3.1888088,"timestamp":"2013-05-30T12:19:11Z","version":1,"changeset":16350909,"user":"peeweeke","uid":494726,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2325437873,"lat":51.1778384,"lon":3.1913802,"timestamp":"2013-05-30T12:19:11Z","version":1,"changeset":16350909,"user":"peeweeke","uid":494726,"tags":{"amenity":"bench","backrest":"yes","material":"wood"}},{"type":"node","id":2732486257,"lat":51.129741,"lon":3.1907419,"timestamp":"2014-03-21T21:15:28Z","version":1,"changeset":21234491,"user":"meannder","uid":149496,"tags":{"board_type":"nature","information":"board","name":"Doeveren","tourism":"information"}},{"type":"node","id":3774054068,"lat":51.1586662,"lon":3.2271102,"timestamp":"2015-10-05T20:34:04Z","version":1,"changeset":34456387,"user":"TripleBee","uid":497177,"tags":{"amenity":"bench"}},{"type":"node","id":4769106605,"lat":51.138264,"lon":3.1798655,"timestamp":"2020-05-31T19:49:45Z","version":3,"changeset":86019474,"user":"Hopperpop","uid":3664604,"tags":{"backrest":"yes","leisure":"picnic_table"}},{"type":"node","id":4912238707,"lat":51.1448634,"lon":3.2455986,"timestamp":"2017-06-13T08:12:04Z","version":1,"changeset":49491753,"user":"Jakka","uid":2403313,"tags":{"access":"yes","amenity":"parking","fee":"no","name":"Oostkamp","parking":"Carpool"}},{"type":"node","id":5637212235,"lat":51.1305439,"lon":3.1866873,"timestamp":"2021-11-22T11:54:45Z","version":4,"changeset":114095475,"user":"L'imaginaire","uid":654234,"tags":{"board_type":"nature","image":"https://i.imgur.com/HehOQL9.jpg","information":"board","name":"Welkom Doeveren","tourism":"information"}},{"type":"node","id":5637224573,"lat":51.1281084,"lon":3.1881726,"timestamp":"2020-06-01T22:39:30Z","version":2,"changeset":86065716,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"board_type":"nature","information":"board","name":"Welkom Doeveren","tourism":"information"}},{"type":"node","id":5637230107,"lat":51.1280884,"lon":3.1889798,"timestamp":"2018-05-23T11:55:01Z","version":1,"changeset":59208628,"user":"Jakka","uid":2403313,"tags":{"information":"board","tourism":"information"}},{"type":"node","id":5637743026,"lat":51.1295973,"lon":3.1751122,"timestamp":"2021-10-08T08:53:14Z","version":2,"changeset":112251989,"user":"DieterWesttoer","uid":13062237,"tags":{"information":"board","name":"Doeveren Wandelroute","tourism":"information"}},{"type":"node","id":5716130103,"lat":51.1767183,"lon":3.1947867,"timestamp":"2018-06-24T22:04:21Z","version":1,"changeset":60130942,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":5745783208,"lat":51.1782581,"lon":3.2410111,"timestamp":"2018-07-07T18:42:23Z","version":1,"changeset":60494990,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"amenity":"bench"}},{"type":"node","id":5745807545,"lat":51.1784037,"lon":3.2369439,"timestamp":"2018-07-07T18:58:25Z","version":1,"changeset":60495307,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"amenity":"bench"}},{"type":"node","id":5745807551,"lat":51.1783278,"lon":3.236678,"timestamp":"2018-07-07T18:58:25Z","version":1,"changeset":60495307,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"amenity":"bench"}},{"type":"node","id":6535241426,"lat":51.1693142,"lon":3.1673093,"timestamp":"2019-06-09T13:50:19Z","version":1,"changeset":71071874,"user":"Hopperpop","uid":3664604,"tags":{"amenity":"bench"}},{"type":"node","id":6535241427,"lat":51.169265,"lon":3.1673159,"timestamp":"2019-06-09T13:50:19Z","version":1,"changeset":71071874,"user":"Hopperpop","uid":3664604,"tags":{"amenity":"bench"}},{"type":"node","id":6535241428,"lat":51.1692199,"lon":3.1673224,"timestamp":"2019-06-09T13:50:19Z","version":1,"changeset":71071874,"user":"Hopperpop","uid":3664604,"tags":{"amenity":"bench"}},{"type":"node","id":6535241430,"lat":51.1685726,"lon":3.1678225,"timestamp":"2019-06-09T13:50:19Z","version":1,"changeset":71071874,"user":"Hopperpop","uid":3664604,"tags":{"bench":"yes","leisure":"picnic_table","material":"wood"}},{"type":"node","id":6536026827,"lat":51.1703142,"lon":3.1691109,"timestamp":"2019-06-09T22:54:45Z","version":1,"changeset":71082671,"user":"Hopperpop","uid":3664604,"tags":{"leisure":"picnic_table"}},{"type":"node","id":6536026828,"lat":51.1702795,"lon":3.1691552,"timestamp":"2019-06-09T22:54:45Z","version":1,"changeset":71082671,"user":"Hopperpop","uid":3664604,"tags":{"leisure":"picnic_table"}},{"type":"node","id":6712112244,"lat":51.1595064,"lon":3.2021482,"timestamp":"2020-05-24T21:35:50Z","version":2,"changeset":85695537,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"leisure":"picnic_table"}},{"type":"node","id":7304050040,"lat":51.1560908,"lon":3.1748919,"timestamp":"2020-03-17T19:11:00Z","version":1,"changeset":82315744,"user":"Hopperpop","uid":3664604,"tags":{"amenity":"bench"}},{"type":"node","id":7304050041,"lat":51.1560141,"lon":3.1749533,"timestamp":"2020-03-17T19:11:00Z","version":1,"changeset":82315744,"user":"Hopperpop","uid":3664604,"tags":{"amenity":"bench"}},{"type":"node","id":7304050042,"lat":51.156032,"lon":3.1749379,"timestamp":"2020-03-17T19:11:00Z","version":1,"changeset":82315744,"user":"Hopperpop","uid":3664604,"tags":{"amenity":"bench"}},{"type":"node","id":7439979218,"lat":51.1780402,"lon":3.2178666,"timestamp":"2020-04-24T00:56:14Z","version":1,"changeset":84027933,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":7439979219,"lat":51.1780508,"lon":3.2179033,"timestamp":"2020-04-24T00:56:14Z","version":1,"changeset":84027933,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":7529262982,"lat":51.1585566,"lon":3.1715528,"timestamp":"2020-05-17T16:12:04Z","version":1,"changeset":85340264,"user":"Hopperpop","uid":3664604,"tags":{"board_type":"map","information":"board","tourism":"information"}},{"type":"node","id":7529262984,"lat":51.1585786,"lon":3.1715385,"timestamp":"2020-05-17T16:12:04Z","version":1,"changeset":85340264,"user":"Hopperpop","uid":3664604,"tags":{"leisure":"picnic_table"}},{"type":"node","id":7554879668,"lat":51.1573713,"lon":3.2043731,"timestamp":"2020-05-24T21:35:50Z","version":1,"changeset":85695537,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"access":"yes","amenity":"toilets","fee":"no","toilets:disposal":"flush","unisex":"yes","wheelchair":"yes"}},{"type":"node","id":7554879669,"lat":51.1594855,"lon":3.2021507,"timestamp":"2020-05-24T21:35:50Z","version":1,"changeset":85695537,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"leisure":"picnic_table"}},{"type":"node","id":7556988723,"lat":51.1330234,"lon":3.1839944,"timestamp":"2020-05-25T19:19:56Z","version":1,"changeset":85730259,"user":"Hopperpop","uid":3664604,"tags":{"amenity":"bench","material":"wood"}},{"type":"node","id":7575825326,"lat":51.1386553,"lon":3.1797358,"timestamp":"2020-05-31T19:49:45Z","version":1,"changeset":86019474,"user":"Hopperpop","uid":3664604,"tags":{"amenity":"bench"}},{"type":"node","id":7575825327,"lat":51.1382456,"lon":3.1797422,"timestamp":"2020-05-31T19:49:45Z","version":1,"changeset":86019474,"user":"Hopperpop","uid":3664604,"tags":{"information":"board","tourism":"information"}},{"type":"node","id":8109498958,"lat":51.1332267,"lon":3.2341272,"timestamp":"2020-11-11T20:42:45Z","version":1,"changeset":93951029,"user":"L'imaginaire","uid":654234,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":8109498959,"lat":51.1335011,"lon":3.2343954,"timestamp":"2020-11-11T20:42:45Z","version":1,"changeset":93951029,"user":"L'imaginaire","uid":654234,"tags":{"leisure":"picnic_table"}},{"type":"node","id":8198894646,"lat":51.125688,"lon":3.1856217,"timestamp":"2020-12-06T23:39:34Z","version":3,"changeset":95384686,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"image":"https://i.imgur.com/O5kX20u.jpg","information":"board","tourism":"information"}},{"type":"node","id":8199012519,"lat":51.1262245,"lon":3.1802429,"timestamp":"2020-12-07T00:12:14Z","version":3,"changeset":95385124,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"image":"https://i.imgur.com/tomw9p5.jpg","information":"board","tourism":"information"}},{"type":"node","id":8199244816,"lat":51.1252874,"lon":3.1837622,"timestamp":"2020-12-06T17:14:52Z","version":1,"changeset":95374174,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"amenity":"bench"}},{"type":"node","id":8199301617,"lat":51.1256827,"lon":3.1853543,"timestamp":"2020-12-06T17:14:52Z","version":1,"changeset":95374174,"user":"Pieter Vander Vennet","uid":3818858,"tags":{"amenity":"bench","backrest":"no"}},{"type":"node","id":8255488518,"lat":51.1406698,"lon":3.235178,"timestamp":"2020-12-23T18:20:35Z","version":1,"changeset":96342158,"user":"L'imaginaire","uid":654234,"tags":{"amenity":"bench","backrest":"yes"}},{"type":"node","id":9316104741,"lat":51.1330984,"lon":3.2335257,"timestamp":"2021-12-06T18:31:00Z","version":1,"changeset":114629890,"user":"L'imaginaire","uid":654234,"tags":{"information":"board","tourism":"information"}},{"type":"node","id":9442532340,"lat":51.1763651,"lon":3.1947952,"timestamp":"2022-01-23T16:26:28Z","version":2,"changeset":116506336,"user":"L'imaginaire","uid":654234,"tags":{"amenity":"bench","backrest":"yes","image":"https://i.imgur.com/eZ0Loii.jpg"}},{"type":"way","id":15242261,"timestamp":"2020-04-05T07:08:45Z","version":8,"changeset":83089516,"user":"Hopperpop","uid":3664604,"nodes":[150996092,150996093,6754312552,6754312553,6754312550,6754312551,150996094,150996095,150996097,150996098,6754312560,6754312559,6754312558,150996099,6754312557,150996100,6754312555,6754312556,150996101,6754312554,150996092],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":16514228,"timestamp":"2017-06-13T07:14:23Z","version":9,"changeset":49490318,"user":"Jakka","uid":2403313,"nodes":[170464837,170464839,170464840,170464841,170464837],"tags":{"access":"yes","amenity":"parking","fee":"no","maxstay":"4 hours","parking":"surface"}},{"type":"way","id":76706071,"timestamp":"2017-06-17T07:51:31Z","version":4,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[903903386,1038557094,1038557233,1038557143,1038557075,903903387,1038557195,903903388,903903390,903904576,903903386],"tags":{"access":"permissive","amenity":"parking"}},{"type":"way","id":89601157,"timestamp":"2019-11-09T18:40:50Z","version":3,"changeset":76851428,"user":"Hopperpop","uid":3664604,"nodes":[1038557083,1038557078,1038557104,1038557072,1038557108,1038557230,1038557227,1038557102,1038557137,1038575040,1038557191,1038557014,6960473080,1038557035,1038557012,1038557083],"tags":{"amenity":"parking"}},{"type":"way","id":89604999,"timestamp":"2020-01-16T22:01:28Z","version":5,"changeset":79667667,"user":"Hopperpop","uid":3664604,"nodes":[1038583404,1038583491,1038583375,1038583483,1038583479,1038583398,1038583459,1038583456,1038583446,1038583441,1038583425,1038583501,1038583451,1038583463,1038583476,1038583404],"tags":{"access":"yes","amenity":"parking","capacity":"57","carpool":"yes","description":"carpoolparking","fee":"no","name":"Loppem","parking":"surface"}},{"type":"way","id":92035679,"timestamp":"2019-10-05T08:05:33Z","version":7,"changeset":75311122,"user":"skyman81","uid":955688,"nodes":[1069177920,6853179264,1069177925,1069177919,6853179269,6853179268,6853179267,6853179215,6853179213,6853179214,1069178133,1069177984,6853179230,6853179228,6853179229,6853179224,6853179225,6853179227,6853179226,6853179216,6853179220,6853179219,6853179218,6853179217,6853179223,6853179221,6853179222,1069177967,1069177852,6853179211,6853179212,6853179210,6853179327,6853179208,6853179209,6853179203,1069177976,6853179207,6853179206,6853179205,6853179204,6853179202,1069177849,6852012579,6852012578,6852012580,6852012577,6852012581,6852012582,6852012583,1069177845,1759437085,1519342743,1519342742,1069178166,1069177853,1069177915,6853179235,6853179234,6853179236,1069177933,6853179237,6853179238,1069178021,6853179246,6853179244,6853179245,6853179240,6853179243,6853179241,6853179242,6853179239,6853179248,6853179249,6853179250,6853179247,1069177873,6853179262,6853179263,6853179260,6853179261,6853179256,6853179259,6853179257,6853179258,1069177920],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":101248451,"timestamp":"2018-05-23T14:18:27Z","version":2,"changeset":59213416,"user":"Jakka","uid":2403313,"nodes":[1168728158,1168728325,1168728159,5637669355,1168728109,1168728158],"tags":{"access":"private","amenity":"parking","name":"Parking Merkenveld"}},{"type":"way","id":101248462,"timestamp":"2020-05-25T13:53:02Z","version":3,"changeset":85720081,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[1168727876,1168728288,1168728412,1168728208,1168727876],"tags":{"amenity":"toilets","building":"yes","source:geometry:date":"2019-03-14","source:geometry:ref":"Gbg/6588148"}},{"type":"way","id":131622387,"timestamp":"2015-01-09T12:06:51Z","version":2,"changeset":28017707,"user":"TripleBee","uid":497177,"nodes":[1448421093,1448421099,1448421091,1448421081,1448421093],"tags":{"amenity":"parking","name":"Tudor - Zeeweg","parking":"surface"}},{"type":"way","id":145691934,"timestamp":"2012-01-15T12:43:37Z","version":1,"changeset":10397429,"user":"Sanderd17","uid":253266,"nodes":[1590642859,1590642860,1590642858,1590642849,1590642859],"tags":{"amenity":"parking"}},{"type":"way","id":145691937,"timestamp":"2012-01-15T12:43:37Z","version":1,"changeset":10397429,"user":"Sanderd17","uid":253266,"nodes":[1590642829,1590642828,1590642830,1590642832,1590642829],"tags":{"amenity":"parking"}},{"type":"way","id":158901716,"timestamp":"2017-06-13T07:12:20Z","version":2,"changeset":49490264,"user":"Jakka","uid":2403313,"nodes":[1710245713,1710245718,1710245707,1710245705,1710245703,1710245715,1710245711,1710245709,1710245701,1710245713],"tags":{"access":"yes","amenity":"parking","capacity":"14","fee":"no","parking":"surface"}},{"type":"way","id":158904558,"timestamp":"2020-12-22T22:39:41Z","version":4,"changeset":96283379,"user":"M!dgard","uid":763799,"nodes":[1710262742,1710262745,1710262735,1710262733,1710262732,1710262743,1710262741,1710262739,1710262744,1710262737,1710262736,1710262731,1710262738,1710262742],"tags":{"access":"yes","alt_name":"Schoolparking","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":158906028,"timestamp":"2017-06-13T07:27:19Z","version":5,"changeset":49490646,"user":"Jakka","uid":2403313,"nodes":[1710276259,1710276251,1810330766,1710276255,1710276261,1710276240,1710276232,1710276257,1710276243,1710276253,1810347217,1710276242,1710276259],"tags":{"access":"yes","amenity":"parking","fee":"no","name":"Parking Sportcentrum De Valkaart","parking":"surface"}},{"type":"way","id":160825858,"timestamp":"2012-04-23T20:35:52Z","version":1,"changeset":11399632,"user":"martino260","uid":655442,"nodes":[1728421375,1728421374,1728421379,1728421377,1728421376,1728421378,1728421375],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":162602213,"timestamp":"2020-04-11T18:12:16Z","version":8,"changeset":83407731,"user":"JanFi","uid":672253,"nodes":[1920143232,7393009684,7393048385,1744641293,1523513488,1744641292,1920143232],"tags":{"amenity":"parking","capacity":"15"}},{"type":"way","id":165489167,"timestamp":"2020-10-12T19:06:29Z","version":3,"changeset":92371840,"user":"L'imaginaire","uid":654234,"nodes":[4912197370,4912197365,4912197373,4912197364,4912197372,1770289505,4912197362,4912197371,4912197374,4912197363,4912197368,4912197366,4912197369,4912197367,4912197370],"tags":{"access":"yes","amenity":"parking","fee":"no","name":"Bad Neuheimplein","parking":"surface"}},{"type":"way","id":168291852,"timestamp":"2017-07-19T11:17:33Z","version":3,"changeset":50402298,"user":"martino260","uid":655442,"nodes":[1795793399,4979389763,1795793409,1795793395,1795793393,1795793397,1795793407,1795793406,1795793408,1795793405,1795793399],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":169875513,"timestamp":"2017-06-13T07:26:09Z","version":2,"changeset":49490613,"user":"Jakka","uid":2403313,"nodes":[1810345951,1810345955,1810345947,1810345944,1810345951],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":170015605,"timestamp":"2017-06-17T07:51:33Z","version":4,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[1811673425,1811673421,1811673418,1811673423,1811673425],"tags":{"access":"private","amenity":"parking","name":"gheeraert E40","operator":"Gheeraert"}},{"type":"way","id":170018487,"timestamp":"2017-06-17T07:51:33Z","version":3,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[1811699779,1811699778,1811699776,1811699777,1811699779],"tags":{"access":"private","amenity":"parking","name":"Gheeraert vooraan"}},{"type":"way","id":170559194,"timestamp":"2017-06-17T07:51:33Z","version":2,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[1817319304,1817319302,1817319297,1817319301,1817319304],"tags":{"access":"private","amenity":"parking","name":"Gheeraert laadkade"}},{"type":"way","id":170559195,"timestamp":"2017-06-17T07:51:33Z","version":2,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[1817319299,1817319303,1817319300,1817319292,1817319299],"tags":{"access":"private","amenity":"parking","name":"Gheeraert spoorweg trailers"}},{"type":"way","id":170559196,"timestamp":"2017-06-17T07:51:33Z","version":2,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[1817319293,1817319289,1817319291,1817319296,1817319293],"tags":{"access":"private","amenity":"parking","name":"Gheeraert spoorweg trucks"}},{"type":"way","id":170559197,"timestamp":"2017-06-17T07:51:33Z","version":2,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[1817319294,1817319298,1817319295,1817319290,1817319294],"tags":{"access":"private","amenity":"parking","name":"Gheeraert zijkant"}},{"type":"way","id":170559292,"timestamp":"2017-06-17T07:51:33Z","version":2,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[1817320496,1817320494,1817320493,1817320495,1817320496],"tags":{"access":"private","amenity":"parking","name":"Gheeraert vooraan gebouw"}},{"type":"way","id":170559832,"timestamp":"2020-10-07T10:51:41Z","version":6,"changeset":92105788,"user":"effem","uid":16437,"nodes":[1817324515,1817324509,1817324491,6397031888,4044172008,4044172003,4044171997,4044171962,4044171957,4044171976,1817324489,1817324488,3550860268,1817324505,3550860269,1817324513,1817324515],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":223674368,"timestamp":"2020-12-03T18:47:28Z","version":3,"changeset":95244226,"user":"L'imaginaire","uid":654234,"nodes":[2325437844,8191691971,8191691973,8191691972,2325437840,8191691970,414025563,2325437844],"tags":{"amenity":"parking","name":"Tillegembos","parking":"surface"}},{"type":"way","id":237214948,"timestamp":"2017-06-17T07:51:35Z","version":2,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[2451574741,2451574742,2451574744,1015583939,2451574741],"tags":{"access":"private","amenity":"parking"}},{"type":"way","id":237214949,"timestamp":"2017-06-17T07:51:35Z","version":2,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[2451574748,2451574746,2451574747,2451574749,2451574748],"tags":{"access":"private","amenity":"parking"}},{"type":"way","id":237214950,"timestamp":"2017-06-17T07:51:35Z","version":3,"changeset":49608752,"user":"rowers2","uid":2445224,"nodes":[2451569392,1015567837,2451574745,2451574743,2451578121,2451569392],"tags":{"access":"private","amenity":"parking"}},{"type":"way","id":325909586,"timestamp":"2016-01-05T18:51:49Z","version":2,"changeset":36387330,"user":"JanFi","uid":672253,"nodes":[3325315243,111759500,3325315247,3325315232,3325315230,3325315226,1169056712,3325315243],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":326834162,"timestamp":"2021-10-10T21:49:11Z","version":4,"changeset":112350014,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[3335137807,3335137692,3335137795,9163493632,3335137802,3335137812,9163486855,9163486856,3335137823,3335137807],"tags":{"access":"customers","amenity":"parking","operator":"Best Western Weinebrugge","parking":"surface"}},{"type":"way","id":327849054,"timestamp":"2015-02-12T20:26:22Z","version":1,"changeset":28807613,"user":"escada","uid":436365,"nodes":[3346575929,3346575873,3346575876,3346575843,3346575845,3346575891,3346575901,3346575923,3346575928,3346575950,3346575929],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":327849055,"timestamp":"2016-10-08T21:24:46Z","version":2,"changeset":42742859,"user":"maggot27","uid":118021,"nodes":[3346575945,3346575946,3346575943,3346575933,3346575925,3346575917,3346575903,3346575908,3346575889,3346575886,3346575945],"tags":{"access":"customers","amenity":"parking","parking":"surface"}},{"type":"way","id":327849056,"timestamp":"2015-02-12T20:26:22Z","version":1,"changeset":28807613,"user":"escada","uid":436365,"nodes":[3346575865,3346575853,3346575855,3346575846,3346575840,3346575858,3346575865],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":374677860,"timestamp":"2015-10-10T09:08:20Z","version":1,"changeset":34545536,"user":"Jakka","uid":2403313,"nodes":[3780611504,3780611502,3780611500,3780611503,3780611504],"tags":{"amenity":"parking"}},{"type":"way","id":374677861,"timestamp":"2015-10-10T09:08:20Z","version":1,"changeset":34545536,"user":"Jakka","uid":2403313,"nodes":[3780611495,3780611493,3780611492,3780611494,3780611495],"tags":{"amenity":"parking"}},{"type":"way","id":374677862,"timestamp":"2015-10-10T09:08:20Z","version":1,"changeset":34545536,"user":"Jakka","uid":2403313,"nodes":[3780611498,3780611497,3780611496,3780611499,3780611501,3780611498],"tags":{"amenity":"parking"}},{"type":"way","id":389912371,"timestamp":"2016-01-06T16:51:45Z","version":1,"changeset":36407948,"user":"Spectrokid","uid":19775,"nodes":[3930713440,3930713451,3930713447,3930713437,3930713440],"tags":{"amenity":"parking"}},{"type":"way","id":389912372,"timestamp":"2019-11-16T13:17:09Z","version":4,"changeset":77164376,"user":"Hopperpop","uid":3664604,"nodes":[3930713454,3930713442,3930713435,3930713429,5826811614,3930713426,3930713430,6982605752,6982605754,3930713438,6982605769,6982605766,6982605767,6982605762,6982605764,3930713446,3930713454],"tags":{"access":"customers","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":401995684,"timestamp":"2020-10-07T10:52:00Z","version":3,"changeset":92105972,"user":"effem","uid":16437,"nodes":[4044171963,4044171954,4044171924,4044171936,4044171941,4044171963],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":500067820,"timestamp":"2017-06-13T07:49:12Z","version":1,"changeset":49491219,"user":"Jakka","uid":2403313,"nodes":[4912203166,4912203165,4912203164,4912203163,4912203162,4912203161,4912203160,4912203166],"tags":{"access":"yes","amenity":"parking","parking":"surface"}},{"type":"way","id":500067821,"timestamp":"2017-06-13T07:49:12Z","version":1,"changeset":49491219,"user":"Jakka","uid":2403313,"nodes":[4912203170,4912203169,4912203168,4912203167,4912203170],"tags":{"access":"yes","amenity":"parking","parking":"surface"}},{"type":"way","id":500067822,"timestamp":"2017-06-13T07:49:12Z","version":1,"changeset":49491219,"user":"Jakka","uid":2403313,"nodes":[4912203174,4912203173,4912203172,4912203171,4912203174],"tags":{"access":"yes","amenity":"parking","parking":"surface"}},{"type":"way","id":500067823,"timestamp":"2017-06-13T07:49:12Z","version":1,"changeset":49491219,"user":"Jakka","uid":2403313,"nodes":[4912203179,4912203178,4912203177,4912203176,4912203179],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":500069613,"timestamp":"2018-10-11T09:30:48Z","version":2,"changeset":63409550,"user":"Jakka","uid":2403313,"nodes":[4912214695,4912214685,4912214694,4912214693,4912214692,4912214680,4912214695],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":500071452,"timestamp":"2018-10-11T09:30:48Z","version":2,"changeset":63409550,"user":"Jakka","uid":2403313,"nodes":[4912225068,4912225062,4912225063,4912225053,4912225064,4912214694,4912214685,4912225068],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":500071455,"timestamp":"2018-10-11T09:30:48Z","version":2,"changeset":63409550,"user":"Jakka","uid":2403313,"nodes":[4912225070,4912214681,4912214686,4912225052,4912225051,4912225067,4912225062,4912225068,4912225070],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":500071458,"timestamp":"2018-10-11T09:30:48Z","version":2,"changeset":63409550,"user":"Jakka","uid":2403313,"nodes":[4912214695,4912214680,4912225069,4912225050,1525460846,4912214681,4912225070,4912214695],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":533276307,"timestamp":"2019-12-13T10:02:12Z","version":2,"changeset":78364882,"user":"skyman81","uid":955688,"nodes":[5173881316,5173881317,5173881318,7054196467,5173881316],"tags":{"amenity":"parking"}},{"type":"way","id":533276308,"timestamp":"2017-10-17T23:36:18Z","version":1,"changeset":53027174,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[5173881320,5173881621,5173881622,5173881623,5173881320],"tags":{"amenity":"parking"}},{"type":"way","id":533276309,"timestamp":"2017-10-17T23:36:18Z","version":1,"changeset":53027174,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[5173881624,5173881625,5173881626,5173881627,5173881624],"tags":{"amenity":"parking"}},{"type":"way","id":579848581,"timestamp":"2020-04-05T07:08:57Z","version":6,"changeset":83089516,"user":"Hopperpop","uid":3664604,"nodes":[4043782112,5825400688,5552466020,6997096756,6997096759,6997096758,5552466018,5552466013,5552466014,6997076567,4043782112],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":584455569,"timestamp":"2019-10-31T19:49:18Z","version":2,"changeset":76465627,"user":"Hopperpop","uid":3664604,"nodes":[5586765933,5586765934,5586765935,5586765936,5586765933],"tags":{"amenity":"parking"}},{"type":"way","id":585977870,"timestamp":"2019-10-11T13:28:22Z","version":2,"changeset":75566739,"user":"Hopperpop","uid":3664604,"nodes":[5587844460,5599314384,5599314385,1659850846,6870850178,5587844462,5587844461,6870863414,5587844460],"tags":{"amenity":"parking"}},{"type":"way","id":587014342,"timestamp":"2018-05-09T19:13:29Z","version":1,"changeset":58829130,"user":"Sille Van Landschoot","uid":4852501,"nodes":[5607796820,5607798725,5607798721,5607798722,5607796819,5607798723,5607796820],"tags":{"access":"permissive","amenity":"parking","park_ride":"no","parking":"surface","surface":"paved"}},{"type":"way","id":590167103,"timestamp":"2018-05-22T12:37:36Z","version":1,"changeset":59179114,"user":"ForstEK","uid":1737608,"nodes":[5635001277,5635001274,5635001275,5635001276,5635001277],"tags":{"amenity":"parking"}},{"type":"way","id":590167113,"timestamp":"2020-07-29T17:45:20Z","version":2,"changeset":88691835,"user":"JanFi","uid":672253,"nodes":[5635001312,5635001306,7767137237,7767137235,7767137236,7767137234,5635001312],"tags":{"amenity":"parking"}},{"type":"way","id":590167134,"timestamp":"2018-05-22T12:37:37Z","version":1,"changeset":59179114,"user":"ForstEK","uid":1737608,"nodes":[5635001374,5635001373,5635001372,5635001371,5635001374],"tags":{"amenity":"parking"}},{"type":"way","id":590167135,"timestamp":"2018-05-22T12:37:37Z","version":1,"changeset":59179114,"user":"ForstEK","uid":1737608,"nodes":[5635001378,5635001377,5635001376,5635001375,5635001378],"tags":{"amenity":"parking"}},{"type":"way","id":590167136,"timestamp":"2018-05-22T12:37:37Z","version":1,"changeset":59179114,"user":"ForstEK","uid":1737608,"nodes":[5635001382,5635001381,5635001380,5635001379,5635001382],"tags":{"amenity":"parking"}},{"type":"way","id":590167137,"timestamp":"2019-07-06T15:58:19Z","version":3,"changeset":71962591,"user":"gjosch","uid":1776978,"nodes":[5635001386,5882873336,5882873337,5882873338,5882873335,6593340582,6593340583,5882873334,6593340584,5635001385,5635001384,5635001383,5635001386],"tags":{"amenity":"parking"}},{"type":"way","id":590167147,"timestamp":"2018-05-22T12:37:38Z","version":1,"changeset":59179114,"user":"ForstEK","uid":1737608,"nodes":[5635001417,5635001414,5635001415,5635001416,5635001417],"tags":{"amenity":"parking"}},{"type":"way","id":601406079,"timestamp":"2018-06-24T22:15:06Z","version":1,"changeset":60131072,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[5716136617,5716136618,5716136619,5716136620,5716136617],"tags":{"amenity":"parking"}},{"type":"way","id":632813009,"timestamp":"2018-10-11T09:24:42Z","version":1,"changeset":63409297,"user":"Jakka","uid":2403313,"nodes":[5974489618,1810326044,1810326087,5974489617,5972179348,5972179347,5972179346,5972179345,5972179344,5972179343,5972179331,5974489616,5974489615,5974489614,5974489618],"tags":{"amenity":"parking","name":"Gemeenteplein","parking":"surface"}},{"type":"way","id":668043297,"timestamp":"2019-04-10T18:34:27Z","version":2,"changeset":69093378,"user":"RudolpheDeer","uid":9408828,"nodes":[6255587424,6255587425,6255587426,6255587427,6255587424],"tags":{"access":"private","amenity":"parking"}},{"type":"way","id":670104236,"timestamp":"2019-02-13T00:05:02Z","version":1,"changeset":67147239,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[6275462768,6275462769,6275462770,6275462771,6275462768],"tags":{"amenity":"parking"}},{"type":"way","id":670104238,"timestamp":"2019-02-13T00:05:02Z","version":1,"changeset":67147239,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[6275462772,6275462989,6275462773,6275462774,6275462775,6275462772],"tags":{"amenity":"parking"}},{"type":"way","id":670104239,"timestamp":"2019-02-13T00:05:02Z","version":1,"changeset":67147239,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[6275462776,6275462777,6275462778,6275462779,6275462776],"tags":{"amenity":"parking"}},{"type":"way","id":670104241,"timestamp":"2019-02-13T00:05:02Z","version":1,"changeset":67147239,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[6275462780,6275462781,6275462782,6275462783,6275462780],"tags":{"amenity":"parking"}},{"type":"way","id":670104242,"timestamp":"2019-02-13T00:05:02Z","version":1,"changeset":67147239,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[6275462784,6275462985,6275462988,6275462986,6275462987,6275462784],"tags":{"amenity":"parking"}},{"type":"way","id":671840055,"timestamp":"2019-02-20T15:15:45Z","version":1,"changeset":67395313,"user":"Tim Couwelier","uid":7246683,"nodes":[6291339827,6291339828,6291339816,6291339815,6291339822,6291339821,6291339829,6291339830,6291339827],"tags":{"amenity":"parking"}},{"type":"way","id":695825223,"timestamp":"2019-06-08T15:19:24Z","version":1,"changeset":71053301,"user":"Hopperpop","uid":3664604,"nodes":[1519476746,6533893620,6533893621,6533893622,1519476797,1519476620,1519476746],"tags":{"access":"yes","amenity":"parking"}},{"type":"way","id":695825224,"timestamp":"2019-06-08T15:19:24Z","version":1,"changeset":71053301,"user":"Hopperpop","uid":3664604,"nodes":[1519476744,6533893624,6533893625,6533893626,1519476698,1519476635,1519476744],"tags":{"access":"yes","amenity":"parking"}},{"type":"way","id":696040917,"timestamp":"2019-06-09T23:24:59Z","version":2,"changeset":71082992,"user":"Hopperpop","uid":3664604,"nodes":[6536026850,6536026851,6536026852,6536026853,6536026850],"tags":{"amenity":"parking","name":"Kasteel Tudor"}},{"type":"way","id":696043218,"timestamp":"2019-06-09T23:24:59Z","version":1,"changeset":71082992,"user":"Hopperpop","uid":3664604,"nodes":[6536038234,6536038235,6536038236,6536038237,6536038234],"tags":{"access":"customers","amenity":"parking"}},{"type":"way","id":700675991,"timestamp":"2020-12-18T10:48:20Z","version":2,"changeset":96062619,"user":"Hopperpop","uid":3664604,"nodes":[6579962064,6579962065,6579962066,6579962068,6579962067,6579962064],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":705278707,"timestamp":"2020-09-30T20:36:55Z","version":2,"changeset":91787895,"user":"L'imaginaire","uid":654234,"nodes":[6625037999,6625038000,6625038001,6625038002,6625038003,6004375826,6625038005,6625038006,6625037999],"tags":{"amenity":"parking"}},{"type":"way","id":719482833,"timestamp":"2019-08-28T21:18:49Z","version":1,"changeset":73857967,"user":"Hopperpop","uid":3664604,"nodes":[6754312544,6754312543,6754312542,6754312541,6754312544],"tags":{"access":"yes","amenity":"parking","capacity":"5"}},{"type":"way","id":719482834,"timestamp":"2019-08-28T21:18:49Z","version":1,"changeset":73857967,"user":"Hopperpop","uid":3664604,"nodes":[6754312565,6754312564,6754312563,6754312562,6754312565],"tags":{"access":"yes","amenity":"parking","capacity":"12"}},{"type":"way","id":737054013,"timestamp":"2019-10-20T15:39:32Z","version":1,"changeset":75957554,"user":"Hopperpop","uid":3664604,"nodes":[5826811496,5826811497,5826811494,5826811495,5826811496],"tags":{"amenity":"parking"}},{"type":"way","id":737054014,"timestamp":"2019-10-20T15:39:32Z","version":1,"changeset":75957554,"user":"Hopperpop","uid":3664604,"nodes":[5826810676,5826810673,5826810674,5826810675,5826810676],"tags":{"amenity":"parking"}},{"type":"way","id":737054015,"timestamp":"2019-10-20T15:39:32Z","version":1,"changeset":75957554,"user":"Hopperpop","uid":3664604,"nodes":[5826810681,5826810678,5826810679,5826810680,5826810681],"tags":{"amenity":"parking"}},{"type":"way","id":737093410,"timestamp":"2021-08-14T21:52:07Z","version":2,"changeset":109683899,"user":"effem","uid":16437,"nodes":[5826811559,5826811536,5826811535,5826811561,5826811560,5826811559],"tags":{"access":"yes","amenity":"parking","capacity":"4","fee":"no","parking":"surface"}},{"type":"way","id":737093411,"timestamp":"2021-08-14T21:52:03Z","version":2,"changeset":109683899,"user":"effem","uid":16437,"nodes":[5826811551,5826811547,5826811548,5826811549,5826811550,5826811551],"tags":{"access":"yes","amenity":"parking","capacity":"4","fee":"no","parking":"surface"}},{"type":"way","id":739652949,"timestamp":"2019-10-28T20:18:16Z","version":1,"changeset":76314556,"user":"Hopperpop","uid":3664604,"nodes":[6925536542,6925536541,6925536540,6925536539,6925536542],"tags":{"amenity":"parking","capacity":"6","parking":"surface"}},{"type":"way","id":741675236,"timestamp":"2020-12-17T22:07:55Z","version":4,"changeset":96029554,"user":"Hopperpop","uid":3664604,"nodes":[6943148207,6943148206,6943148205,6943148204,1637742821,6943148203,6943148202,6943148201,6943148200,6943148199,6943148198,6943148197,6943148207],"tags":{"access":"yes","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":742295526,"timestamp":"2019-11-05T19:27:15Z","version":1,"changeset":76664875,"user":"Hopperpop","uid":3664604,"nodes":[6949357909,6949357908,6949357907,6949357906,6949357909],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":742295527,"timestamp":"2019-11-05T19:27:15Z","version":1,"changeset":76664875,"user":"Hopperpop","uid":3664604,"nodes":[6949357913,6949357912,6949357911,6949357910,6949357913],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":742295528,"timestamp":"2019-11-05T19:27:15Z","version":1,"changeset":76664875,"user":"Hopperpop","uid":3664604,"nodes":[6949357917,6949357916,6949357915,6949357914,6949357917],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":742295529,"timestamp":"2019-11-05T19:27:15Z","version":1,"changeset":76664875,"user":"Hopperpop","uid":3664604,"nodes":[6949357921,6949357920,6949357919,6949357918,6949357921],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":746170866,"timestamp":"2019-11-16T15:27:02Z","version":1,"changeset":77167609,"user":"Hopperpop","uid":3664604,"nodes":[6982906547,6982906546,6982906545,6982906544,6982906543,6982906542,6982906547],"tags":{"access":"customers","amenity":"parking"}},{"type":"way","id":747880657,"timestamp":"2021-09-19T12:40:45Z","version":2,"changeset":111407274,"user":"Hopperpop","uid":3664604,"nodes":[3325315397,6997076566,6997076565,6997076563,6997076562,6997076564,3325315395,3325315397],"tags":{"access":"customers","amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":763977465,"timestamp":"2020-12-17T21:59:46Z","version":2,"changeset":96029554,"user":"Hopperpop","uid":3664604,"nodes":[7137343680,7137343681,7137343682,7137343683,7137343680],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":763977466,"timestamp":"2020-12-17T21:59:40Z","version":2,"changeset":96029554,"user":"Hopperpop","uid":3664604,"nodes":[7137343684,7137383185,7137383186,7137383187,7137343684],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":803821090,"timestamp":"2020-05-14T17:37:10Z","version":1,"changeset":85215781,"user":"Hopperpop","uid":3664604,"nodes":[7519058290,7519058289,7519058288,7519058287,7519058290],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":803821091,"timestamp":"2020-05-14T17:37:10Z","version":1,"changeset":85215781,"user":"Hopperpop","uid":3664604,"nodes":[7519058294,7519058293,7519058292,7519058291,7519058294],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":803821092,"timestamp":"2020-05-14T17:37:10Z","version":1,"changeset":85215781,"user":"Hopperpop","uid":3664604,"nodes":[7519058298,7519058297,7519058296,7519058295,7519058298],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":803821093,"timestamp":"2020-05-14T17:37:10Z","version":1,"changeset":85215781,"user":"Hopperpop","uid":3664604,"nodes":[7519058302,7519058301,7519058300,7519058299,7519058302],"tags":{"access":"private","amenity":"parking","capacity":"6","parking":"surface"}},{"type":"way","id":804963962,"timestamp":"2020-05-17T17:09:31Z","version":1,"changeset":85342199,"user":"Hopperpop","uid":3664604,"nodes":[7529417225,7529417226,7529417227,7529417228,7529417229,7529417230,7529417232,7529417225],"tags":{"access":"customers","amenity":"parking","fee":"no","operator":"’t Kiekekot","parking":"surface","surface":"unpaved"}},{"type":"way","id":806875503,"timestamp":"2020-05-21T15:48:37Z","version":1,"changeset":85563652,"user":"Hopperpop","uid":3664604,"nodes":[4042671969,7545532512,7545532514,7545532513,3359977305,4042671969],"tags":{"amenity":"parking","parking":"surface"}},{"type":"way","id":806963547,"timestamp":"2020-05-21T21:16:34Z","version":1,"changeset":85574048,"user":"Hopperpop","uid":3664604,"nodes":[7546193222,7546193221,7546193220,7546193219,7546193222],"tags":{"access":"private","amenity":"parking","parking":"surface"}},{"type":"way","id":865357121,"timestamp":"2020-10-30T14:45:23Z","version":1,"changeset":93296961,"user":"L'imaginaire","uid":654234,"nodes":[8065883228,8065883227,8065883226,8065883225,8065883228],"tags":{"amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":865357122,"timestamp":"2020-10-30T14:45:23Z","version":1,"changeset":93296961,"user":"L'imaginaire","uid":654234,"nodes":[8065883233,8065883230,8065883229,8065883232,8065883233],"tags":{"amenity":"parking","fee":"no","parking":"surface"}},{"type":"way","id":879281221,"timestamp":"2020-11-30T14:18:18Z","version":1,"changeset":95050429,"user":"M!dgard","uid":763799,"nodes":[8179735269,8179735268,8179735267,8179735266,8179735265,8179735264,8179735224,8179735269],"tags":{"access":"customers","amenity":"parking","parking":"surface"}},{"type":"way","id":881770201,"timestamp":"2020-12-07T00:46:56Z","version":1,"changeset":95385582,"user":"Pieter Vander Vennet","uid":3818858,"nodes":[8200275847,8200275848,8200275844,8200275853,8200275849,8200275847],"tags":{"amenity":"parking","parking":"surface","surface":"grass"}},{"type":"way","id":978360549,"timestamp":"2021-09-01T08:53:08Z","version":1,"changeset":110553113,"user":"JanFi","uid":672253,"nodes":[5761770202,5761770204,9052878229,9052878228,5761770202],"tags":{"amenity":"parking"}},{"type":"way","id":1009692722,"timestamp":"2021-12-06T18:34:20Z","version":1,"changeset":114629990,"user":"L'imaginaire","uid":654234,"nodes":[9316118540,9316118536,9316118531,9316118535,9316118534,9316118533,9316118530,9316118532,3311835478,9316118540],"tags":{"amenity":"parking","parking":"street_side"}},{"type":"relation","id":8188853,"timestamp":"2020-07-05T12:38:48Z","version":13,"changeset":87554177,"user":"Pieter Vander Vennet","uid":3818858,"members":[{"type":"way","ref":577572397,"role":"outer"},{"type":"way","ref":577572399,"role":"outer"}],"tags":{"access":"guided","curator":"Luc Maene;Geert De Clercq","email":"lucmaene@hotmail.com;geert.de.clercq1@pandora.be","landuse":"meadow","leisure":"nature_reserve","name":"De Wulgenbroeken","natural":"wetland","operator":"Natuurpunt Brugge","type":"multipolygon","website":"https://natuurpuntbrugge.be/wulgenbroeken/","wetland":"wet_meadow","wikidata":"Q60061498","wikipedia":"nl:Wulgenbroeken"}},{"type":"relation","id":11163488,"timestamp":"2021-10-04T14:09:47Z","version":15,"changeset":112079863,"user":"DieterWesttoer","uid":13062237,"members":[{"type":"way","ref":810604915,"role":"outer"},{"type":"way","ref":989393316,"role":"outer"},{"type":"way","ref":389026405,"role":"inner"},{"type":"way","ref":810607458,"role":"outer"}],"tags":{"access":"yes","curator":"Kris Lesage","description":"Wat Doeveren zo uniek maakt, zijn zijn kleine heidegebiedjes met soorten die erg verschillen van de Kempense heide. Doeveren en omstreken was vroeger één groot heidegebied, maar bestaat nu grotendeels uit bossen.","dog":"leashed","email":"doeveren@natuurpuntzedelgem.be","image":"https://i.imgur.com/NEAsQZG.jpg","image:0":"https://i.imgur.com/Dq71hyQ.jpg","image:1":"https://i.imgur.com/mAIiT4f.jpg","image:2":"https://i.imgur.com/dELZU97.jpg","image:3":"https://i.imgur.com/Bso57JC.jpg","image:4":"https://i.imgur.com/9DtcfXo.jpg","image:5":"https://i.imgur.com/0R6eBfk.jpg","image:6":"https://i.imgur.com/b0JpvbR.jpg","leisure":"nature_reserve","name":"Doeveren","operator":"Natuurpunt Zedelgem","phone":"+32 486 25 25 30","type":"multipolygon","website":"https://www.natuurpuntzedelgem.be/gebieden/doeveren/","wikidata":"Q56395754","wikipedia":"nl:Doeveren (natuurgebied)"}},{"type":"relation","id":11790117,"timestamp":"2020-10-24T19:11:01Z","version":1,"changeset":92997462,"user":"Pieter Vander Vennet","uid":3818858,"members":[{"type":"way","ref":863373849,"role":"outer"},{"type":"way","ref":777280458,"role":"outer"}],"tags":{"access":"no","description:0":"In gebruik als waterbuffering","leisure":"nature_reserve","name":"Kerkebeek","operator":"Natuurpunt Brugge","type":"multipolygon"}},{"type":"node","id":1038638696,"lat":51.1197075,"lon":3.1827007},{"type":"node","id":7578975029,"lat":51.1199041,"lon":3.1828945},{"type":"node","id":7578975030,"lat":51.1201514,"lon":3.1831942},{"type":"node","id":1038638743,"lat":51.1202445,"lon":3.1894878},{"type":"node","id":7578975002,"lat":51.1202598,"lon":3.1897155},{"type":"node","id":7578975007,"lat":51.1199771,"lon":3.1863015},{"type":"node","id":7578975008,"lat":51.1199523,"lon":3.1863031},{"type":"node","id":7578975009,"lat":51.1199279,"lon":3.1859524},{"type":"node","id":1168728109,"lat":51.1275839,"lon":3.1765505},{"type":"node","id":1168728158,"lat":51.1278835,"lon":3.1763986},{"type":"node","id":1168728159,"lat":51.1276298,"lon":3.1767808},{"type":"node","id":5637669355,"lat":51.1276039,"lon":3.1766509},{"type":"node","id":1038638723,"lat":51.1272818,"lon":3.184601},{"type":"node","id":7554434438,"lat":51.1225298,"lon":3.1847624},{"type":"node","id":7578865273,"lat":51.122084,"lon":3.1846859},{"type":"node","id":7578975032,"lat":51.1215762,"lon":3.1842866},{"type":"node","id":1168727876,"lat":51.1290569,"lon":3.1766033},{"type":"node","id":1168728208,"lat":51.1289763,"lon":3.1767696},{"type":"node","id":1168728288,"lat":51.1291195,"lon":3.1766799},{"type":"node","id":1168728325,"lat":51.1279295,"lon":3.1766288},{"type":"node","id":1168728412,"lat":51.1290389,"lon":3.1768463},{"type":"node","id":1038638712,"lat":51.1282367,"lon":3.1840296},{"type":"node","id":1168727824,"lat":51.1312478,"lon":3.182233},{"type":"node","id":3922375256,"lat":51.1301155,"lon":3.1848042},{"type":"node","id":3922380071,"lat":51.1304048,"lon":3.1838954},{"type":"node","id":3922380081,"lat":51.1305694,"lon":3.1845093},{"type":"node","id":3922380086,"lat":51.1306445,"lon":3.1848152},{"type":"node","id":3922380092,"lat":51.1307378,"lon":3.1849591},{"type":"node","id":7577430793,"lat":51.1289492,"lon":3.1836032},{"type":"node","id":7578975024,"lat":51.1299598,"lon":3.1841704},{"type":"node","id":7578975028,"lat":51.1322547,"lon":3.1833542},{"type":"node","id":7578975049,"lat":51.1313772,"lon":3.1838431},{"type":"node","id":9167054153,"lat":51.1310258,"lon":3.1823668},{"type":"node","id":9167054154,"lat":51.13145,"lon":3.1841492},{"type":"node","id":9167054156,"lat":51.1316731,"lon":3.1850331},{"type":"node","id":9274761589,"lat":51.1297088,"lon":3.1831312},{"type":"node","id":9274761596,"lat":51.1296735,"lon":3.1831518},{"type":"node","id":929120698,"lat":51.1276376,"lon":3.1903134},{"type":"node","id":1038638592,"lat":51.1264889,"lon":3.19027},{"type":"node","id":1038638661,"lat":51.1258582,"lon":3.1854626},{"type":"node","id":1038638721,"lat":51.125636,"lon":3.1855855},{"type":"node","id":1038638753,"lat":51.123845,"lon":3.1880289},{"type":"node","id":3921878998,"lat":51.1255719,"lon":3.1902463},{"type":"node","id":3921879004,"lat":51.1275463,"lon":3.188843},{"type":"node","id":3921879011,"lat":51.1271626,"lon":3.1872368},{"type":"node","id":3921879019,"lat":51.1277666,"lon":3.1868505},{"type":"node","id":7554434436,"lat":51.1252645,"lon":3.1852941},{"type":"node","id":7578865274,"lat":51.1230564,"lon":3.187978},{"type":"node","id":7578865275,"lat":51.1226417,"lon":3.188075},{"type":"node","id":7578904489,"lat":51.1247504,"lon":3.1900249},{"type":"node","id":7578974988,"lat":51.1223221,"lon":3.1906513},{"type":"node","id":7578974989,"lat":51.1224255,"lon":3.1905646},{"type":"node","id":7578974990,"lat":51.1224672,"lon":3.1905195},{"type":"node","id":7578974991,"lat":51.1228709,"lon":3.1901867},{"type":"node","id":7578974992,"lat":51.1229568,"lon":3.1901459},{"type":"node","id":7578974995,"lat":51.123814,"lon":3.1899138},{"type":"node","id":7578974996,"lat":51.1239199,"lon":3.189925},{"type":"node","id":7578974997,"lat":51.1244111,"lon":3.1899686},{"type":"node","id":7578974998,"lat":51.1248503,"lon":3.190215},{"type":"node","id":7578974999,"lat":51.1247917,"lon":3.1900516},{"type":"node","id":7578975000,"lat":51.1248293,"lon":3.1900978},{"type":"node","id":7578975001,"lat":51.1248444,"lon":3.1901483},{"type":"node","id":7578975035,"lat":51.1250798,"lon":3.1851611},{"type":"node","id":7578975045,"lat":51.1278881,"lon":3.1882941},{"type":"node","id":9199177059,"lat":51.1256647,"lon":3.1855696},{"type":"node","id":7578987409,"lat":51.1232707,"lon":3.1920382},{"type":"node","id":7578987413,"lat":51.1260416,"lon":3.1973652},{"type":"node","id":7578987414,"lat":51.1263443,"lon":3.1973775},{"type":"node","id":7578987416,"lat":51.1278708,"lon":3.1974134},{"type":"node","id":7578987417,"lat":51.126749,"lon":3.197258},{"type":"node","id":1675648152,"lat":51.1281877,"lon":3.1903323},{"type":"node","id":2732486274,"lat":51.1302553,"lon":3.1886305},{"type":"node","id":3921879018,"lat":51.1280809,"lon":3.188102},{"type":"node","id":3922380061,"lat":51.1301929,"lon":3.1895402},{"type":"node","id":3922380083,"lat":51.1305788,"lon":3.1884337},{"type":"node","id":3922380095,"lat":51.130784,"lon":3.1852632},{"type":"node","id":7578865281,"lat":51.1283938,"lon":3.1903716},{"type":"node","id":7578865283,"lat":51.1288414,"lon":3.1904911},{"type":"node","id":7578960079,"lat":51.1303025,"lon":3.1855669},{"type":"node","id":7578975012,"lat":51.1294792,"lon":3.1906231},{"type":"node","id":7578975015,"lat":51.1297374,"lon":3.1907018},{"type":"node","id":7578975016,"lat":51.1300451,"lon":3.1907679},{"type":"node","id":7578975018,"lat":51.1305785,"lon":3.186668},{"type":"node","id":7578975019,"lat":51.130956,"lon":3.1881852},{"type":"node","id":7578975021,"lat":51.1303082,"lon":3.1855908},{"type":"node","id":7578975026,"lat":51.1310167,"lon":3.1861981},{"type":"node","id":7578975027,"lat":51.1318642,"lon":3.1857905},{"type":"node","id":7578975040,"lat":51.1280348,"lon":3.1889503},{"type":"node","id":7578975044,"lat":51.1279308,"lon":3.1875031},{"type":"node","id":7578975046,"lat":51.1279329,"lon":3.1881992},{"type":"node","id":9167054157,"lat":51.1308023,"lon":3.1852517},{"type":"node","id":9274761591,"lat":51.1310994,"lon":3.1862668},{"type":"node","id":9274761592,"lat":51.1310643,"lon":3.1862655},{"type":"node","id":9274761593,"lat":51.1310386,"lon":3.1862393},{"type":"node","id":7578987418,"lat":51.128003,"lon":3.1959031},{"type":"node","id":7578987419,"lat":51.1282167,"lon":3.193723},{"type":"node","id":5745833239,"lat":51.1258572,"lon":3.1996713},{"type":"node","id":5745833240,"lat":51.1257519,"lon":3.1995939},{"type":"node","id":5745833241,"lat":51.1253365,"lon":3.1991234},{"type":"node","id":7578987410,"lat":51.1243814,"lon":3.1988516},{"type":"node","id":7578987411,"lat":51.1243992,"lon":3.1989686},{"type":"node","id":7578987412,"lat":51.1259883,"lon":3.1997074},{"type":"node","id":7578987415,"lat":51.1260745,"lon":3.1997142},{"type":"node","id":1590642829,"lat":51.1333867,"lon":3.2308055},{"type":"node","id":1590642832,"lat":51.1334371,"lon":3.2308262},{"type":"node","id":1590642849,"lat":51.1336392,"lon":3.2305316},{"type":"node","id":1590642858,"lat":51.133659,"lon":3.2303991},{"type":"node","id":1590642859,"lat":51.1336899,"lon":3.2305508},{"type":"node","id":1590642860,"lat":51.1337096,"lon":3.2304183},{"type":"node","id":1590642828,"lat":51.1333653,"lon":3.2309374},{"type":"node","id":1590642830,"lat":51.1334157,"lon":3.2309581},{"type":"node","id":3311835478,"lat":51.133195,"lon":3.2334351},{"type":"node","id":9316118530,"lat":51.1331607,"lon":3.2333604},{"type":"node","id":9316118531,"lat":51.1330927,"lon":3.2334241},{"type":"node","id":9316118532,"lat":51.1331767,"lon":3.233347},{"type":"node","id":9316118533,"lat":51.133147,"lon":3.2333808},{"type":"node","id":9316118534,"lat":51.1331302,"lon":3.2334006},{"type":"node","id":9316118535,"lat":51.1331127,"lon":3.2334144},{"type":"node","id":9316118536,"lat":51.1330784,"lon":3.2334281},{"type":"node","id":9316118540,"lat":51.1330946,"lon":3.2335103},{"type":"node","id":6579962064,"lat":51.1367061,"lon":3.1640546},{"type":"node","id":6579962065,"lat":51.1361156,"lon":3.1646435},{"type":"node","id":6579962066,"lat":51.1357413,"lon":3.1637334},{"type":"node","id":6579962067,"lat":51.1359511,"lon":3.1637408},{"type":"node","id":6579962068,"lat":51.1359389,"lon":3.1638093},{"type":"node","id":7546193219,"lat":51.1456739,"lon":3.1637073},{"type":"node","id":7546193220,"lat":51.1455706,"lon":3.1643444},{"type":"node","id":7546193221,"lat":51.1456623,"lon":3.1643821},{"type":"node","id":7546193222,"lat":51.1457656,"lon":3.1637451},{"type":"node","id":3359977305,"lat":51.1464982,"lon":3.1689911},{"type":"node","id":4042671969,"lat":51.1461398,"lon":3.169233},{"type":"node","id":7545532512,"lat":51.1463103,"lon":3.169498},{"type":"node","id":7545532513,"lat":51.1466008,"lon":3.1695349},{"type":"node","id":7545532514,"lat":51.1464331,"lon":3.16962},{"type":"node","id":8200275848,"lat":51.1409105,"lon":3.1800288},{"type":"node","id":8200275844,"lat":51.1416967,"lon":3.1797728},{"type":"node","id":8200275847,"lat":51.1411211,"lon":3.1805153},{"type":"node","id":8200275849,"lat":51.1417397,"lon":3.1802115},{"type":"node","id":8200275853,"lat":51.1417351,"lon":3.1801651},{"type":"node","id":111759500,"lat":51.1483444,"lon":3.1886487},{"type":"node","id":1169056712,"lat":51.1482974,"lon":3.1884805},{"type":"node","id":3325315226,"lat":51.147926,"lon":3.1887015},{"type":"node","id":3325315230,"lat":51.1479856,"lon":3.1889124},{"type":"node","id":3325315232,"lat":51.1480454,"lon":3.1891027},{"type":"node","id":3325315243,"lat":51.1483285,"lon":3.1885919},{"type":"node","id":3325315247,"lat":51.1484007,"lon":3.1888131},{"type":"node","id":5826810673,"lat":51.1512507,"lon":3.1914885},{"type":"node","id":5826810674,"lat":51.15126,"lon":3.1914533},{"type":"node","id":5826810675,"lat":51.1510883,"lon":3.1912776},{"type":"node","id":5826810676,"lat":51.151057,"lon":3.1912906},{"type":"node","id":5826810678,"lat":51.1509897,"lon":3.1911759},{"type":"node","id":5826810679,"lat":51.1510025,"lon":3.1911334},{"type":"node","id":5826810680,"lat":51.1509352,"lon":3.1908874},{"type":"node","id":5826810681,"lat":51.1509074,"lon":3.1908689},{"type":"node","id":5826811494,"lat":51.1512125,"lon":3.1911315},{"type":"node","id":5826811495,"lat":51.1512055,"lon":3.191187},{"type":"node","id":5826811496,"lat":51.151296,"lon":3.1914182},{"type":"node","id":5826811497,"lat":51.1513261,"lon":3.1914182},{"type":"node","id":5826811535,"lat":51.1517839,"lon":3.1959375},{"type":"node","id":5826811536,"lat":51.1518581,"lon":3.1959708},{"type":"node","id":5826811547,"lat":51.1515913,"lon":3.196115},{"type":"node","id":5826811548,"lat":51.1516307,"lon":3.1961465},{"type":"node","id":5826811549,"lat":51.1516435,"lon":3.1961076},{"type":"node","id":5826811550,"lat":51.1516087,"lon":3.1959541},{"type":"node","id":5826811551,"lat":51.1515437,"lon":3.1959024},{"type":"node","id":5826811559,"lat":51.1517896,"lon":3.1957717},{"type":"node","id":5826811560,"lat":51.1517417,"lon":3.1957528},{"type":"node","id":5826811561,"lat":51.1517365,"lon":3.1957872},{"type":"node","id":3325315395,"lat":51.1544187,"lon":3.1856685},{"type":"node","id":3325315397,"lat":51.1545358,"lon":3.1860117},{"type":"node","id":3930713426,"lat":51.1571474,"lon":3.1889324},{"type":"node","id":3930713429,"lat":51.1573669,"lon":3.1883265},{"type":"node","id":3930713430,"lat":51.1573202,"lon":3.1890776},{"type":"node","id":3930713435,"lat":51.1574561,"lon":3.1883916},{"type":"node","id":3930713437,"lat":51.1574971,"lon":3.1893349},{"type":"node","id":3930713438,"lat":51.1574907,"lon":3.1884223},{"type":"node","id":3930713440,"lat":51.1575693,"lon":3.1890951},{"type":"node","id":3930713442,"lat":51.1575932,"lon":3.1879961},{"type":"node","id":3930713446,"lat":51.1577118,"lon":3.1885611},{"type":"node","id":3930713447,"lat":51.157698,"lon":3.1894886},{"type":"node","id":3930713451,"lat":51.1577702,"lon":3.1892488},{"type":"node","id":3930713454,"lat":51.1577969,"lon":3.1882567},{"type":"node","id":4043782112,"lat":51.1549447,"lon":3.1864571},{"type":"node","id":5552466013,"lat":51.1545783,"lon":3.1874672},{"type":"node","id":5552466014,"lat":51.1543143,"lon":3.1873045},{"type":"node","id":5552466018,"lat":51.1545999,"lon":3.1873846},{"type":"node","id":5552466020,"lat":51.1548079,"lon":3.1868846},{"type":"node","id":5825400688,"lat":51.1549303,"lon":3.1867969},{"type":"node","id":5826811614,"lat":51.1572659,"lon":3.1885288},{"type":"node","id":6949357906,"lat":51.1572911,"lon":3.1915323},{"type":"node","id":6949357909,"lat":51.1573109,"lon":3.1914572},{"type":"node","id":6949357910,"lat":51.1574373,"lon":3.1913744},{"type":"node","id":6949357911,"lat":51.1574179,"lon":3.1914502},{"type":"node","id":6949357912,"lat":51.1575109,"lon":3.1915112},{"type":"node","id":6949357913,"lat":51.1575304,"lon":3.1914354},{"type":"node","id":6949357914,"lat":51.1574638,"lon":3.1912712},{"type":"node","id":6949357915,"lat":51.1574444,"lon":3.1913473},{"type":"node","id":6949357916,"lat":51.1575599,"lon":3.191423},{"type":"node","id":6949357917,"lat":51.1575803,"lon":3.1913473},{"type":"node","id":6949357918,"lat":51.157501,"lon":3.1911303},{"type":"node","id":6949357919,"lat":51.1574808,"lon":3.1912058},{"type":"node","id":6949357920,"lat":51.1577374,"lon":3.1913724},{"type":"node","id":6949357921,"lat":51.1577563,"lon":3.1912987},{"type":"node","id":6982605752,"lat":51.1574664,"lon":3.1885975},{"type":"node","id":6982605754,"lat":51.1574428,"lon":3.1885793},{"type":"node","id":6982605762,"lat":51.1576066,"lon":3.1884793},{"type":"node","id":6982605764,"lat":51.1576853,"lon":3.18854},{"type":"node","id":6982605766,"lat":51.1575125,"lon":3.1884502},{"type":"node","id":6982605767,"lat":51.1575959,"lon":3.1885145},{"type":"node","id":6982605769,"lat":51.1575152,"lon":3.1884412},{"type":"node","id":6982906542,"lat":51.1591649,"lon":3.1904238},{"type":"node","id":6982906543,"lat":51.1592937,"lon":3.1905221},{"type":"node","id":6982906544,"lat":51.1593438,"lon":3.1903659},{"type":"node","id":6982906545,"lat":51.1593158,"lon":3.1903453},{"type":"node","id":6982906546,"lat":51.1593351,"lon":3.1902852},{"type":"node","id":6982906547,"lat":51.1592385,"lon":3.1902052},{"type":"node","id":6997076562,"lat":51.1546633,"lon":3.1858333},{"type":"node","id":6997076563,"lat":51.1546293,"lon":3.1858642},{"type":"node","id":6997076564,"lat":51.154594,"lon":3.1856715},{"type":"node","id":6997076565,"lat":51.1546727,"lon":3.1859889},{"type":"node","id":6997076566,"lat":51.1545545,"lon":3.1860687},{"type":"node","id":6997076567,"lat":51.1543063,"lon":3.1869337},{"type":"node","id":6997096756,"lat":51.1547387,"lon":3.1868376},{"type":"node","id":6997096758,"lat":51.1546899,"lon":3.1870707},{"type":"node","id":6997096759,"lat":51.1546751,"lon":3.1870601},{"type":"node","id":7137343680,"lat":51.1558646,"lon":3.1876808},{"type":"node","id":7137343681,"lat":51.1558466,"lon":3.1877456},{"type":"node","id":7137343682,"lat":51.1555824,"lon":3.187559},{"type":"node","id":7137343683,"lat":51.1556004,"lon":3.1874941},{"type":"node","id":7137343684,"lat":51.1555549,"lon":3.1874612},{"type":"node","id":7137383185,"lat":51.1555369,"lon":3.1875268},{"type":"node","id":7137383186,"lat":51.1553925,"lon":3.1874261},{"type":"node","id":7137383187,"lat":51.1554105,"lon":3.1873604},{"type":"node","id":7519058287,"lat":51.1555296,"lon":3.1858152},{"type":"node","id":7519058288,"lat":51.1555027,"lon":3.1858752},{"type":"node","id":7519058289,"lat":51.1556329,"lon":3.1860234},{"type":"node","id":7519058290,"lat":51.1556597,"lon":3.1859634},{"type":"node","id":7519058291,"lat":51.1557039,"lon":3.1860155},{"type":"node","id":7519058292,"lat":51.1556789,"lon":3.1860736},{"type":"node","id":7519058293,"lat":51.1558105,"lon":3.1862177},{"type":"node","id":7519058294,"lat":51.1558355,"lon":3.1861597},{"type":"node","id":7519058295,"lat":51.1557209,"lon":3.185828},{"type":"node","id":7519058296,"lat":51.1556932,"lon":3.1858902},{"type":"node","id":7519058297,"lat":51.1558686,"lon":3.1860888},{"type":"node","id":7519058298,"lat":51.1558963,"lon":3.1860265},{"type":"node","id":7519058299,"lat":51.1555421,"lon":3.1856365},{"type":"node","id":7519058300,"lat":51.1555168,"lon":3.1856923},{"type":"node","id":7519058301,"lat":51.1556479,"lon":3.1858437},{"type":"node","id":7519058302,"lat":51.1556732,"lon":3.1857879},{"type":"node","id":150996092,"lat":51.1554945,"lon":3.1954639},{"type":"node","id":150996093,"lat":51.155531,"lon":3.1953168},{"type":"node","id":150996094,"lat":51.1554912,"lon":3.1943936},{"type":"node","id":150996095,"lat":51.155456,"lon":3.1942488},{"type":"node","id":150996097,"lat":51.155432,"lon":3.1942095},{"type":"node","id":150996098,"lat":51.155397,"lon":3.1941906},{"type":"node","id":150996099,"lat":51.1552938,"lon":3.1945134},{"type":"node","id":150996100,"lat":51.1552701,"lon":3.1949002},{"type":"node","id":150996101,"lat":51.1553901,"lon":3.1953415},{"type":"node","id":1015567837,"lat":51.1603457,"lon":3.1926746},{"type":"node","id":1015583939,"lat":51.1598982,"lon":3.1934595},{"type":"node","id":1659850846,"lat":51.1562462,"lon":3.1925019},{"type":"node","id":1811699776,"lat":51.1604859,"lon":3.1920734},{"type":"node","id":1811699777,"lat":51.1605587,"lon":3.1917984},{"type":"node","id":1817319289,"lat":51.1599853,"lon":3.1935159},{"type":"node","id":1817319290,"lat":51.1600476,"lon":3.1933385},{"type":"node","id":1817319291,"lat":51.1600745,"lon":3.1934309},{"type":"node","id":1817319292,"lat":51.1602073,"lon":3.1941751},{"type":"node","id":1817319293,"lat":51.160208,"lon":3.1941098},{"type":"node","id":1817319294,"lat":51.1602178,"lon":3.1935425},{"type":"node","id":1817319295,"lat":51.1602385,"lon":3.19297},{"type":"node","id":1817319296,"lat":51.1602972,"lon":3.1940248},{"type":"node","id":1817319297,"lat":51.1603313,"lon":3.193809},{"type":"node","id":1817319298,"lat":51.1603427,"lon":3.1930326},{"type":"node","id":1817319299,"lat":51.1603716,"lon":3.1940192},{"type":"node","id":1817319300,"lat":51.1603777,"lon":3.1946319},{"type":"node","id":1817319301,"lat":51.1604665,"lon":3.193304},{"type":"node","id":1817319302,"lat":51.1604758,"lon":3.1939077},{"type":"node","id":1817319303,"lat":51.1605421,"lon":3.194476},{"type":"node","id":1817319304,"lat":51.1606037,"lon":3.1933895},{"type":"node","id":1817320493,"lat":51.1604248,"lon":3.1927398},{"type":"node","id":1817320494,"lat":51.1604851,"lon":3.192495},{"type":"node","id":2451569392,"lat":51.1598651,"lon":3.1919974},{"type":"node","id":2451574741,"lat":51.1594995,"lon":3.1924908},{"type":"node","id":2451574742,"lat":51.1596217,"lon":3.1923259},{"type":"node","id":2451574743,"lat":51.1597161,"lon":3.1922023},{"type":"node","id":2451574744,"lat":51.1600391,"lon":3.1932123},{"type":"node","id":2451574745,"lat":51.1601904,"lon":3.192947},{"type":"node","id":2451574746,"lat":51.1603862,"lon":3.1925461},{"type":"node","id":2451574747,"lat":51.1604272,"lon":3.19257},{"type":"node","id":2451574748,"lat":51.1604837,"lon":3.1921535},{"type":"node","id":2451574749,"lat":51.1605266,"lon":3.1921769},{"type":"node","id":2451578121,"lat":51.159758,"lon":3.1921448},{"type":"node","id":5587844460,"lat":51.1562664,"lon":3.1919544},{"type":"node","id":5587844461,"lat":51.15612,"lon":3.1920681},{"type":"node","id":5587844462,"lat":51.1561808,"lon":3.1922614},{"type":"node","id":5599314384,"lat":51.1563882,"lon":3.1923707},{"type":"node","id":5599314385,"lat":51.1563587,"lon":3.1924465},{"type":"node","id":6754312541,"lat":51.154716,"lon":3.1952084},{"type":"node","id":6754312542,"lat":51.1547723,"lon":3.1953372},{"type":"node","id":6754312543,"lat":51.1548078,"lon":3.1952983},{"type":"node","id":6754312544,"lat":51.1547519,"lon":3.1951702},{"type":"node","id":6754312550,"lat":51.1555879,"lon":3.1950341},{"type":"node","id":6754312551,"lat":51.1556025,"lon":3.194956},{"type":"node","id":6754312552,"lat":51.1555664,"lon":3.1952408},{"type":"node","id":6754312553,"lat":51.1556188,"lon":3.1951751},{"type":"node","id":6754312554,"lat":51.1554565,"lon":3.195427},{"type":"node","id":6754312555,"lat":51.1552894,"lon":3.1950649},{"type":"node","id":6754312556,"lat":51.1553277,"lon":3.1951991},{"type":"node","id":6754312557,"lat":51.1552774,"lon":3.1947027},{"type":"node","id":6754312558,"lat":51.1553131,"lon":3.1943816},{"type":"node","id":6754312559,"lat":51.1553397,"lon":3.1942577},{"type":"node","id":6754312560,"lat":51.1553697,"lon":3.1942084},{"type":"node","id":6754312562,"lat":51.1548064,"lon":3.1954209},{"type":"node","id":6754312563,"lat":51.1548266,"lon":3.1954893},{"type":"node","id":6754312564,"lat":51.1550417,"lon":3.1953175},{"type":"node","id":6754312565,"lat":51.1550193,"lon":3.1952538},{"type":"node","id":6870850178,"lat":51.1561935,"lon":3.1923019},{"type":"node","id":6870863414,"lat":51.1562489,"lon":3.1919675},{"type":"node","id":6949357907,"lat":51.1575239,"lon":3.1916859},{"type":"node","id":6949357908,"lat":51.1575439,"lon":3.1916101},{"type":"node","id":1448421081,"lat":51.167491,"lon":3.1713256},{"type":"node","id":1448421091,"lat":51.1677042,"lon":3.1714548},{"type":"node","id":1448421093,"lat":51.1677455,"lon":3.1702529},{"type":"node","id":1448421099,"lat":51.1679647,"lon":3.1703977},{"type":"node","id":6536026850,"lat":51.1711159,"lon":3.1669401},{"type":"node","id":6536026851,"lat":51.1712692,"lon":3.167296},{"type":"node","id":6536026852,"lat":51.1711296,"lon":3.1674712},{"type":"node","id":6536026853,"lat":51.1709602,"lon":3.1671189},{"type":"node","id":6536038234,"lat":51.1711913,"lon":3.165543},{"type":"node","id":6536038235,"lat":51.1711301,"lon":3.1656263},{"type":"node","id":6536038236,"lat":51.1712318,"lon":3.1658161},{"type":"node","id":6536038237,"lat":51.171293,"lon":3.1657327},{"type":"node","id":1038583451,"lat":51.1625071,"lon":3.191602},{"type":"node","id":4044171936,"lat":51.1609177,"lon":3.1911926},{"type":"node","id":4044171941,"lat":51.1609801,"lon":3.191229},{"type":"node","id":4044171963,"lat":51.1611962,"lon":3.1913534},{"type":"node","id":903903386,"lat":51.1618084,"lon":3.1932127},{"type":"node","id":903903387,"lat":51.1623536,"lon":3.1936011},{"type":"node","id":903903388,"lat":51.1624429,"lon":3.1931156},{"type":"node","id":903903390,"lat":51.1618641,"lon":3.1930197},{"type":"node","id":903904576,"lat":51.1618211,"lon":3.1931711},{"type":"node","id":1038557012,"lat":51.16155,"lon":3.1931121},{"type":"node","id":1038557014,"lat":51.1613774,"lon":3.1930711},{"type":"node","id":1038557035,"lat":51.1615349,"lon":3.1931712},{"type":"node","id":1038557072,"lat":51.1616138,"lon":3.1927483},{"type":"node","id":1038557075,"lat":51.162286,"lon":3.1935989},{"type":"node","id":1038557078,"lat":51.1616517,"lon":3.1928439},{"type":"node","id":1038557083,"lat":51.1616055,"lon":3.1930249},{"type":"node","id":1038557094,"lat":51.1618993,"lon":3.193299},{"type":"node","id":1038557102,"lat":51.1613235,"lon":3.1927138},{"type":"node","id":1038557104,"lat":51.1615987,"lon":3.1928077},{"type":"node","id":1038557108,"lat":51.1615113,"lon":3.1926816},{"type":"node","id":1038557137,"lat":51.1608873,"lon":3.1924416},{"type":"node","id":1038557143,"lat":51.1622248,"lon":3.193662},{"type":"node","id":1038557191,"lat":51.1608171,"lon":3.1926951},{"type":"node","id":1038557195,"lat":51.162409,"lon":3.1933428},{"type":"node","id":1038557227,"lat":51.1613767,"lon":3.1925113},{"type":"node","id":1038557230,"lat":51.1615281,"lon":3.1926132},{"type":"node","id":1038557233,"lat":51.1619765,"lon":3.1933723},{"type":"node","id":1038575040,"lat":51.1608523,"lon":3.1925679},{"type":"node","id":1038583375,"lat":51.1625113,"lon":3.1926776},{"type":"node","id":1038583398,"lat":51.1624305,"lon":3.1925743},{"type":"node","id":1038583404,"lat":51.1627055,"lon":3.191826},{"type":"node","id":1038583425,"lat":51.1624272,"lon":3.1916637},{"type":"node","id":1038583441,"lat":51.1621479,"lon":3.1921546},{"type":"node","id":1038583446,"lat":51.1622018,"lon":3.1921814},{"type":"node","id":1038583456,"lat":51.162174,"lon":3.1922806},{"type":"node","id":1038583459,"lat":51.162259,"lon":3.1924885},{"type":"node","id":1038583463,"lat":51.162661,"lon":3.1917442},{"type":"node","id":1038583476,"lat":51.1626425,"lon":3.1918448},{"type":"node","id":1038583479,"lat":51.1624196,"lon":3.1926561},{"type":"node","id":1038583483,"lat":51.1625037,"lon":3.1927232},{"type":"node","id":1038583491,"lat":51.1625701,"lon":3.1926387},{"type":"node","id":1038583501,"lat":51.1624928,"lon":3.1917013},{"type":"node","id":1811673418,"lat":51.1618484,"lon":3.1950253},{"type":"node","id":1811673421,"lat":51.1619875,"lon":3.1951427},{"type":"node","id":1811673423,"lat":51.162144,"lon":3.193835},{"type":"node","id":1811673425,"lat":51.1622452,"lon":3.1939149},{"type":"node","id":1811699778,"lat":51.1608187,"lon":3.1922973},{"type":"node","id":1811699779,"lat":51.1608915,"lon":3.1920223},{"type":"node","id":1817320495,"lat":51.1607269,"lon":3.192929},{"type":"node","id":1817320496,"lat":51.1607872,"lon":3.1926841},{"type":"node","id":1817324488,"lat":51.1615575,"lon":3.1921423},{"type":"node","id":1817324489,"lat":51.1612682,"lon":3.1920196},{"type":"node","id":1817324491,"lat":51.1617501,"lon":3.1918468},{"type":"node","id":1817324505,"lat":51.1618272,"lon":3.1921231},{"type":"node","id":1817324509,"lat":51.1618658,"lon":3.191793},{"type":"node","id":1817324513,"lat":51.1619814,"lon":3.1920002},{"type":"node","id":1817324515,"lat":51.161985,"lon":3.191793},{"type":"node","id":3550860268,"lat":51.1617349,"lon":3.1921922},{"type":"node","id":3550860269,"lat":51.1619403,"lon":3.1920686},{"type":"node","id":4044171924,"lat":51.1608199,"lon":3.1916126},{"type":"node","id":4044171954,"lat":51.1610853,"lon":3.191781},{"type":"node","id":4044171957,"lat":51.1611433,"lon":3.1918701},{"type":"node","id":4044171962,"lat":51.1611926,"lon":3.1916807},{"type":"node","id":4044171976,"lat":51.1612826,"lon":3.1919582},{"type":"node","id":4044171997,"lat":51.1613568,"lon":3.1917787},{"type":"node","id":4044172003,"lat":51.1613248,"lon":3.1919027},{"type":"node","id":4044172008,"lat":51.1614345,"lon":3.1919767},{"type":"node","id":6397031888,"lat":51.1615029,"lon":3.1919851},{"type":"node","id":6960473080,"lat":51.1614227,"lon":3.1931004},{"type":"node","id":3335137692,"lat":51.1698302,"lon":3.1965654},{"type":"node","id":3335137795,"lat":51.1698788,"lon":3.1970728},{"type":"node","id":3335137802,"lat":51.1700082,"lon":3.1971734},{"type":"node","id":3335137807,"lat":51.1701139,"lon":3.1965001},{"type":"node","id":3335137812,"lat":51.1703247,"lon":3.197352},{"type":"node","id":3335137823,"lat":51.1703133,"lon":3.1966232},{"type":"node","id":6255587427,"lat":51.1694775,"lon":3.1980047},{"type":"node","id":9163486855,"lat":51.1703854,"lon":3.1970901},{"type":"node","id":9163486856,"lat":51.1702114,"lon":3.1969688},{"type":"node","id":9163493632,"lat":51.1699473,"lon":3.197063},{"type":"node","id":414025563,"lat":51.1768198,"lon":3.1839265},{"type":"node","id":2325437840,"lat":51.1765747,"lon":3.1839745},{"type":"node","id":2325437844,"lat":51.1768286,"lon":3.1825946},{"type":"node","id":8191691970,"lat":51.1767611,"lon":3.1839766},{"type":"node","id":8191691971,"lat":51.1767812,"lon":3.1826167},{"type":"node","id":8191691972,"lat":51.1765804,"lon":3.1826583},{"type":"node","id":8191691973,"lat":51.1766324,"lon":3.182616},{"type":"node","id":5716136617,"lat":51.1773127,"lon":3.1969033},{"type":"node","id":5716136618,"lat":51.1771859,"lon":3.1969078},{"type":"node","id":5716136619,"lat":51.177203,"lon":3.1981369},{"type":"node","id":5716136620,"lat":51.1773298,"lon":3.1981324},{"type":"node","id":6004375826,"lat":51.1786839,"lon":3.1952389},{"type":"node","id":6625037999,"lat":51.1788016,"lon":3.1950645},{"type":"node","id":6625038000,"lat":51.1789916,"lon":3.1966631},{"type":"node","id":6625038001,"lat":51.1789003,"lon":3.1966838},{"type":"node","id":6625038002,"lat":51.1788554,"lon":3.1963547},{"type":"node","id":6625038003,"lat":51.1788165,"lon":3.1963622},{"type":"node","id":6625038005,"lat":51.1785124,"lon":3.1952362},{"type":"node","id":6625038006,"lat":51.1784779,"lon":3.1950618},{"type":"node","id":6925536539,"lat":51.1522475,"lon":3.1985416},{"type":"node","id":6925536540,"lat":51.1522635,"lon":3.1986187},{"type":"node","id":6925536541,"lat":51.1523922,"lon":3.1985517},{"type":"node","id":6925536542,"lat":51.1523766,"lon":3.1984746},{"type":"node","id":1637742821,"lat":51.158524,"lon":3.199021},{"type":"node","id":5586765933,"lat":51.1566667,"lon":3.2008881},{"type":"node","id":5586765934,"lat":51.1564286,"lon":3.2012575},{"type":"node","id":5586765935,"lat":51.1562496,"lon":3.2008579},{"type":"node","id":5586765936,"lat":51.1564982,"lon":3.200522},{"type":"node","id":6943148197,"lat":51.1581916,"lon":3.1989071},{"type":"node","id":6943148198,"lat":51.1582377,"lon":3.1989899},{"type":"node","id":6943148199,"lat":51.1581859,"lon":3.1990728},{"type":"node","id":6943148200,"lat":51.1583257,"lon":3.199295},{"type":"node","id":6943148201,"lat":51.1583563,"lon":3.199246},{"type":"node","id":6943148202,"lat":51.1583988,"lon":3.1993135},{"type":"node","id":6943148203,"lat":51.1585529,"lon":3.1990669},{"type":"node","id":6943148204,"lat":51.1586554,"lon":3.1988109},{"type":"node","id":6943148205,"lat":51.1585617,"lon":3.1986619},{"type":"node","id":6943148206,"lat":51.1586782,"lon":3.1984755},{"type":"node","id":6943148207,"lat":51.1585692,"lon":3.1982996},{"type":"node","id":8065883225,"lat":51.1366029,"lon":3.233506},{"type":"node","id":8065883226,"lat":51.1364627,"lon":3.2335338},{"type":"node","id":8065883227,"lat":51.1363922,"lon":3.2326314},{"type":"node","id":8065883228,"lat":51.1365324,"lon":3.2326036},{"type":"node","id":8065883229,"lat":51.1374344,"lon":3.2333338},{"type":"node","id":8065883230,"lat":51.1373632,"lon":3.2324534},{"type":"node","id":8065883232,"lat":51.1375819,"lon":3.2333035},{"type":"node","id":8065883233,"lat":51.1375107,"lon":3.232423},{"type":"node","id":1795793393,"lat":51.1475704,"lon":3.233832},{"type":"node","id":3346575840,"lat":51.146485,"lon":3.2349284},{"type":"node","id":3346575846,"lat":51.1465127,"lon":3.2355341},{"type":"node","id":3346575853,"lat":51.1466617,"lon":3.2349708},{"type":"node","id":3346575855,"lat":51.1466787,"lon":3.2355171},{"type":"node","id":3346575858,"lat":51.1466968,"lon":3.2342532},{"type":"node","id":3346575865,"lat":51.1468756,"lon":3.2344143},{"type":"node","id":3346575873,"lat":51.1469706,"lon":3.2366779},{"type":"node","id":3346575929,"lat":51.1474307,"lon":3.2366434},{"type":"node","id":1523513488,"lat":51.1398248,"lon":3.2392608},{"type":"node","id":1744641292,"lat":51.1395814,"lon":3.2390365},{"type":"node","id":1744641293,"lat":51.1397822,"lon":3.2393867},{"type":"node","id":1920143232,"lat":51.1394724,"lon":3.2390121},{"type":"node","id":7393009684,"lat":51.1394307,"lon":3.2390001},{"type":"node","id":7393048385,"lat":51.1394135,"lon":3.2390524},{"type":"node","id":3346575843,"lat":51.1465041,"lon":3.2376453},{"type":"node","id":3346575845,"lat":51.146508,"lon":3.2378517},{"type":"node","id":3346575876,"lat":51.1470052,"lon":3.237604},{"type":"node","id":3346575886,"lat":51.147098,"lon":3.2412975},{"type":"node","id":3346575889,"lat":51.1471585,"lon":3.2428761},{"type":"node","id":3346575891,"lat":51.1471715,"lon":3.2377865},{"type":"node","id":3346575901,"lat":51.1472492,"lon":3.2398591},{"type":"node","id":3346575903,"lat":51.1472654,"lon":3.242623},{"type":"node","id":3346575908,"lat":51.1472751,"lon":3.2428571},{"type":"node","id":3346575917,"lat":51.1473518,"lon":3.2426093},{"type":"node","id":3346575923,"lat":51.1473906,"lon":3.2398205},{"type":"node","id":3346575925,"lat":51.147408,"lon":3.2424474},{"type":"node","id":3346575928,"lat":51.1474263,"lon":3.24062},{"type":"node","id":3346575933,"lat":51.1474728,"lon":3.2421565},{"type":"node","id":3346575943,"lat":51.1475354,"lon":3.2418174},{"type":"node","id":3346575945,"lat":51.1475494,"lon":3.2412786},{"type":"node","id":3346575946,"lat":51.1475667,"lon":3.2415454},{"type":"node","id":6291339815,"lat":51.1434669,"lon":3.2496811},{"type":"node","id":6291339816,"lat":51.1434103,"lon":3.2497287},{"type":"node","id":6291339821,"lat":51.1435685,"lon":3.2496576},{"type":"node","id":6291339822,"lat":51.1434825,"lon":3.2497283},{"type":"node","id":6291339827,"lat":51.1437401,"lon":3.2490327},{"type":"node","id":6291339828,"lat":51.1433037,"lon":3.2494123},{"type":"node","id":6291339829,"lat":51.1436099,"lon":3.2497855},{"type":"node","id":6291339830,"lat":51.1439041,"lon":3.249535},{"type":"node","id":170464837,"lat":51.1533286,"lon":3.236239},{"type":"node","id":170464839,"lat":51.1532379,"lon":3.2364578},{"type":"node","id":1710262731,"lat":51.1513274,"lon":3.2373199},{"type":"node","id":1710262732,"lat":51.1508759,"lon":3.2370371},{"type":"node","id":1710262733,"lat":51.1509316,"lon":3.2370599},{"type":"node","id":1710262735,"lat":51.1510166,"lon":3.2370123},{"type":"node","id":1710262738,"lat":51.1512751,"lon":3.2372984},{"type":"node","id":1710262742,"lat":51.1513127,"lon":3.237065},{"type":"node","id":1710262743,"lat":51.1508201,"lon":3.2373832},{"type":"node","id":1710262745,"lat":51.151027,"lon":3.2369479},{"type":"node","id":1795793395,"lat":51.1476158,"lon":3.2338163},{"type":"node","id":1795793397,"lat":51.1475842,"lon":3.2344427},{"type":"node","id":1795793399,"lat":51.1477641,"lon":3.233033},{"type":"node","id":1795793405,"lat":51.1477717,"lon":3.2338665},{"type":"node","id":1795793406,"lat":51.1480775,"lon":3.2344787},{"type":"node","id":1795793407,"lat":51.1478893,"lon":3.2344203},{"type":"node","id":1795793408,"lat":51.1481719,"lon":3.2342485},{"type":"node","id":1795793409,"lat":51.147607,"lon":3.2330256},{"type":"node","id":4979389763,"lat":51.1476223,"lon":3.2330288},{"type":"node","id":8179735224,"lat":51.156047,"lon":3.2252534},{"type":"node","id":8179735264,"lat":51.1560464,"lon":3.2252785},{"type":"node","id":8179735265,"lat":51.1558544,"lon":3.2252597},{"type":"node","id":8179735266,"lat":51.1556789,"lon":3.2252522},{"type":"node","id":8179735267,"lat":51.1555253,"lon":3.2252547},{"type":"node","id":8179735268,"lat":51.1555747,"lon":3.2250024},{"type":"node","id":8179735269,"lat":51.1560527,"lon":3.2250198},{"type":"node","id":1525460846,"lat":51.1550489,"lon":3.2347709},{"type":"node","id":1810326044,"lat":51.1547625,"lon":3.2355098},{"type":"node","id":1810326087,"lat":51.1547809,"lon":3.2353708},{"type":"node","id":4912203160,"lat":51.1554941,"lon":3.2364781},{"type":"node","id":4912203161,"lat":51.1554192,"lon":3.2369649},{"type":"node","id":4912203162,"lat":51.1554175,"lon":3.2371071},{"type":"node","id":4912203163,"lat":51.1554301,"lon":3.2372063},{"type":"node","id":4912203164,"lat":51.1553847,"lon":3.2372197},{"type":"node","id":4912203165,"lat":51.1553763,"lon":3.2369502},{"type":"node","id":4912203166,"lat":51.1554512,"lon":3.236462},{"type":"node","id":4912203167,"lat":51.1555218,"lon":3.2366455},{"type":"node","id":4912203168,"lat":51.1554742,"lon":3.2369592},{"type":"node","id":4912203169,"lat":51.155516,"lon":3.2369752},{"type":"node","id":4912203170,"lat":51.1555635,"lon":3.2366616},{"type":"node","id":4912203171,"lat":51.1556125,"lon":3.2360775},{"type":"node","id":4912203172,"lat":51.155547,"lon":3.2364923},{"type":"node","id":4912203173,"lat":51.1555893,"lon":3.2365092},{"type":"node","id":4912203174,"lat":51.1556547,"lon":3.2360945},{"type":"node","id":4912203176,"lat":51.1554841,"lon":3.2362949},{"type":"node","id":4912203177,"lat":51.1553752,"lon":3.2362591},{"type":"node","id":4912203178,"lat":51.1553968,"lon":3.2360924},{"type":"node","id":4912203179,"lat":51.1555056,"lon":3.2361281},{"type":"node","id":4912214680,"lat":51.1553544,"lon":3.2348128},{"type":"node","id":4912214681,"lat":51.1550186,"lon":3.2346814},{"type":"node","id":4912214685,"lat":51.1554486,"lon":3.2338965},{"type":"node","id":4912214686,"lat":51.1550098,"lon":3.2346405},{"type":"node","id":4912214692,"lat":51.155386,"lon":3.2347722},{"type":"node","id":4912214693,"lat":51.1555155,"lon":3.2338415},{"type":"node","id":4912214694,"lat":51.1554587,"lon":3.2338214},{"type":"node","id":4912214695,"lat":51.1553292,"lon":3.2347521},{"type":"node","id":4912225050,"lat":51.1553136,"lon":3.234866},{"type":"node","id":4912225051,"lat":51.1551036,"lon":3.2337751},{"type":"node","id":4912225052,"lat":51.1549825,"lon":3.2346307},{"type":"node","id":4912225053,"lat":51.1551894,"lon":3.2336789},{"type":"node","id":4912225062,"lat":51.1551528,"lon":3.233747},{"type":"node","id":4912225063,"lat":51.1551831,"lon":3.2337249},{"type":"node","id":4912225064,"lat":51.1554653,"lon":3.2337755},{"type":"node","id":4912225067,"lat":51.1551309,"lon":3.2337849},{"type":"node","id":4912225068,"lat":51.1551727,"lon":3.2337999},{"type":"node","id":4912225069,"lat":51.1553182,"lon":3.2348322},{"type":"node","id":4912225070,"lat":51.1550516,"lon":3.2346556},{"type":"node","id":5972179331,"lat":51.154488,"lon":3.2350802},{"type":"node","id":5972179343,"lat":51.1545781,"lon":3.2351138},{"type":"node","id":5972179344,"lat":51.1546444,"lon":3.2351409},{"type":"node","id":5972179345,"lat":51.1546431,"lon":3.2351485},{"type":"node","id":5972179346,"lat":51.1547126,"lon":3.2351739},{"type":"node","id":5972179347,"lat":51.154714,"lon":3.2351659},{"type":"node","id":5972179348,"lat":51.1547795,"lon":3.235188},{"type":"node","id":5974489614,"lat":51.1546386,"lon":3.2355125},{"type":"node","id":5974489615,"lat":51.1544914,"lon":3.2353516},{"type":"node","id":5974489616,"lat":51.1544813,"lon":3.2351384},{"type":"node","id":5974489617,"lat":51.1548024,"lon":3.2352003},{"type":"node","id":5974489618,"lat":51.154732,"lon":3.2356091},{"type":"node","id":7529417225,"lat":51.159095,"lon":3.2366844},{"type":"node","id":7529417226,"lat":51.1589926,"lon":3.2372825},{"type":"node","id":7529417227,"lat":51.1588687,"lon":3.2372286},{"type":"node","id":7529417228,"lat":51.1589264,"lon":3.2368918},{"type":"node","id":7529417229,"lat":51.1588879,"lon":3.236875},{"type":"node","id":7529417230,"lat":51.1589326,"lon":3.2366138},{"type":"node","id":7529417232,"lat":51.159019,"lon":3.2366513},{"type":"node","id":170464840,"lat":51.1531619,"lon":3.2376814},{"type":"node","id":170464841,"lat":51.1532306,"lon":3.2376888},{"type":"node","id":1710245701,"lat":51.1528676,"lon":3.2390068},{"type":"node","id":1710245703,"lat":51.1527703,"lon":3.239403},{"type":"node","id":1710245705,"lat":51.1527888,"lon":3.2390966},{"type":"node","id":1710245707,"lat":51.1526357,"lon":3.2390543},{"type":"node","id":1710245709,"lat":51.1528763,"lon":3.2390382},{"type":"node","id":1710245711,"lat":51.1528928,"lon":3.2390631},{"type":"node","id":1710245713,"lat":51.1528729,"lon":3.2389738},{"type":"node","id":1710245715,"lat":51.1528645,"lon":3.2394083},{"type":"node","id":1710245718,"lat":51.1526407,"lon":3.2389524},{"type":"node","id":1710262736,"lat":51.1512857,"lon":3.2375783},{"type":"node","id":1710262737,"lat":51.151234,"lon":3.2375571},{"type":"node","id":1710262739,"lat":51.151183,"lon":3.2375939},{"type":"node","id":1710262741,"lat":51.1511924,"lon":3.2375358},{"type":"node","id":1710262744,"lat":51.1512252,"lon":3.2376112},{"type":"node","id":3346575950,"lat":51.1475926,"lon":3.2406028},{"type":"node","id":1728421374,"lat":51.1554436,"lon":3.2438233},{"type":"node","id":1728421375,"lat":51.15594,"lon":3.2438649},{"type":"node","id":1728421377,"lat":51.15559,"lon":3.2439695},{"type":"node","id":1728421379,"lat":51.1554335,"lon":3.243944},{"type":"node","id":1770289505,"lat":51.1565437,"lon":3.2437924},{"type":"node","id":4912197362,"lat":51.1565535,"lon":3.2438327},{"type":"node","id":4912197363,"lat":51.1562818,"lon":3.2438374},{"type":"node","id":4912197364,"lat":51.1565321,"lon":3.2435757},{"type":"node","id":4912197365,"lat":51.1565279,"lon":3.2433181},{"type":"node","id":4912197366,"lat":51.1562804,"lon":3.2435833},{"type":"node","id":4912197367,"lat":51.1562798,"lon":3.2431702},{"type":"node","id":4912197368,"lat":51.1562813,"lon":3.2437497},{"type":"node","id":4912197369,"lat":51.1562802,"lon":3.243488},{"type":"node","id":4912197370,"lat":51.1565257,"lon":3.2431702},{"type":"node","id":4912197371,"lat":51.1565542,"lon":3.2439044},{"type":"node","id":4912197372,"lat":51.1565308,"lon":3.2437482},{"type":"node","id":4912197373,"lat":51.1565294,"lon":3.2434893},{"type":"node","id":4912197374,"lat":51.1562835,"lon":3.2439005},{"type":"node","id":1710276232,"lat":51.1572435,"lon":3.2451269},{"type":"node","id":1710276240,"lat":51.156984,"lon":3.2453481},{"type":"node","id":1710276242,"lat":51.1567167,"lon":3.2452913},{"type":"node","id":1710276243,"lat":51.1570484,"lon":3.2451},{"type":"node","id":1710276251,"lat":51.1562241,"lon":3.2457572},{"type":"node","id":1710276253,"lat":51.156868,"lon":3.2451689},{"type":"node","id":1710276255,"lat":51.1563873,"lon":3.2456553},{"type":"node","id":1710276257,"lat":51.1572402,"lon":3.2450303},{"type":"node","id":1710276259,"lat":51.1561703,"lon":3.2454299},{"type":"node","id":1710276261,"lat":51.1564411,"lon":3.2457304},{"type":"node","id":1728421376,"lat":51.1555858,"lon":3.2441572},{"type":"node","id":1728421378,"lat":51.1559348,"lon":3.2441264},{"type":"node","id":1810330766,"lat":51.1562599,"lon":3.2457349},{"type":"node","id":1810345944,"lat":51.1572859,"lon":3.2458614},{"type":"node","id":1810345947,"lat":51.1568366,"lon":3.2461909},{"type":"node","id":1810345951,"lat":51.1572074,"lon":3.2455895},{"type":"node","id":1810345955,"lat":51.1567582,"lon":3.245919},{"type":"node","id":1810347217,"lat":51.1568783,"lon":3.2452387},{"type":"node","id":6255587424,"lat":51.1699788,"lon":3.1988617},{"type":"node","id":6255587425,"lat":51.1695322,"lon":3.1995447},{"type":"node","id":6255587426,"lat":51.1690026,"lon":3.1986489},{"type":"node","id":5173881316,"lat":51.1728811,"lon":3.210692},{"type":"node","id":5173881317,"lat":51.1728829,"lon":3.21077},{"type":"node","id":5173881318,"lat":51.1726197,"lon":3.2107914},{"type":"node","id":5173881320,"lat":51.1728794,"lon":3.2108575},{"type":"node","id":5173881621,"lat":51.1728791,"lon":3.2109364},{"type":"node","id":5173881622,"lat":51.1727133,"lon":3.2109488},{"type":"node","id":5173881623,"lat":51.1727117,"lon":3.2108703},{"type":"node","id":5173881624,"lat":51.1728613,"lon":3.211069},{"type":"node","id":5173881625,"lat":51.1728601,"lon":3.2111406},{"type":"node","id":5173881626,"lat":51.1727019,"lon":3.2111316},{"type":"node","id":5173881627,"lat":51.1727041,"lon":3.2110597},{"type":"node","id":6275462772,"lat":51.1733576,"lon":3.2110928},{"type":"node","id":6275462773,"lat":51.1733528,"lon":3.2112295},{"type":"node","id":6275462774,"lat":51.1735278,"lon":3.2112449},{"type":"node","id":6275462775,"lat":51.1735325,"lon":3.2111082},{"type":"node","id":6275462776,"lat":51.1736659,"lon":3.2112568},{"type":"node","id":6275462777,"lat":51.1736113,"lon":3.2112529},{"type":"node","id":6275462784,"lat":51.1735598,"lon":3.2109277},{"type":"node","id":6275462985,"lat":51.1734626,"lon":3.2109229},{"type":"node","id":6275462986,"lat":51.1734599,"lon":3.2110592},{"type":"node","id":6275462987,"lat":51.1735572,"lon":3.211064},{"type":"node","id":6275462988,"lat":51.1734613,"lon":3.2109904},{"type":"node","id":6275462989,"lat":51.173357,"lon":3.2111476},{"type":"node","id":7054196467,"lat":51.1726209,"lon":3.2107131},{"type":"node","id":8042845810,"lat":51.1737696,"lon":3.206708},{"type":"node","id":8042845811,"lat":51.1734466,"lon":3.2056148},{"type":"node","id":5952389321,"lat":51.1668901,"lon":3.2166736},{"type":"node","id":5952389322,"lat":51.1664592,"lon":3.2166337},{"type":"node","id":5952389323,"lat":51.1659941,"lon":3.2166018},{"type":"node","id":5172938444,"lat":51.1667283,"lon":3.2192609},{"type":"node","id":5536609426,"lat":51.1664884,"lon":3.2184803},{"type":"node","id":5536620510,"lat":51.1668363,"lon":3.2197448},{"type":"node","id":5536620511,"lat":51.1671911,"lon":3.2210959},{"type":"node","id":5952389320,"lat":51.1665059,"lon":3.2183884},{"type":"node","id":5536620506,"lat":51.1675299,"lon":3.2170283},{"type":"node","id":5536620507,"lat":51.1672585,"lon":3.2168071},{"type":"node","id":6275462778,"lat":51.1736042,"lon":3.2115044},{"type":"node","id":6275462779,"lat":51.1736588,"lon":3.2115083},{"type":"node","id":6275462780,"lat":51.1735687,"lon":3.2112964},{"type":"node","id":6275462781,"lat":51.1735211,"lon":3.2112937},{"type":"node","id":6275462782,"lat":51.1735156,"lon":3.2115423},{"type":"node","id":6275462783,"lat":51.1735632,"lon":3.211545},{"type":"node","id":5536620505,"lat":51.1683944,"lon":3.2180288},{"type":"node","id":5536620512,"lat":51.1673641,"lon":3.2217199},{"type":"node","id":5536620513,"lat":51.1675007,"lon":3.2221772},{"type":"node","id":5536620514,"lat":51.1679104,"lon":3.2236675},{"type":"node","id":5536620516,"lat":51.1679955,"lon":3.224005},{"type":"node","id":5536620824,"lat":51.1700823,"lon":3.2236258},{"type":"node","id":5536620826,"lat":51.171324,"lon":3.2230929},{"type":"node","id":5536620827,"lat":51.1717731,"lon":3.2213846},{"type":"node","id":5536620828,"lat":51.170726,"lon":3.2202369},{"type":"node","id":5536620829,"lat":51.1706206,"lon":3.2201178},{"type":"node","id":5536620830,"lat":51.170049,"lon":3.2215441},{"type":"node","id":5536620831,"lat":51.1699442,"lon":3.2215294},{"type":"node","id":5536620832,"lat":51.1683757,"lon":3.2194636},{"type":"node","id":6067483781,"lat":51.1675243,"lon":3.222207},{"type":"node","id":6067483782,"lat":51.1713888,"lon":3.2231705},{"type":"node","id":7794736251,"lat":51.1688401,"lon":3.2184325},{"type":"node","id":1069177852,"lat":51.1789546,"lon":3.2021791},{"type":"node","id":1069177853,"lat":51.1801636,"lon":3.2031369},{"type":"node","id":1069177873,"lat":51.1791663,"lon":3.2034541},{"type":"node","id":1069177915,"lat":51.1799187,"lon":3.2029579},{"type":"node","id":1069177919,"lat":51.1786053,"lon":3.2030903},{"type":"node","id":1069177920,"lat":51.1790417,"lon":3.2033998},{"type":"node","id":1069177925,"lat":51.1788415,"lon":3.2032442},{"type":"node","id":1069177933,"lat":51.1798479,"lon":3.2029364},{"type":"node","id":1069177967,"lat":51.178467,"lon":3.2025563},{"type":"node","id":1069177976,"lat":51.1791427,"lon":3.2026954},{"type":"node","id":1069177984,"lat":51.1783718,"lon":3.2028231},{"type":"node","id":1069178021,"lat":51.1793534,"lon":3.2033094},{"type":"node","id":1069178133,"lat":51.1784113,"lon":3.2028156},{"type":"node","id":6853179202,"lat":51.1792037,"lon":3.2026994},{"type":"node","id":6853179203,"lat":51.1790601,"lon":3.2026755},{"type":"node","id":6853179204,"lat":51.1791861,"lon":3.2027108},{"type":"node","id":6853179205,"lat":51.1791741,"lon":3.2027122},{"type":"node","id":6853179206,"lat":51.1791634,"lon":3.2027102},{"type":"node","id":6853179207,"lat":51.1791526,"lon":3.2027048},{"type":"node","id":6853179208,"lat":51.1790128,"lon":3.202488},{"type":"node","id":6853179209,"lat":51.1790434,"lon":3.2026225},{"type":"node","id":6853179210,"lat":51.1789811,"lon":3.2023837},{"type":"node","id":6853179211,"lat":51.1789744,"lon":3.2022415},{"type":"node","id":6853179212,"lat":51.1789438,"lon":3.2022643},{"type":"node","id":6853179213,"lat":51.1784216,"lon":3.2028567},{"type":"node","id":6853179214,"lat":51.1784157,"lon":3.2028375},{"type":"node","id":6853179215,"lat":51.1784506,"lon":3.2029294},{"type":"node","id":6853179216,"lat":51.1783884,"lon":3.2026704},{"type":"node","id":6853179217,"lat":51.178422,"lon":3.2026034},{"type":"node","id":6853179218,"lat":51.1784117,"lon":3.2026185},{"type":"node","id":6853179219,"lat":51.1784021,"lon":3.2026354},{"type":"node","id":6853179220,"lat":51.1783957,"lon":3.2026505},{"type":"node","id":6853179221,"lat":51.178443,"lon":3.2025785},{"type":"node","id":6853179222,"lat":51.1784546,"lon":3.202567},{"type":"node","id":6853179223,"lat":51.1784321,"lon":3.2025906},{"type":"node","id":6853179224,"lat":51.1783719,"lon":3.2027464},{"type":"node","id":6853179225,"lat":51.1783749,"lon":3.2027238},{"type":"node","id":6853179226,"lat":51.1783827,"lon":3.2026894},{"type":"node","id":6853179227,"lat":51.1783784,"lon":3.2027066},{"type":"node","id":6853179228,"lat":51.1783697,"lon":3.2027864},{"type":"node","id":6853179229,"lat":51.1783704,"lon":3.2027651},{"type":"node","id":6853179230,"lat":51.1783703,"lon":3.2028048},{"type":"node","id":6853179234,"lat":51.1798837,"lon":3.2029379},{"type":"node","id":6853179235,"lat":51.1798988,"lon":3.2029445},{"type":"node","id":6853179236,"lat":51.1798661,"lon":3.2029354},{"type":"node","id":6853179237,"lat":51.1798345,"lon":3.2029407},{"type":"node","id":6853179238,"lat":51.1798207,"lon":3.2029479},{"type":"node","id":6853179239,"lat":51.1792634,"lon":3.2033377},{"type":"node","id":6853179240,"lat":51.1793019,"lon":3.2033359},{"type":"node","id":6853179241,"lat":51.1792828,"lon":3.20334},{"type":"node","id":6853179242,"lat":51.1792732,"lon":3.2033393},{"type":"node","id":6853179243,"lat":51.1792921,"lon":3.2033388},{"type":"node","id":6853179244,"lat":51.1793279,"lon":3.2033257},{"type":"node","id":6853179245,"lat":51.1793153,"lon":3.2033313},{"type":"node","id":6853179246,"lat":51.1793413,"lon":3.2033182},{"type":"node","id":6853179247,"lat":51.1792384,"lon":3.2033981},{"type":"node","id":6853179248,"lat":51.1792572,"lon":3.2033605},{"type":"node","id":6853179249,"lat":51.1792512,"lon":3.2033774},{"type":"node","id":6853179250,"lat":51.1792456,"lon":3.2033888},{"type":"node","id":6853179256,"lat":51.1790996,"lon":3.2034514},{"type":"node","id":6853179257,"lat":51.1790731,"lon":3.2034317},{"type":"node","id":6853179258,"lat":51.1790581,"lon":3.2034168},{"type":"node","id":6853179259,"lat":51.1790862,"lon":3.2034422},{"type":"node","id":6853179260,"lat":51.179133,"lon":3.2034648},{"type":"node","id":6853179261,"lat":51.1791191,"lon":3.203461},{"type":"node","id":6853179262,"lat":51.1791546,"lon":3.2034608},{"type":"node","id":6853179263,"lat":51.1791443,"lon":3.2034639},{"type":"node","id":6853179264,"lat":51.1789437,"lon":3.2033089},{"type":"node","id":6853179267,"lat":51.1785146,"lon":3.2030128},{"type":"node","id":6853179268,"lat":51.1785517,"lon":3.2030489},{"type":"node","id":6853179269,"lat":51.1785863,"lon":3.2030773},{"type":"node","id":6853179327,"lat":51.1789936,"lon":3.2024248},{"type":"node","id":7252820961,"lat":51.175521,"lon":3.2045972},{"type":"node","id":7252863798,"lat":51.1754304,"lon":3.2044959},{"type":"node","id":8042845806,"lat":51.1753353,"lon":3.2041851},{"type":"node","id":8042845807,"lat":51.175363,"lon":3.2043314},{"type":"node","id":8042845812,"lat":51.1752711,"lon":3.2040127},{"type":"node","id":4036885076,"lat":51.1740632,"lon":3.2050437},{"type":"node","id":4036899624,"lat":51.1767493,"lon":3.2082945},{"type":"node","id":5607796819,"lat":51.1782483,"lon":3.2091883},{"type":"node","id":5607796820,"lat":51.1785128,"lon":3.2086016},{"type":"node","id":5607798721,"lat":51.1786474,"lon":3.2090453},{"type":"node","id":5607798722,"lat":51.1782874,"lon":3.2093115},{"type":"node","id":5607798723,"lat":51.178141,"lon":3.2088491},{"type":"node","id":5607798725,"lat":51.1785713,"lon":3.2087945},{"type":"node","id":5728443539,"lat":51.1753294,"lon":3.2097039},{"type":"node","id":5728443540,"lat":51.1752216,"lon":3.2089278},{"type":"node","id":6275462768,"lat":51.174424,"lon":3.2105467},{"type":"node","id":6275462769,"lat":51.1743524,"lon":3.2105548},{"type":"node","id":6275462770,"lat":51.1743644,"lon":3.2108257},{"type":"node","id":6275462771,"lat":51.1744361,"lon":3.2108176},{"type":"node","id":7252820962,"lat":51.1756015,"lon":3.204854},{"type":"node","id":7252820963,"lat":51.1755802,"lon":3.204928},{"type":"node","id":7252820964,"lat":51.1755132,"lon":3.2049422},{"type":"node","id":7252820965,"lat":51.1754719,"lon":3.2050156},{"type":"node","id":7252820966,"lat":51.1754575,"lon":3.2051212},{"type":"node","id":7252820967,"lat":51.1755143,"lon":3.2052892},{"type":"node","id":7252820968,"lat":51.1755533,"lon":3.2055086},{"type":"node","id":7252820969,"lat":51.1755563,"lon":3.2060065},{"type":"node","id":7252820970,"lat":51.175491,"lon":3.2064409},{"type":"node","id":7252820971,"lat":51.1753674,"lon":3.2068348},{"type":"node","id":7252820972,"lat":51.1751944,"lon":3.2070531},{"type":"node","id":7252820973,"lat":51.1751195,"lon":3.2071478},{"type":"node","id":7252820974,"lat":51.1750834,"lon":3.2072467},{"type":"node","id":7252820975,"lat":51.1750963,"lon":3.2073579},{"type":"node","id":7252820976,"lat":51.1751376,"lon":3.2074032},{"type":"node","id":7252820977,"lat":51.175215,"lon":3.2073826},{"type":"node","id":7252820978,"lat":51.1752848,"lon":3.2073785},{"type":"node","id":7252820979,"lat":51.1754252,"lon":3.2073858},{"type":"node","id":7252820980,"lat":51.1754615,"lon":3.2074926},{"type":"node","id":7252820981,"lat":51.1754259,"lon":3.20756},{"type":"node","id":7252820982,"lat":51.17537,"lon":3.2076668},{"type":"node","id":7252820983,"lat":51.1753304,"lon":3.2078901},{"type":"node","id":7252820984,"lat":51.1753152,"lon":3.2079319},{"type":"node","id":7252874885,"lat":51.1754423,"lon":3.2080951},{"type":"node","id":7252874886,"lat":51.1754991,"lon":3.2083134},{"type":"node","id":7252874887,"lat":51.1755307,"lon":3.2084864},{"type":"node","id":7252874888,"lat":51.1755729,"lon":3.2087064},{"type":"node","id":7252874889,"lat":51.1753248,"lon":3.2088635},{"type":"node","id":7252874890,"lat":51.1752645,"lon":3.2092365},{"type":"node","id":7252874891,"lat":51.1747746,"lon":3.2093558},{"type":"node","id":8042845789,"lat":51.1748587,"lon":3.209526},{"type":"node","id":8042845790,"lat":51.1749489,"lon":3.2096774},{"type":"node","id":8042845791,"lat":51.1750595,"lon":3.2097458},{"type":"node","id":8042845792,"lat":51.1753557,"lon":3.2077924},{"type":"node","id":8042845793,"lat":51.1754621,"lon":3.2074425},{"type":"node","id":8042845794,"lat":51.1754531,"lon":3.2074092},{"type":"node","id":8042845795,"lat":51.1754729,"lon":3.2051839},{"type":"node","id":8042845796,"lat":51.1754907,"lon":3.2052089},{"type":"node","id":8042845797,"lat":51.1755084,"lon":3.2052355},{"type":"node","id":8042845798,"lat":51.1755235,"lon":3.2053482},{"type":"node","id":8042845799,"lat":51.1755387,"lon":3.2053805},{"type":"node","id":8042845800,"lat":51.1755584,"lon":3.2057251},{"type":"node","id":8042845801,"lat":51.1755536,"lon":3.205762},{"type":"node","id":8042845802,"lat":51.1755492,"lon":3.2061312},{"type":"node","id":8042845803,"lat":51.1755305,"lon":3.2062755},{"type":"node","id":8042845804,"lat":51.1754335,"lon":3.2066603},{"type":"node","id":8042845805,"lat":51.1755929,"lon":3.2047843},{"type":"node","id":8042845808,"lat":51.1746278,"lon":3.2090183},{"type":"node","id":8042845809,"lat":51.1740796,"lon":3.2076268},{"type":"node","id":8042845844,"lat":51.1768218,"lon":3.20861},{"type":"node","id":8042845845,"lat":51.1767935,"lon":3.2085031},{"type":"node","id":8042845846,"lat":51.1769413,"lon":3.2089936},{"type":"node","id":8042845847,"lat":51.1757541,"lon":3.2096988},{"type":"node","id":8042845848,"lat":51.1757421,"lon":3.2096812},{"type":"node","id":8042845849,"lat":51.1757312,"lon":3.2096924},{"type":"node","id":8042845850,"lat":51.1757202,"lon":3.2096478},{"type":"node","id":8042845851,"lat":51.1756902,"lon":3.2096207},{"type":"node","id":8042845852,"lat":51.1756712,"lon":3.2096143},{"type":"node","id":8042845853,"lat":51.1756602,"lon":3.2095745},{"type":"node","id":8042845854,"lat":51.1756552,"lon":3.2095537},{"type":"node","id":8042845855,"lat":51.1756657,"lon":3.2095174},{"type":"node","id":8042845856,"lat":51.175658,"lon":3.20908},{"type":"node","id":8042845857,"lat":51.1756525,"lon":3.2093366},{"type":"node","id":8042845858,"lat":51.1756466,"lon":3.2088282},{"type":"node","id":8042845859,"lat":51.1756582,"lon":3.2089151},{"type":"node","id":8042845860,"lat":51.1765521,"lon":3.20839},{"type":"node","id":1069177845,"lat":51.1809357,"lon":3.2035366},{"type":"node","id":1069177849,"lat":51.1803975,"lon":3.2017749},{"type":"node","id":1069178166,"lat":51.1804195,"lon":3.2033098},{"type":"node","id":1519342742,"lat":51.1805239,"lon":3.2032684},{"type":"node","id":1519342743,"lat":51.18064,"lon":3.2036951},{"type":"node","id":1759437085,"lat":51.1806986,"lon":3.2036647},{"type":"node","id":6852012577,"lat":51.1804541,"lon":3.2017867},{"type":"node","id":6852012578,"lat":51.1804124,"lon":3.2018177},{"type":"node","id":6852012579,"lat":51.1804106,"lon":3.2018165},{"type":"node","id":6852012580,"lat":51.1804143,"lon":3.2018177},{"type":"node","id":6852012581,"lat":51.1808363,"lon":3.2030295},{"type":"node","id":6852012582,"lat":51.1807955,"lon":3.2030595},{"type":"node","id":6852012583,"lat":51.180798,"lon":3.2030712},{"type":"node","id":1519476620,"lat":51.1786696,"lon":3.2199463},{"type":"node","id":1519476635,"lat":51.179306,"lon":3.2193119},{"type":"node","id":1519476698,"lat":51.1795485,"lon":3.2192221},{"type":"node","id":1519476744,"lat":51.1791125,"lon":3.2194529},{"type":"node","id":1519476746,"lat":51.178483,"lon":3.2203218},{"type":"node","id":1519476797,"lat":51.1788731,"lon":3.2196593},{"type":"node","id":3780611492,"lat":51.1761568,"lon":3.2238485},{"type":"node","id":3780611493,"lat":51.1762213,"lon":3.223901},{"type":"node","id":3780611494,"lat":51.1762626,"lon":3.2237172},{"type":"node","id":3780611495,"lat":51.1763208,"lon":3.2237628},{"type":"node","id":3780611496,"lat":51.1763248,"lon":3.2236414},{"type":"node","id":3780611497,"lat":51.1763881,"lon":3.2236926},{"type":"node","id":3780611498,"lat":51.1764876,"lon":3.2235544},{"type":"node","id":3780611499,"lat":51.1766551,"lon":3.2232337},{"type":"node","id":3780611500,"lat":51.176687,"lon":3.2231945},{"type":"node","id":3780611501,"lat":51.1767105,"lon":3.2232776},{"type":"node","id":3780611502,"lat":51.176751,"lon":3.2232465},{"type":"node","id":3780611503,"lat":51.1767812,"lon":3.2230729},{"type":"node","id":3780611504,"lat":51.1768505,"lon":3.2231083},{"type":"node","id":6533893620,"lat":51.178521,"lon":3.2203687},{"type":"node","id":6533893621,"lat":51.1786845,"lon":3.220025},{"type":"node","id":6533893622,"lat":51.1789011,"lon":3.2197183},{"type":"node","id":6533893624,"lat":51.1791343,"lon":3.2195235},{"type":"node","id":6533893625,"lat":51.1793269,"lon":3.2193854},{"type":"node","id":6533893626,"lat":51.1795596,"lon":3.219299},{"type":"node","id":5536620518,"lat":51.1683264,"lon":3.224863},{"type":"node","id":5536620519,"lat":51.1684352,"lon":3.2251117},{"type":"node","id":5536620520,"lat":51.1685675,"lon":3.2254022},{"type":"node","id":5536620821,"lat":51.1687379,"lon":3.2258223},{"type":"node","id":5536620822,"lat":51.1693682,"lon":3.2250177},{"type":"node","id":5536620823,"lat":51.1693734,"lon":3.225049},{"type":"node","id":5536620825,"lat":51.1707605,"lon":3.2244639},{"type":"node","id":5536620837,"lat":51.1697793,"lon":3.2260181},{"type":"node","id":5536620838,"lat":51.1699712,"lon":3.2262338},{"type":"node","id":5536620839,"lat":51.1701247,"lon":3.2263242},{"type":"node","id":5536620840,"lat":51.1704719,"lon":3.2266478},{"type":"node","id":5536620841,"lat":51.1701028,"lon":3.2281081},{"type":"node","id":5536620842,"lat":51.1698158,"lon":3.2276446},{"type":"node","id":5536620843,"lat":51.1696441,"lon":3.2273837},{"type":"node","id":5536620844,"lat":51.1695154,"lon":3.2272009},{"type":"node","id":5536620845,"lat":51.169536,"lon":3.2271664},{"type":"node","id":5536620846,"lat":51.1694515,"lon":3.2270181},{"type":"node","id":5635001306,"lat":51.1737078,"lon":3.2354437},{"type":"node","id":5635001371,"lat":51.1722128,"lon":3.2340273},{"type":"node","id":5635001372,"lat":51.1723921,"lon":3.2343394},{"type":"node","id":5635001373,"lat":51.1724213,"lon":3.2342967},{"type":"node","id":5635001374,"lat":51.1722421,"lon":3.2339846},{"type":"node","id":5635001375,"lat":51.1728995,"lon":3.2339319},{"type":"node","id":5635001376,"lat":51.1729253,"lon":3.2339922},{"type":"node","id":5635001377,"lat":51.1723583,"lon":3.2340816},{"type":"node","id":5635001378,"lat":51.1723268,"lon":3.2340173},{"type":"node","id":5635001379,"lat":51.172885,"lon":3.2337993},{"type":"node","id":5635001380,"lat":51.1728611,"lon":3.2338706},{"type":"node","id":5635001381,"lat":51.1723325,"lon":3.2339419},{"type":"node","id":5635001382,"lat":51.1723464,"lon":3.2338696},{"type":"node","id":5882873334,"lat":51.1736186,"lon":3.2330966},{"type":"node","id":5882873335,"lat":51.1735451,"lon":3.2327633},{"type":"node","id":5882873336,"lat":51.1737001,"lon":3.2327438},{"type":"node","id":5882873337,"lat":51.1736796,"lon":3.2318764},{"type":"node","id":5882873338,"lat":51.1735265,"lon":3.2318782},{"type":"node","id":6593340582,"lat":51.1727872,"lon":3.2328745},{"type":"node","id":6593340583,"lat":51.1728013,"lon":3.2332051},{"type":"node","id":6593340584,"lat":51.1736743,"lon":3.2331435},{"type":"node","id":7767137235,"lat":51.1735198,"lon":3.2355568},{"type":"node","id":7767137236,"lat":51.1735366,"lon":3.2355246},{"type":"node","id":7767137237,"lat":51.1735198,"lon":3.2356399},{"type":"node","id":5635001274,"lat":51.1751425,"lon":3.2346144},{"type":"node","id":5635001275,"lat":51.1751696,"lon":3.2347601},{"type":"node","id":5635001276,"lat":51.1750553,"lon":3.2348141},{"type":"node","id":5635001277,"lat":51.1750282,"lon":3.2346684},{"type":"node","id":5635001312,"lat":51.174002,"lon":3.2349367},{"type":"node","id":5635001383,"lat":51.1740709,"lon":3.233056},{"type":"node","id":5635001384,"lat":51.1740249,"lon":3.2330598},{"type":"node","id":5635001385,"lat":51.1740265,"lon":3.2331313},{"type":"node","id":5635001386,"lat":51.1740597,"lon":3.2327202},{"type":"node","id":5635001414,"lat":51.174281,"lon":3.2336147},{"type":"node","id":5635001415,"lat":51.174081,"lon":3.2338914},{"type":"node","id":5635001416,"lat":51.1740489,"lon":3.2338323},{"type":"node","id":5635001417,"lat":51.1742489,"lon":3.2335556},{"type":"node","id":5761770202,"lat":51.1783111,"lon":3.2342484},{"type":"node","id":5761770204,"lat":51.1782819,"lon":3.2339616},{"type":"node","id":7767137234,"lat":51.1739713,"lon":3.2348766},{"type":"node","id":9052878228,"lat":51.1781206,"lon":3.234323},{"type":"node","id":9052878229,"lat":51.1781054,"lon":3.2339448},{"type":"way","id":810604915,"nodes":[1168727824,9167054153,9274761589,9274761596,7577430793,1038638712,1038638723,1038638661,9199177059,1038638721,7554434436,7578975035,7554434438,7578865273,7578975032,7578975030,7578975029,1038638696,7578975009,7578975008,7578975007,1038638743,7578975002,7578974988,7578974989,7578974990,7578974991,7578974992,7578865275,7578865274,1038638753,7578974995,7578974996,7578974997,7578904489,7578974999,7578975000,7578975001,7578974998,3921878998,1038638592,929120698,1675648152,7578865281,7578865283,7578975012,7578975015,7578975016,3922380061,2732486274,3922380083,7578975019,7578975018,7578975021,7578960079,3922375256,7578975024,3922380071]},{"type":"way","id":989393316,"nodes":[3922380071,3922380081,3922380086,3922380092,3922380095,9167054157,7578975026,9274761593,9274761592,9274761591,7578975027,9167054156,9167054154,7578975049,7578975028,1168727824]},{"type":"way","id":389026405,"nodes":[3921879019,7578975044,3921879018,7578975046,7578975045,7578975040,3921879004,3921879011,3921879019]},{"type":"way","id":810607458,"nodes":[7578987409,7578987410,7578987411,5745833241,5745833240,5745833239,7578987412,7578987415,7578987413,7578987414,7578987417,7578987416,7578987418,7578987419,7578987409]},{"type":"way","id":777280458,"nodes":[8042845812,8042845806,8042845807,7252863798,7252820961,8042845805,7252820962,7252820963,7252820964,7252820965,7252820966,8042845795,8042845796,8042845797,7252820967,8042845798,8042845799,7252820968,8042845800,8042845801,7252820969,8042845802,8042845803,7252820970,8042845804,7252820971,7252820972,7252820973,7252820974,7252820975,7252820976,7252820977,7252820978,7252820979,8042845794,8042845793,7252820980,7252820981,7252820982,8042845792,7252820983,7252820984,7252874885,7252874886,7252874887,7252874888,7252874889,5728443540,7252874890,5728443539,8042845791,8042845790,8042845789,7252874891,8042845808,8042845809,8042845810,8042845811,4036885076,8042845812]},{"type":"way","id":577572397,"nodes":[5536620518,5536620519,5536620520,5536620821,5536620822,5536620823,5536620824,5536620825,5536620826,6067483782,5536620827,5536620828,5536620829,5536620830,5536620831,5536620832,7794736251,5536620505,5536620506,5536620507,5952389321,5952389322,5952389323,5536609426,5952389320,5172938444,5536620510,5536620511,5536620512,5536620513,6067483781,5536620514,5536620516,5536620518]},{"type":"way","id":863373849,"nodes":[4036899624,8042845845,8042845844,8042845846,8042845847,8042845848,8042845849,8042845850,8042845851,8042845852,8042845853,8042845854,8042845855,8042845857,8042845856,8042845859,8042845858,8042845860,4036899624]},{"type":"way","id":577572399,"nodes":[5536620837,5536620838,5536620839,5536620840,5536620841,5536620842,5536620843,5536620844,5536620845,5536620846,5536620837]}]} + "https://overpass-api.de/api/interpreter?data=%5Bout%3Ajson%5D%5Btimeout%3A60%5D%5Bbbox%3A51.124212757826875%2C3.1640625%2C51.17934297928927%2C3.251953125%5D%3B"+query , d ) Utils.injectJsonDownloadForTests( From df706d2f9780b383e74da7df279629b5331e4582 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Mon, 4 Apr 2022 05:12:14 +0200 Subject: [PATCH 19/37] Small fixes, add filters to shops --- Models/ThemeConfig/Json/FilterConfigJson.ts | 3 ++ UI/BigComponents/ExtraLinkButton.ts | 2 +- assets/layers/shops/shops.json | 28 +++++++++++++++++++ .../mapcomplete-changes.json | 3 +- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/Models/ThemeConfig/Json/FilterConfigJson.ts b/Models/ThemeConfig/Json/FilterConfigJson.ts index 493bf74c90..bd03200f3b 100644 --- a/Models/ThemeConfig/Json/FilterConfigJson.ts +++ b/Models/ThemeConfig/Json/FilterConfigJson.ts @@ -16,6 +16,9 @@ export default interface FilterConfigJson { osmTags?: AndOrTagConfigJson | string, default?: boolean, fields?: { + /** + * If name is `search`, use "_first_comment~.*{search}.*" as osmTags + */ name: string, type?: string | "string" }[] diff --git a/UI/BigComponents/ExtraLinkButton.ts b/UI/BigComponents/ExtraLinkButton.ts index 102204e8de..4e4dbb0a20 100644 --- a/UI/BigComponents/ExtraLinkButton.ts +++ b/UI/BigComponents/ExtraLinkButton.ts @@ -62,7 +62,7 @@ export default class ExtraLinkButton extends UIElement { let text: Translation if (c.text === undefined) { - text = Translations.t.general.screenToSmall.Fuse(this.state.layoutToUse.title, "{theme}") + text = Translations.t.general.screenToSmall.Subs({theme: this.state.layoutToUse.title}) } else { text = c.text.Clone() } diff --git a/assets/layers/shops/shops.json b/assets/layers/shops/shops.json index 69df31c5a0..9f5a32dce7 100644 --- a/assets/layers/shops/shops.json +++ b/assets/layers/shops/shops.json @@ -408,5 +408,33 @@ "render": "8" } } + ], + "filter": [ + { + "id": "shop-type", + "options": [{ + "fields": [{ + "name": "search", + "type": "string" + }], + "osmTags": "shop~^.*{search}.*$", + "question": { + "en": "Only show shops selling {search}" + } + } + ] + }, + { + "id": "shop-name", + "options": [{ + "fields": [{ + "name": "search", + "type": "string" + }], + "osmTags": "name~^.*{search}.*$", + "question": { + "en": "Only show shops with name {search}" + } + }]} ] } \ No newline at end of file diff --git a/assets/themes/mapcomplete-changes/mapcomplete-changes.json b/assets/themes/mapcomplete-changes/mapcomplete-changes.json index 478d968efe..da73732b30 100644 --- a/assets/themes/mapcomplete-changes/mapcomplete-changes.json +++ b/assets/themes/mapcomplete-changes/mapcomplete-changes.json @@ -1,8 +1,7 @@ { "id": "mapcomplete-changes", "title": { - "en": "Changes made with MapComplete", - "nl": "Wijzigingen gemaakt met MapComplete" + "en": "Changes made with MapComplete" }, "shortDescription": { "en": "Shows changes made by MapComplete" From c3859d56c6e9185d4de22d8b12450f17a917ea51 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 6 Apr 2022 03:06:28 +0200 Subject: [PATCH 20/37] Rename tests to test; add a few tests --- {tests => test}/Chai.spec.ts | 0 {tests => test}/CodeQuality.spec.ts | 2 +- {tests => test}/Logic/Actors/Actors.spec.ts | 0 ...teMultiPolygonWithPointReuseAction.spec.ts | 0 .../TileFreshnessCalculator.spec.ts | 0 {tests => test}/Logic/GeoOperations.spec.ts | 0 .../ImageProviders/ImageProviders.spec.ts | 0 .../OSM/Actions/RelationSplitHandler.spec.ts | 0 .../OSM/Actions/ReplaceGeometryAction.spec.ts | 0 .../Logic/OSM/Actions/SplitAction.spec.ts | 0 {tests => test}/Logic/OSM/Changes.spec.ts | 0 .../Logic/OSM/ChangesetHandler.spec.ts | 0 {tests => test}/Logic/OSM/OsmObject.spec.ts | 0 .../Logic/Tags/LazyMatching.spec.ts | 0 .../Logic/Tags/OptimzeTags.spec.ts | 0 {tests => test}/Logic/Tags/TagUtils.spec.ts | 0 {tests => test}/Logic/Web/Wikidata.spec.ts | 0 .../Conversion/CreateNoteImportLayer.spec.ts | 0 .../Conversion/FixLegacyTheme.spec.ts | 0 .../Conversion/PrepareLayer.spec.ts | 3 -- .../Conversion/PrepareTheme.spec.ts | 33 ++++++++++++++++++- .../ThemeConfig/TagRenderingConfig.spec.ts | 0 {tests => test}/Models/Units.spec.ts | 0 .../UI/SpecialVisualisations.spec.ts | 0 .../UI/ValidatedTextFieldTranslations.ts | 0 {tests => test}/Utils.MinifyJson.spec.ts | 0 {tests => test}/scripts/GenerateCache.spec.ts | 0 {tests => test}/testhooks.ts | 0 28 files changed, 33 insertions(+), 5 deletions(-) rename {tests => test}/Chai.spec.ts (100%) rename {tests => test}/CodeQuality.spec.ts (94%) rename {tests => test}/Logic/Actors/Actors.spec.ts (100%) rename {tests => test}/Logic/Actors/CreateMultiPolygonWithPointReuseAction.spec.ts (100%) rename {tests => test}/Logic/FeatureSource/TileFreshnessCalculator.spec.ts (100%) rename {tests => test}/Logic/GeoOperations.spec.ts (100%) rename {tests => test}/Logic/ImageProviders/ImageProviders.spec.ts (100%) rename {tests => test}/Logic/OSM/Actions/RelationSplitHandler.spec.ts (100%) rename {tests => test}/Logic/OSM/Actions/ReplaceGeometryAction.spec.ts (100%) rename {tests => test}/Logic/OSM/Actions/SplitAction.spec.ts (100%) rename {tests => test}/Logic/OSM/Changes.spec.ts (100%) rename {tests => test}/Logic/OSM/ChangesetHandler.spec.ts (100%) rename {tests => test}/Logic/OSM/OsmObject.spec.ts (100%) rename {tests => test}/Logic/Tags/LazyMatching.spec.ts (100%) rename {tests => test}/Logic/Tags/OptimzeTags.spec.ts (100%) rename {tests => test}/Logic/Tags/TagUtils.spec.ts (100%) rename {tests => test}/Logic/Web/Wikidata.spec.ts (100%) rename {tests => test}/Models/ThemeConfig/Conversion/CreateNoteImportLayer.spec.ts (100%) rename {tests => test}/Models/ThemeConfig/Conversion/FixLegacyTheme.spec.ts (100%) rename {tests => test}/Models/ThemeConfig/Conversion/PrepareLayer.spec.ts (98%) rename {tests => test}/Models/ThemeConfig/Conversion/PrepareTheme.spec.ts (65%) rename {tests => test}/Models/ThemeConfig/TagRenderingConfig.spec.ts (100%) rename {tests => test}/Models/Units.spec.ts (100%) rename {tests => test}/UI/SpecialVisualisations.spec.ts (100%) rename {tests => test}/UI/ValidatedTextFieldTranslations.ts (100%) rename {tests => test}/Utils.MinifyJson.spec.ts (100%) rename {tests => test}/scripts/GenerateCache.spec.ts (100%) rename {tests => test}/testhooks.ts (100%) diff --git a/tests/Chai.spec.ts b/test/Chai.spec.ts similarity index 100% rename from tests/Chai.spec.ts rename to test/Chai.spec.ts diff --git a/tests/CodeQuality.spec.ts b/test/CodeQuality.spec.ts similarity index 94% rename from tests/CodeQuality.spec.ts rename to test/CodeQuality.spec.ts index a3db97b4e4..33fffcb54f 100644 --- a/tests/CodeQuality.spec.ts +++ b/test/CodeQuality.spec.ts @@ -24,7 +24,7 @@ function detectInCode(forbidden: string, reason: string) { throw stderr } - const found = stdout.split("\n").filter(s => s !== "").filter(s => !s.startsWith("./tests/") && !s.startsWith("./testLegacy/")); + const found = stdout.split("\n").filter(s => s !== "").filter(s => !s.startsWith("./test/")); if (found.length > 0) { throw `Found a '${forbidden}' at \n ${found.join("\n ")}.\n ${reason}` } diff --git a/tests/Logic/Actors/Actors.spec.ts b/test/Logic/Actors/Actors.spec.ts similarity index 100% rename from tests/Logic/Actors/Actors.spec.ts rename to test/Logic/Actors/Actors.spec.ts diff --git a/tests/Logic/Actors/CreateMultiPolygonWithPointReuseAction.spec.ts b/test/Logic/Actors/CreateMultiPolygonWithPointReuseAction.spec.ts similarity index 100% rename from tests/Logic/Actors/CreateMultiPolygonWithPointReuseAction.spec.ts rename to test/Logic/Actors/CreateMultiPolygonWithPointReuseAction.spec.ts diff --git a/tests/Logic/FeatureSource/TileFreshnessCalculator.spec.ts b/test/Logic/FeatureSource/TileFreshnessCalculator.spec.ts similarity index 100% rename from tests/Logic/FeatureSource/TileFreshnessCalculator.spec.ts rename to test/Logic/FeatureSource/TileFreshnessCalculator.spec.ts diff --git a/tests/Logic/GeoOperations.spec.ts b/test/Logic/GeoOperations.spec.ts similarity index 100% rename from tests/Logic/GeoOperations.spec.ts rename to test/Logic/GeoOperations.spec.ts diff --git a/tests/Logic/ImageProviders/ImageProviders.spec.ts b/test/Logic/ImageProviders/ImageProviders.spec.ts similarity index 100% rename from tests/Logic/ImageProviders/ImageProviders.spec.ts rename to test/Logic/ImageProviders/ImageProviders.spec.ts diff --git a/tests/Logic/OSM/Actions/RelationSplitHandler.spec.ts b/test/Logic/OSM/Actions/RelationSplitHandler.spec.ts similarity index 100% rename from tests/Logic/OSM/Actions/RelationSplitHandler.spec.ts rename to test/Logic/OSM/Actions/RelationSplitHandler.spec.ts diff --git a/tests/Logic/OSM/Actions/ReplaceGeometryAction.spec.ts b/test/Logic/OSM/Actions/ReplaceGeometryAction.spec.ts similarity index 100% rename from tests/Logic/OSM/Actions/ReplaceGeometryAction.spec.ts rename to test/Logic/OSM/Actions/ReplaceGeometryAction.spec.ts diff --git a/tests/Logic/OSM/Actions/SplitAction.spec.ts b/test/Logic/OSM/Actions/SplitAction.spec.ts similarity index 100% rename from tests/Logic/OSM/Actions/SplitAction.spec.ts rename to test/Logic/OSM/Actions/SplitAction.spec.ts diff --git a/tests/Logic/OSM/Changes.spec.ts b/test/Logic/OSM/Changes.spec.ts similarity index 100% rename from tests/Logic/OSM/Changes.spec.ts rename to test/Logic/OSM/Changes.spec.ts diff --git a/tests/Logic/OSM/ChangesetHandler.spec.ts b/test/Logic/OSM/ChangesetHandler.spec.ts similarity index 100% rename from tests/Logic/OSM/ChangesetHandler.spec.ts rename to test/Logic/OSM/ChangesetHandler.spec.ts diff --git a/tests/Logic/OSM/OsmObject.spec.ts b/test/Logic/OSM/OsmObject.spec.ts similarity index 100% rename from tests/Logic/OSM/OsmObject.spec.ts rename to test/Logic/OSM/OsmObject.spec.ts diff --git a/tests/Logic/Tags/LazyMatching.spec.ts b/test/Logic/Tags/LazyMatching.spec.ts similarity index 100% rename from tests/Logic/Tags/LazyMatching.spec.ts rename to test/Logic/Tags/LazyMatching.spec.ts diff --git a/tests/Logic/Tags/OptimzeTags.spec.ts b/test/Logic/Tags/OptimzeTags.spec.ts similarity index 100% rename from tests/Logic/Tags/OptimzeTags.spec.ts rename to test/Logic/Tags/OptimzeTags.spec.ts diff --git a/tests/Logic/Tags/TagUtils.spec.ts b/test/Logic/Tags/TagUtils.spec.ts similarity index 100% rename from tests/Logic/Tags/TagUtils.spec.ts rename to test/Logic/Tags/TagUtils.spec.ts diff --git a/tests/Logic/Web/Wikidata.spec.ts b/test/Logic/Web/Wikidata.spec.ts similarity index 100% rename from tests/Logic/Web/Wikidata.spec.ts rename to test/Logic/Web/Wikidata.spec.ts diff --git a/tests/Models/ThemeConfig/Conversion/CreateNoteImportLayer.spec.ts b/test/Models/ThemeConfig/Conversion/CreateNoteImportLayer.spec.ts similarity index 100% rename from tests/Models/ThemeConfig/Conversion/CreateNoteImportLayer.spec.ts rename to test/Models/ThemeConfig/Conversion/CreateNoteImportLayer.spec.ts diff --git a/tests/Models/ThemeConfig/Conversion/FixLegacyTheme.spec.ts b/test/Models/ThemeConfig/Conversion/FixLegacyTheme.spec.ts similarity index 100% rename from tests/Models/ThemeConfig/Conversion/FixLegacyTheme.spec.ts rename to test/Models/ThemeConfig/Conversion/FixLegacyTheme.spec.ts diff --git a/tests/Models/ThemeConfig/Conversion/PrepareLayer.spec.ts b/test/Models/ThemeConfig/Conversion/PrepareLayer.spec.ts similarity index 98% rename from tests/Models/ThemeConfig/Conversion/PrepareLayer.spec.ts rename to test/Models/ThemeConfig/Conversion/PrepareLayer.spec.ts index 042c9166fd..d395401bef 100644 --- a/tests/Models/ThemeConfig/Conversion/PrepareLayer.spec.ts +++ b/test/Models/ThemeConfig/Conversion/PrepareLayer.spec.ts @@ -12,9 +12,6 @@ import RewritableConfigJson from "../../../../Models/ThemeConfig/Json/Rewritable describe("ExpandRewrite", () => { - it("should do simple substitution", () => { - - }) it("should not allow overlapping keys", () => { const spec = >{ rewrite: { diff --git a/tests/Models/ThemeConfig/Conversion/PrepareTheme.spec.ts b/test/Models/ThemeConfig/Conversion/PrepareTheme.spec.ts similarity index 65% rename from tests/Models/ThemeConfig/Conversion/PrepareTheme.spec.ts rename to test/Models/ThemeConfig/Conversion/PrepareTheme.spec.ts index 6b60434911..b18863ce79 100644 --- a/tests/Models/ThemeConfig/Conversion/PrepareTheme.spec.ts +++ b/test/Models/ThemeConfig/Conversion/PrepareTheme.spec.ts @@ -9,6 +9,7 @@ import * as bookcaseLayer from "../../../../assets/generated/layers/public_bookc import LayerConfig from "../../../../Models/ThemeConfig/LayerConfig"; import {ExtractImages} from "../../../../Models/ThemeConfig/Conversion/FixImages"; import * as cyclofix from "../../../../assets/generated/themes/cyclofix.json" +import {Tag} from "../../../../Logic/Tags/Tag"; const themeConfigJson: LayoutConfigJson = { @@ -37,8 +38,24 @@ const themeConfigJson: LayoutConfigJson = { } describe("PrepareTheme", () => { + + it("should substitute layers", () => { + + const sharedLayers = new Map() + sharedLayers.set("public_bookcase", bookcaseLayer["default"]) + const theme ={...themeConfigJson, layers: ["public_bookcase"]} + const prepareStep = new PrepareTheme({ + tagRenderings: new Map(), + sharedLayers: sharedLayers + }) + let themeConfigJsonPrepared = prepareStep.convert(theme, "test").result + const themeConfig = new LayoutConfig(themeConfigJsonPrepared); + const layerUnderTest = themeConfig.layers.find(l => l.id === "public_bookcase") + expect(layerUnderTest.source.osmTags).deep.eq(new Tag("amenity","public_bookcase")) + + }) - it("should apply overrideAll", () => { + it("should apply override", () => { const sharedLayers = new Map() sharedLayers.set("public_bookcase", bookcaseLayer["default"]) @@ -51,6 +68,20 @@ describe("PrepareTheme", () => { expect(layerUnderTest.source.geojsonSource).eq("xyz") }) + + + it("should apply override", () => { + + const sharedLayers = new Map() + sharedLayers.set("public_bookcase", bookcaseLayer["default"]) + let themeConfigJsonPrepared = new PrepareTheme({ + tagRenderings: new Map(), + sharedLayers: sharedLayers + }).convert({...themeConfigJson, overrideAll: {source: {geoJson: "https://example.com/data.geojson"}}}, "test").result + const themeConfig = new LayoutConfig(themeConfigJsonPrepared); + const layerUnderTest = themeConfig.layers.find(l => l.id === "public_bookcase") + expect(layerUnderTest.source.geojsonSource).eq("https://example.com/data.geojson") + }) }) diff --git a/tests/Models/ThemeConfig/TagRenderingConfig.spec.ts b/test/Models/ThemeConfig/TagRenderingConfig.spec.ts similarity index 100% rename from tests/Models/ThemeConfig/TagRenderingConfig.spec.ts rename to test/Models/ThemeConfig/TagRenderingConfig.spec.ts diff --git a/tests/Models/Units.spec.ts b/test/Models/Units.spec.ts similarity index 100% rename from tests/Models/Units.spec.ts rename to test/Models/Units.spec.ts diff --git a/tests/UI/SpecialVisualisations.spec.ts b/test/UI/SpecialVisualisations.spec.ts similarity index 100% rename from tests/UI/SpecialVisualisations.spec.ts rename to test/UI/SpecialVisualisations.spec.ts diff --git a/tests/UI/ValidatedTextFieldTranslations.ts b/test/UI/ValidatedTextFieldTranslations.ts similarity index 100% rename from tests/UI/ValidatedTextFieldTranslations.ts rename to test/UI/ValidatedTextFieldTranslations.ts diff --git a/tests/Utils.MinifyJson.spec.ts b/test/Utils.MinifyJson.spec.ts similarity index 100% rename from tests/Utils.MinifyJson.spec.ts rename to test/Utils.MinifyJson.spec.ts diff --git a/tests/scripts/GenerateCache.spec.ts b/test/scripts/GenerateCache.spec.ts similarity index 100% rename from tests/scripts/GenerateCache.spec.ts rename to test/scripts/GenerateCache.spec.ts diff --git a/tests/testhooks.ts b/test/testhooks.ts similarity index 100% rename from tests/testhooks.ts rename to test/testhooks.ts From 54d7a3a52bc05c4ddf958d289c8cf7166647179c Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 6 Apr 2022 03:06:50 +0200 Subject: [PATCH 21/37] Refactoring of conversion, fix rewriting of maprenderings and tagrenderings --- Models/ThemeConfig/Conversion/Conversion.ts | 223 +++++++++++------- .../Conversion/LegacyJsonConvert.ts | 4 +- Models/ThemeConfig/Conversion/PrepareLayer.ts | 158 ++----------- Models/ThemeConfig/Conversion/PrepareTheme.ts | 11 +- Models/ThemeConfig/Conversion/Validation.ts | 11 +- Utils.ts | 71 ++++-- .../mapcomplete-changes.json | 4 + package.json | 2 +- 8 files changed, 215 insertions(+), 269 deletions(-) diff --git a/Models/ThemeConfig/Conversion/Conversion.ts b/Models/ThemeConfig/Conversion/Conversion.ts index 6be0b2756c..f947ed916e 100644 --- a/Models/ThemeConfig/Conversion/Conversion.ts +++ b/Models/ThemeConfig/Conversion/Conversion.ts @@ -9,27 +9,27 @@ export interface DesugaringContext { export abstract class Conversion { public readonly modifiedAttributes: string[]; - protected readonly doc: string; public readonly name: string - + protected readonly doc: string; + constructor(doc: string, modifiedAttributes: string[] = [], name: string) { this.modifiedAttributes = modifiedAttributes; this.doc = doc + "\n\nModified attributes are\n" + modifiedAttributes.join(", "); - this.name = name + this.name = name } public static strict(fixed: { errors?: string[], warnings?: string[], information?: string[], result?: T }): T { - - fixed.information?.forEach(i => console.log(" ", i)) - const yellow = (s) => "\x1b[33m"+s+"\x1b[0m" - const red = s => '\x1b[31m'+s+'\x1b[0m' - fixed.warnings?.forEach(w => console.warn(red(` `), yellow (w))) - if (fixed?.errors !== undefined && fixed?.errors?.length > 0) { - fixed.errors?.forEach(e => console.error(red(`ERR `+e))) + fixed.information?.forEach(i => console.log(" ", i)) + const yellow = (s) => "\x1b[33m" + s + "\x1b[0m" + const red = s => '\x1b[31m' + s + '\x1b[0m' + fixed.warnings?.forEach(w => console.warn(red(` `), yellow(w))) + + if (fixed?.errors !== undefined && fixed?.errors?.length > 0) { + fixed.errors?.forEach(e => console.error(red(`ERR ` + e))) throw "Detected one or more errors, stopping now" } - + return fixed.result; } @@ -38,98 +38,118 @@ export abstract class Conversion { return DesugaringStep.strict(fixed) } + public andThenF(f: (tout:TOut) => X ): Conversion{ + return new Pipe( + this, + new Pure(f) + ) + } + abstract convert(json: TIn, context: string): { result: TOut, errors?: string[], warnings?: string[], information?: string[] } +} - public convertAll(jsons: TIn[], context: string): { result: TOut[], errors: string[], warnings: string[], information?: string[] } { - if(jsons === undefined || jsons === null){ - throw `Detected a bug in the preprocessor pipeline: ${this.name}.convertAll received undefined or null - don't do this (at ${context})` - } - const result = [] - const errors = [] - const warnings = [] - const information = [] - for (let i = 0; i < jsons.length; i++) { - const json = jsons[i]; - const r = this.convert(json, context + "[" + i + "]") - result.push(r.result) - errors.push(...r.errors ?? []) - warnings.push(...r.warnings ?? []) - information.push(...r.information ?? []) +export abstract class DesugaringStep extends Conversion { + +} + +class Pipe extends Conversion { + private readonly _step0: Conversion; + private readonly _step1: Conversion; + constructor(step0: Conversion, step1: Conversion) { + super("Merges two steps with different types", [], `Pipe(${step0.name}, ${step1.name})`); + this._step0 = step0; + this._step1 = step1; + } + + convert(json: TIn, context: string): { result: TOut; errors?: string[]; warnings?: string[]; information?: string[] } { + + const r0 = this._step0.convert(json, context); + const {result, errors, information, warnings } = r0; + if(result === undefined && errors.length > 0){ + return { + ...r0, + result: undefined + }; } + + const r = this._step1.convert(result, context); + errors.push(...r.errors) + information.push(...r.information) + warnings.push(...r.warnings) return { - result, + result: r.result, errors, warnings, information } } - } -export abstract class DesugaringStep extends Conversion { +class Pure extends Conversion { + private readonly _f: (t: TIn) => TOut; + constructor(f: ((t:TIn) => TOut)) { + super("Wrapper around a pure function",[], "Pure"); + this._f = f; + } + + convert(json: TIn, context: string): { result: TOut; errors?: string[]; warnings?: string[]; information?: string[] } { + return {result: this._f(json)}; + } + } -export class OnEvery extends DesugaringStep { - private readonly key: string; - private readonly step: DesugaringStep; - private _options: { ignoreIfUndefined: boolean }; +export class Each extends Conversion { + private readonly _step: Conversion; - constructor(key: string, step: DesugaringStep, options?: { - ignoreIfUndefined: false | boolean - }) { - super("Applies " + step.name + " onto every object of the list `key`", [key], "OnEvery("+step.name+")"); - this.step = step; - this.key = key; - this._options = options; + constructor(step: Conversion) { + super("Applies the given step on every element of the list", [], "OnEach(" + step.name + ")"); + this._step = step; } - convert(json: T, context: string): { result: T; errors?: string[]; warnings?: string[], information?: string[] } { - json = {...json} - const step = this.step - const key = this.key; - if( this._options?.ignoreIfUndefined && json[key] === undefined){ - return { - result: json, - }; - }else{ - const r = step.convertAll((json[key]), context + "." + key) - json[key] = r.result - return { - ...r, - result: json, - }; - } - - } -} - -export class OnEveryConcat extends DesugaringStep { - private readonly key: string; - private readonly step: Conversion; - - constructor(key: string, step: Conversion) { - super(`Applies ${step.name} onto every object of the list \`${key}\`. The results are concatenated and used as new list`, [key], - "OnEvery("+key+").Concat("+step.name+")"); - this.step = step; - this.key = key; - } - - convert(json: T, context: string): { result: T; errors?: string[]; warnings?: string[], information?: string[] } { - json = {...json} - const step = this.step - const key = this.key; - const values = json[key] + convert(values: X[], context: string): { result: Y[]; errors?: string[]; warnings?: string[]; information?: string[] } { if (values === undefined || values === null) { - // Move on - nothing to see here! - return { - result: json, - } + return {result: undefined} } - const r = step.convertAll((values), context + "." + key) - const vals: X[][] = r.result - - json[key] = [].concat(...vals) - + const information: string[] = [] + const warnings: string[] = [] + const errors: string[] = [] + const step = this._step + const result: Y[] = [] + for (let i = 0; i < values.length; i++) { + const r = step.convert(values[i], context + "[" + i + "]") + information.push(...r.information) + warnings.push(...r.warnings) + errors.push(...r.errors) + result.push(r.result) + } + return { + information, errors, warnings, + result + }; + } + +} + +export class On extends DesugaringStep { + private readonly key: string; + private readonly step: Conversion; + + constructor(key: string, step: Conversion) { + super("Applies " + step.name + " onto property `"+key+"`", [key], `On(${key}, ${step.name})`); + this.step = step; + this.key = key; + } + + convert(json: T, context: string): { result: T; errors?: string[]; warnings?: string[], information?: string[] } { + json = {...json} + const step = this.step + const key = this.key; + const value: P = json[key] + if (value === undefined || value === null) { + return { result: json }; + } + const r = step.convert(value, context + "." + key) + json[key] = r.result return { ...r, result: json, @@ -138,13 +158,40 @@ export class OnEveryConcat extends DesugaringStep { } } +export class Concat extends Conversion { + private readonly _step: Conversion; + + constructor(step: Conversion) { + super("Executes the given step, flattens the resulting list", [], "Concat(" + step.name + ")"); + this._step = step; + } + + convert(values: X[], context: string): { result: T[]; errors?: string[]; warnings?: string[]; information?: string[] } { + if (values === undefined || values === null) { + // Move on - nothing to see here! + return { + result: undefined, + } + } + const r = new Each(this._step).convert(values, context) + const vals: T[][] = r.result + + const flattened: T[] = [].concat(...vals) + + return { + ...r, + result: flattened, + }; + } +} + export class Fuse extends DesugaringStep { private readonly steps: DesugaringStep[]; constructor(doc: string, ...steps: DesugaringStep[]) { super((doc ?? "") + "This fused pipeline of the following steps: " + steps.map(s => s.name).join(", "), Utils.Dedup([].concat(...steps.map(step => step.modifiedAttributes))), - "Fuse of "+steps.map(s => s.name).join(", ") + "Fuse of " + steps.map(s => s.name).join(", ") ); this.steps = Utils.NoNull(steps); } @@ -155,7 +202,7 @@ export class Fuse extends DesugaringStep { const information = [] for (let i = 0; i < this.steps.length; i++) { const step = this.steps[i]; - let r = step.convert(json, "While running step " +step.name + ": " + context) + let r = step.convert(json, "While running step " + step.name + ": " + context) errors.push(...r.errors ?? []) warnings.push(...r.warnings ?? []) information.push(...r.information ?? []) @@ -180,7 +227,7 @@ export class SetDefault extends DesugaringStep { private readonly _overrideEmptyString: boolean; constructor(key: string, value: any, overrideEmptyString = false) { - super("Sets " + key + " to a default value if undefined", [], "SetDefault of "+key); + super("Sets " + key + " to a default value if undefined", [], "SetDefault of " + key); this.key = key; this.value = value; this._overrideEmptyString = overrideEmptyString; diff --git a/Models/ThemeConfig/Conversion/LegacyJsonConvert.ts b/Models/ThemeConfig/Conversion/LegacyJsonConvert.ts index c1bbcec37d..547f8c57b4 100644 --- a/Models/ThemeConfig/Conversion/LegacyJsonConvert.ts +++ b/Models/ThemeConfig/Conversion/LegacyJsonConvert.ts @@ -2,7 +2,7 @@ import {LayoutConfigJson} from "../Json/LayoutConfigJson"; import {Utils} from "../../../Utils"; import LineRenderingConfigJson from "../Json/LineRenderingConfigJson"; import {LayerConfigJson} from "../Json/LayerConfigJson"; -import {DesugaringStep, Fuse, OnEvery} from "./Conversion"; +import {DesugaringStep, Each, Fuse, On} from "./Conversion"; export class UpdateLegacyLayer extends DesugaringStep { @@ -159,7 +159,7 @@ export class FixLegacyTheme extends Fuse { super( "Fixes a legacy theme to the modern JSON format geared to humans. Syntactic sugars are kept (i.e. no tagRenderings are expandend, no dependencies are automatically gathered)", new UpdateLegacyTheme(), - new OnEvery("layers", new UpdateLegacyLayer()) + new On("layers",new Each( new UpdateLegacyLayer())) ); } } diff --git a/Models/ThemeConfig/Conversion/PrepareLayer.ts b/Models/ThemeConfig/Conversion/PrepareLayer.ts index 616453d544..8e41251345 100644 --- a/Models/ThemeConfig/Conversion/PrepareLayer.ts +++ b/Models/ThemeConfig/Conversion/PrepareLayer.ts @@ -1,4 +1,4 @@ -import {Conversion, DesugaringContext, DesugaringStep, Fuse, OnEvery, OnEveryConcat, SetDefault} from "./Conversion"; +import {Concat, Conversion, DesugaringContext, DesugaringStep, Each, Fuse, On, SetDefault} from "./Conversion"; import {LayerConfigJson} from "../Json/LayerConfigJson"; import {TagRenderingConfigJson} from "../Json/TagRenderingConfigJson"; import {Utils} from "../../../Utils"; @@ -12,7 +12,7 @@ class ExpandTagRendering extends Conversion { - - - private _expandSubTagRenderings; - - constructor(state: DesugaringContext) { - super( - "Converts a rewrite config for tagRenderings into the expanded form", [], - "ExpandGroupRewrite" - ); - this._expandSubTagRenderings = new ExpandTagRendering(state) - } - - convert(json: - { - rewrite: - { sourceString: string; into: string[] }[]; renderings: (string | { builtin: string; override: any } | TagRenderingConfigJson)[] - } | TagRenderingConfigJson, context: string): { result: TagRenderingConfigJson[]; errors: string[]; warnings?: string[] } { - - if (json["rewrite"] === undefined) { - return {result: [json], errors: [], warnings: []} - } - let config = <{ - rewrite: - { sourceString: string[]; into: (string | any)[][] }; - renderings: (string | { builtin: string; override: any } | TagRenderingConfigJson)[] - }>json; - - - { - const errors = [] - - if (!Array.isArray(config.rewrite.sourceString)) { - let extra = ""; - if (typeof config.rewrite.sourceString === "string") { - extra = `
Try "sourceString": [ "${config.rewrite.sourceString}" ] instead (note the [ and ])` - } - const msg = context + "
Invalid format: a rewrite block is defined, but the 'sourceString' should be an array of strings, but it is a " + typeof config.rewrite.sourceString + extra - errors.push(msg) - } - - - const expectedLength = config.rewrite.sourceString.length - for (let i = 0; i < config.rewrite.into.length; i++) { - const targets = config.rewrite.into[i]; - if (!Array.isArray(targets)) { - errors.push(`${context}.rewrite.into[${i}] should be an array of values, but it is a ` + typeof targets) - } else if (targets.length !== expectedLength) { - errors.push(`${context}.rewrite.into[${i}]:
The rewrite specified ${config.rewrite.sourceString} as sourcestring, which consists of ${expectedLength} values. The target ${JSON.stringify(targets)} has ${targets.length} items`) - if (typeof targets[0] !== "string") { - errors.push(context + ".rewrite.into[" + i + "]: expected a string as first rewrite value values, but got " + targets[0]) - - } - } - } - - if (errors.length > 0) { - return { - errors, - warnings: [], - result: undefined - } - } - } - - const subRenderingsRes = <{ result: TagRenderingConfigJson[][], errors, warnings }>this._expandSubTagRenderings.convertAll(config.renderings, context); - const subRenderings: TagRenderingConfigJson[] = [].concat(...subRenderingsRes.result); - const errors = subRenderingsRes.errors; - const warnings = subRenderingsRes.warnings; - - - const rewrittenPerGroup = new Map() - - // The actual rewriting - const sourceStrings = config.rewrite.sourceString; - for (const targets of config.rewrite.into) { - const groupName = targets[0]; - if (typeof groupName !== "string") { - throw "The first string of 'targets' should always be a string" - } - const trs: TagRenderingConfigJson[] = [] - - for (const tr of subRenderings) { - let rewritten = tr; - for (let i = 0; i < sourceStrings.length; i++) { - const source = sourceStrings[i] - const target = targets[i] // This is a string OR a translation - rewritten = ExpandRewrite.RewriteParts(source, target, rewritten) - } - rewritten.group = rewritten.group ?? groupName - trs.push(rewritten) - } - - if (rewrittenPerGroup.has(groupName)) { - rewrittenPerGroup.get(groupName).push(...trs) - } else { - rewrittenPerGroup.set(groupName, trs) - - } - } - - // Add questions box for this category - rewrittenPerGroup.forEach((group, groupName) => { - group.push({ - id: "questions", - group: groupName - }) - }) - - - rewrittenPerGroup.forEach((group, _) => { - group.forEach(tr => { - if (tr.id === undefined || tr.id === "") { - errors.push("A tagrendering has an empty ID after expanding the tag; the tagrendering is: " + JSON.stringify(tr)) - } - }) - }) - - return { - result: [].concat(...Array.from(rewrittenPerGroup.values())), - errors, warnings - }; - } - -} - export class ExpandRewrite extends Conversion, T[]> { constructor() { @@ -286,10 +154,15 @@ export class ExpandRewrite extends Conversion, T[ * "someKey": "somevalue {xyz}" * } * ExpandRewrite.RewriteParts("{xyz}", "rewritten", spec) // => {"someKey": "somevalue rewritten"} + * + * // should substitute all occurances in strings + * const spec = { + * "someKey": "The left|right side has {key:left|right}" + * } + * ExpandRewrite.RewriteParts("left|right", "left", spec) // => {"someKey": "The left side has {key:left}"} * */ public static RewriteParts(keyToRewrite: string, target: string | any, tr: T): T { - const targetIsTranslation = Translations.isProbablyATranslation(target) function replaceRecursive(obj: string | any, target) { @@ -300,7 +173,10 @@ export class ExpandRewrite extends Conversion, T[ if (typeof obj === "string") { // This is a simple string - we do a simple replace - return obj.replace(keyToRewrite, target) + while(obj.indexOf(keyToRewrite) >= 0){ + obj = obj.replace(keyToRewrite, target) + } + return obj } if (Array.isArray(obj)) { // This is a list of items @@ -581,12 +457,12 @@ export class PrepareLayer extends Fuse { constructor(state: DesugaringContext) { super( "Fully prepares and expands a layer for the LayerConfig.", - new OnEvery("tagRenderings", new RewriteSpecial(), {ignoreIfUndefined: true}), - new OnEveryConcat("tagRenderings", new ExpandGroupRewrite(state)), - new OnEveryConcat("tagRenderings", new ExpandTagRendering(state)), - new OnEveryConcat("mapRendering", new ExpandRewrite()), + new On("tagRenderings", new Each(new RewriteSpecial())), + new On("tagRenderings", new Concat(new ExpandRewrite()).andThenF(Utils.Flatten)), + new On("tagRenderings", new Concat(new ExpandTagRendering(state))), + new On("mapRendering", new Concat(new ExpandRewrite()).andThenF(Utils.Flatten)), new SetDefault("titleIcons", ["defaults"]), - new OnEveryConcat("titleIcons", new ExpandTagRendering(state)) + new On("titleIcons", new Concat(new ExpandTagRendering(state))) ); } } \ No newline at end of file diff --git a/Models/ThemeConfig/Conversion/PrepareTheme.ts b/Models/ThemeConfig/Conversion/PrepareTheme.ts index 5c210cec74..b563a232a8 100644 --- a/Models/ThemeConfig/Conversion/PrepareTheme.ts +++ b/Models/ThemeConfig/Conversion/PrepareTheme.ts @@ -1,10 +1,9 @@ -import {Conversion, DesugaringContext, DesugaringStep, Fuse, OnEvery, OnEveryConcat, SetDefault} from "./Conversion"; +import {Concat, Conversion, DesugaringContext, DesugaringStep, Each, Fuse, On, SetDefault} from "./Conversion"; import {LayoutConfigJson} from "../Json/LayoutConfigJson"; import {PrepareLayer} from "./PrepareLayer"; import {LayerConfigJson} from "../Json/LayerConfigJson"; import {Utils} from "../../../Utils"; import Constants from "../../Constants"; -import {AllKnownLayouts} from "../../../Customizations/AllKnownLayouts"; import CreateNoteImportLayer from "./CreateNoteImportLayer"; import LayerConfig from "../LayerConfig"; import {TagRenderingConfigJson} from "../Json/TagRenderingConfigJson"; @@ -457,18 +456,18 @@ export class PrepareTheme extends Fuse { "Fully prepares and expands a theme", new PreparePersonalTheme(state), new WarnForUnsubstitutedLayersInTheme(), - new OnEveryConcat("layers", new SubstituteLayer(state)), + new On("layers", new Concat(new SubstituteLayer(state))), new SetDefault("socialImage", "assets/SocialImage.png", true), // We expand all tagrenderings first... - new OnEvery("layers", new PrepareLayer(state)), + new On("layers", new Each(new PrepareLayer(state))), // Then we apply the override all new ApplyOverrideAll(), // And then we prepare all the layers _again_ in case that an override all contained unexpanded tagrenderings! - new OnEvery("layers", new PrepareLayer(state)), + new On("layers", new Each(new PrepareLayer(state))), new AddDefaultLayers(state), new AddDependencyLayersToTheme(state), new AddImportLayers(), - new OnEvery("layers", new AddMiniMap(state)) + new On("layers", new Each(new AddMiniMap(state))) ); } } \ No newline at end of file diff --git a/Models/ThemeConfig/Conversion/Validation.ts b/Models/ThemeConfig/Conversion/Validation.ts index c983ca9362..b735c9bc79 100644 --- a/Models/ThemeConfig/Conversion/Validation.ts +++ b/Models/ThemeConfig/Conversion/Validation.ts @@ -1,4 +1,4 @@ -import {DesugaringStep, Fuse, OnEvery} from "./Conversion"; +import {DesugaringStep, Each, Fuse, On} from "./Conversion"; import {LayerConfigJson} from "../Json/LayerConfigJson"; import LayerConfig from "../LayerConfig"; import {Utils} from "../../../Utils"; @@ -17,11 +17,12 @@ import {QuestionableTagRenderingConfigJson} from "../Json/QuestionableTagRenderi class ValidateLanguageCompleteness extends DesugaringStep { + private readonly _languages: string[]; constructor(...languages: string[]) { super("Checks that the given object is fully translated in the specified languages", [], "ValidateLanguageCompleteness"); - this._languages = languages; + this._languages = languages ?? ["en"]; } convert(obj: any, context: string): { result: LayerConfig; errors: string[] } { @@ -29,7 +30,7 @@ class ValidateLanguageCompleteness extends DesugaringStep { const translations = Translation.ExtractAllTranslationsFrom( obj ) - for (const neededLanguage of this._languages ?? ["en"]) { + for (const neededLanguage of this._languages) { translations .filter(t => t.tr.translations[neededLanguage] === undefined && t.tr.translations["*"] === undefined) .forEach(missing => { @@ -173,7 +174,7 @@ export class ValidateThemeAndLayers extends Fuse { constructor(knownImagePaths: Set, path: string, isBuiltin: boolean, sharedTagRenderings: Map) { super("Validates a theme and the contained layers", new ValidateTheme(knownImagePaths, path, isBuiltin, sharedTagRenderings), - new OnEvery("layers", new ValidateLayer(undefined, false)) + new On("layers", new Each(new ValidateLayer(undefined, false))) ); } } @@ -510,7 +511,7 @@ export class ValidateLayer extends DesugaringStep { } } if (json.tagRenderings !== undefined) { - const r = new OnEvery("tagRenderings", new ValidateTagRenderings(json)).convert(json, context) + const r = new On("tagRenderings", new Each(new ValidateTagRenderings(json))).convert(json, context) warnings.push(...(r.warnings??[])) errors.push(...(r.errors??[])) information.push(...(r.information??[])) diff --git a/Utils.ts b/Utils.ts index 6d011ba6e1..21668a1bc6 100644 --- a/Utils.ts +++ b/Utils.ts @@ -183,11 +183,11 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be } return str.substr(0, l - 3) + "..."; } - + public static FixedLength(str: string, l: number) { str = Utils.EllipsesAfter(str, l) - while(str.length < l){ - str = " "+str + while (str.length < l) { + str = " " + str } return str; } @@ -220,6 +220,23 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be return newArr; } + /** + * In the given list, all values which are lists will be merged with the values, e.g. + * + * Utils.Flatten([ [1,2], 2, [4, [5 ,6]] ]) // => [1, 2, 3, 4, [5, 6]] + */ + public static Flatten(list: (T | T[])[]): T[] { + const result = [] + for (const value of list) { + if (Array.isArray(value)) { + result.push(...value) + } else { + result.push(value) + } + } + return result; + } + public static Identical(t1: T[], t2: T[], eq?: (t: T, t0: T) => boolean): boolean { if (t1.length !== t2.length) { return false @@ -533,21 +550,21 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be if (jtp !== "object") { return } - + if (isLeaf(json)) { return collect(json, path) } } else if (jtp === "boolean" || jtp === "string" || jtp === "number") { - return collect(json,path) + return collect(json, path) } if (Array.isArray(json)) { - return json.map((sub,i) => { - return Utils.WalkObject(sub, collect, isLeaf,[...path, i]); + return json.map((sub, i) => { + return Utils.WalkObject(sub, collect, isLeaf, [...path, i]); }) } for (const key in json) { - Utils.WalkObject(json[key], collect, isLeaf, [...path,key]) + Utils.WalkObject(json[key], collect, isLeaf, [...path, key]) } } @@ -832,9 +849,9 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be } return new Date(str) } - - public static sortedByLevenshteinDistance(reference: string, ts: T[], getName: (t:T) => string): T[]{ - const withDistance: [T, number][] = ts.map(t => [t, Utils.levenshteinDistance(getName(t), reference)]) + + public static sortedByLevenshteinDistance(reference: string, ts: T[], getName: (t: T) => string): T[] { + const withDistance: [T, number][] = ts.map(t => [t, Utils.levenshteinDistance(getName(t), reference)]) withDistance.sort(([_, a], [__, b]) => a - b) return withDistance.map(n => n[0]) } @@ -872,43 +889,41 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be return o } - private static colorDiff(c0: { r: number, g: number, b: number }, c1: { r: number, g: number, b: number }) { - return Math.abs(c0.r - c1.r) + Math.abs(c0.g - c1.g) + Math.abs(c0.b - c1.b); - } - /** * Utils.colorAsHex({r: 255, g: 128, b: 0}) // => "#ff8000" * Utils.colorAsHex(undefined) // => undefined */ - public static colorAsHex(c:{ r: number, g: number, b: number } ){ - if(c === undefined){ + public static colorAsHex(c: { r: number, g: number, b: number }) { + if (c === undefined) { return undefined } + function componentToHex(n) { let hex = n.toString(16); return hex.length == 1 ? "0" + hex : hex; } + return "#" + componentToHex(c.r) + componentToHex(c.g) + componentToHex(c.b); } - + /** - * + * * Utils.color("#ff8000") // => {r: 255, g:128, b: 0} * Utils.color(" rgba (12,34,56) ") // => {r: 12, g:34, b: 56} * Utils.color(" rgba (12,34,56,0.5) ") // => {r: 12, g:34, b: 56} * Utils.color(undefined) // => undefined */ public static color(hex: string): { r: number, g: number, b: number } { - if(hex === undefined){ + if (hex === undefined) { return undefined } hex = hex.replace(/[ \t]/g, "") if (hex.startsWith("rgba(")) { - const match = hex.match(/rgba\(([0-9.]+),([0-9.]+),([0-9.]+)(,[0-9.]*)?\)/) - if(match == undefined){ + const match = hex.match(/rgba\(([0-9.]+),([0-9.]+),([0-9.]+)(,[0-9.]*)?\)/) + if (match == undefined) { return undefined } - return {r: Number(match[1]), g: Number(match[2]), b:Number( match[3])} + return {r: Number(match[1]), g: Number(match[2]), b: Number(match[3])} } if (!hex.startsWith("#")) { @@ -928,9 +943,9 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be b: parseInt(hex.substr(5, 2), 16), } } - - public static asDict(tags: {key: string, value: string | number}[]) : Map{ - const d= new Map() + + public static asDict(tags: { key: string, value: string | number }[]): Map { + const d = new Map() for (const tag of tags) { d.set(tag.key, tag.value) @@ -938,5 +953,9 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be return d } + + private static colorDiff(c0: { r: number, g: number, b: number }, c1: { r: number, g: number, b: number }) { + return Math.abs(c0.r - c1.r) + Math.abs(c0.g - c1.g) + Math.abs(c0.b - c1.b); + } } diff --git a/assets/themes/mapcomplete-changes/mapcomplete-changes.json b/assets/themes/mapcomplete-changes/mapcomplete-changes.json index da73732b30..b03b39e7ad 100644 --- a/assets/themes/mapcomplete-changes/mapcomplete-changes.json +++ b/assets/themes/mapcomplete-changes/mapcomplete-changes.json @@ -231,6 +231,10 @@ "if": "theme=openwindpowermap", "then": "./assets/themes/openwindpowermap/logo.svg" }, + { + "if": "theme=parking-lanes", + "then": "./assets/svg/bug.svg" + }, { "if": "theme=parkings", "then": "./assets/themes/parkings/parkings.svg" diff --git a/package.json b/package.json index 3dbdf1b945..df8aa0767c 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "watch:css": "tailwindcss -i index.css -o css/index-tailwind-output.css --watch", "generate:css": "tailwindcss -i index.css -o css/index-tailwind-output.css", "generate:doctests": "doctest-ts-improved .", - "test:run-only": "mocha --require ts-node/register --require tests/testhooks.ts \"./**/*.doctest.ts\" \"tests/*\" \"tests/**/*.ts\"", + "test:run-only": "mocha --require ts-node/register --require test/testhooks.ts \"./**/*.doctest.ts\" \"test/*\" \"test/**/*.ts\"", "test": "(npm run generate:doctests 2>&1 | grep -v \"No doctests found in\") && npm run test:run-only && npm run clean:tests", "init": "npm ci && npm run generate && npm run generate:editor-layer-index && npm run generate:layouts && npm run clean", "add-weblate-upstream": "git remote add weblate-layers https://hosted.weblate.org/git/mapcomplete/layer-translations/ ; git remote add weblate-core https://hosted.weblate.org/git/mapcomplete/layer-core/; git remote add weblate-themes https://hosted.weblate.org/git/mapcomplete/layer-themes/; git remote add weblate-github git@github.com:weblate/MapComplete.git", From 9d961b36729a43b16d75a0b6fb0065d59ac6ce06 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 6 Apr 2022 03:11:26 +0200 Subject: [PATCH 22/37] Fix tests --- Utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Utils.ts b/Utils.ts index 21668a1bc6..a6e841cfac 100644 --- a/Utils.ts +++ b/Utils.ts @@ -223,7 +223,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be /** * In the given list, all values which are lists will be merged with the values, e.g. * - * Utils.Flatten([ [1,2], 2, [4, [5 ,6]] ]) // => [1, 2, 3, 4, [5, 6]] + * Utils.Flatten([ [1,2], 3, [4, [5 ,6]] ]) // => [1, 2, 3, 4, [5, 6]] */ public static Flatten(list: (T | T[])[]): T[] { const result = [] From 5857471be365ebd72d9f3afd21577dd4faeaa042 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 6 Apr 2022 03:18:17 +0200 Subject: [PATCH 23/37] More tests --- Utils.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Utils.ts b/Utils.ts index a6e841cfac..9770e3b3f4 100644 --- a/Utils.ts +++ b/Utils.ts @@ -237,6 +237,11 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be return result; } + /** + * Utils.Identical([1,2], [1,2]) // => true + * Utils.Identical([1,2,3], [1,2,4}]) // => false + * Utils.Identical([1,2], [1,2,3]) // => false + */ public static Identical(t1: T[], t2: T[], eq?: (t: T, t0: T) => boolean): boolean { if (t1.length !== t2.length) { return false @@ -250,6 +255,9 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be return true; } + /** + * Utils.MergeTags({k0:"v0","common":"0"},{k1:"v1", common: "1"}) // => {k0: "v0", k1:"v1", common: "1"} + */ public static MergeTags(a: any, b: any) { const t = {}; for (const k in a) { From d80cc64f776580e5160967b2aa2d57d488f97b4e Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 6 Apr 2022 04:21:15 +0200 Subject: [PATCH 24/37] Small bugfix in import helper --- UI/ImportFlow/AskMetadata.ts | 11 ----------- UI/ImportFlow/ConflationChecker.ts | 4 ++-- UI/ImportFlow/ImportHelperGui.ts | 5 ++--- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/UI/ImportFlow/AskMetadata.ts b/UI/ImportFlow/AskMetadata.ts index 975d0e6d99..9f7c16caf5 100644 --- a/UI/ImportFlow/AskMetadata.ts +++ b/UI/ImportFlow/AskMetadata.ts @@ -4,19 +4,8 @@ import {UIEventSource} from "../../Logic/UIEventSource"; import ValidatedTextField from "../Input/ValidatedTextField"; import {LocalStorageSource} from "../../Logic/Web/LocalStorageSource"; import Title from "../Base/Title"; -import {AllKnownLayouts} from "../../Customizations/AllKnownLayouts"; -import {DropDown} from "../Input/DropDown"; -import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; -import BaseUIElement from "../BaseUIElement"; import {FixedUiElement} from "../Base/FixedUiElement"; -import {RadioButton} from "../Input/RadioButton"; -import {FixedInputElement} from "../Input/FixedInputElement"; -import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; -import {InputElement} from "../Input/InputElement"; -import Img from "../Base/Img"; import {VariableUiElement} from "../Base/VariableUIElement"; -import {And} from "../../Logic/Tags/And"; -import Toggleable from "../Base/Toggleable"; export class AskMetadata extends Combine implements FlowStep<{ features: any[], diff --git a/UI/ImportFlow/ConflationChecker.ts b/UI/ImportFlow/ConflationChecker.ts index 192442043c..f0a3f17c96 100644 --- a/UI/ImportFlow/ConflationChecker.ts +++ b/UI/ImportFlow/ConflationChecker.ts @@ -35,7 +35,7 @@ import {ImportUtils} from "./ImportUtils"; export default class ConflationChecker extends Combine implements FlowStep<{ features: any[], theme: string }> { public readonly IsValid - public readonly Value + public readonly Value: UIEventSource<{ features: any[], theme: string }> constructor( state, @@ -249,7 +249,7 @@ export default class ConflationChecker extends Combine implements FlowStep<{ fea ]) - this.Value = paritionedImport.map(feats => ({features: feats?.noNearby, layer: params.layer})) + this.Value = paritionedImport.map(feats => ({theme: params.theme, features: feats?.noNearby, layer: params.layer})) this.IsValid = this.Value.map(v => v?.features !== undefined && v.features.length > 0) } diff --git a/UI/ImportFlow/ImportHelperGui.ts b/UI/ImportFlow/ImportHelperGui.ts index b577c6cfd5..8fb1c041b3 100644 --- a/UI/ImportFlow/ImportHelperGui.ts +++ b/UI/ImportFlow/ImportHelperGui.ts @@ -10,7 +10,6 @@ import {RequestFile} from "./RequestFile"; import {PreviewPanel} from "./PreviewPanel"; import ConflationChecker from "./ConflationChecker"; import {AskMetadata} from "./AskMetadata"; -import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; import {ConfirmProcess} from "./ConfirmProcess"; import {CreateNotes} from "./CreateNotes"; import {FixedUiElement} from "../Base/FixedUiElement"; @@ -38,8 +37,8 @@ export default class ImportHelperGui extends LeftIndex { .then("Select theme", v => new SelectTheme(v)) .then("Compare with open notes", v => new CompareToAlreadyExistingNotes(state, v)) .then("Compare with existing data", v => new ConflationChecker(state, v)) - .then("License and community check", (v : {features: any[], theme: string}) => new ConfirmProcess(v)) - .then("Metadata", (v: { features: any[], layer: LayerConfig, theme: string }) => new AskMetadata(v)) + .then("License and community check", v => new ConfirmProcess(v)) + .then("Metadata", (v) => new AskMetadata(v)) .finish("Note creation", v => new CreateNotes(state, v)); const toc = new List( From db2b14cd95b97e01073fbc03b29586d5207c6269 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 6 Apr 2022 16:12:01 +0200 Subject: [PATCH 25/37] Improve documentation --- Customizations/AllKnownLayouts.ts | 42 +- Docs/BuiltinLayers.md | 36 +- Docs/Layers/address.md | 15 +- Docs/Layers/all_streets.md | 132 ++++-- Docs/Layers/ambulancestation.md | 19 +- Docs/Layers/artwork.md | 18 +- Docs/Layers/assen.md | 38 -- Docs/Layers/barrier.md | 20 +- Docs/Layers/bench.md | 20 +- Docs/Layers/bench_at_pt.md | 16 +- Docs/Layers/bicycle_library.md | 22 +- Docs/Layers/bicycle_rental.md | 108 +---- Docs/Layers/bicycle_tube_vending_machine.md | 20 +- Docs/Layers/bike_cafe.md | 22 +- Docs/Layers/bike_cleaning.md | 16 +- Docs/Layers/bike_parking.md | 21 +- Docs/Layers/bike_repair_station.md | 28 +- Docs/Layers/bike_shop.md | 30 +- Docs/Layers/bike_themed_object.md | 19 +- Docs/Layers/binocular.md | 16 +- Docs/Layers/birdhide.md | 17 +- Docs/Layers/brugge.md | 73 --- Docs/Layers/cafe_pub.md | 24 +- Docs/Layers/caravansites.md | 324 ++++++++----- Docs/Layers/charging_station.md | 100 +--- Docs/Layers/climbing.md | 383 ++++++++++++--- Docs/Layers/climbing_club.md | 344 +++++++++++--- Docs/Layers/climbing_gym.md | 367 ++++++++++++--- Docs/Layers/climbing_route.md | 387 ++++++++++++--- Docs/Layers/cluster_style.md | 13 +- Docs/Layers/conflation.md | 39 -- Docs/Layers/crab_address.md | 13 +- Docs/Layers/crossings.md | 20 +- .../cultural_places_without_etymology.md | 162 +++++++ Docs/Layers/current_view.md | 44 -- Docs/Layers/cycle_highways.md | 107 ----- Docs/Layers/cycleways_and_roads.md | 27 +- Docs/Layers/defibrillator.md | 28 +- Docs/Layers/direction.md | 12 +- Docs/Layers/drinking_water.md | 16 +- Docs/Layers/dumpstations.md | 250 ++++++---- ...ducation_institutions_without_etymology.md | 162 +++++++ Docs/Layers/entrance.md | 17 +- Docs/Layers/etymology.md | 22 +- Docs/Layers/extinguisher.md | 15 +- Docs/Layers/facadegardens.md | 210 ++++++--- Docs/Layers/fietsstraat.md | 121 ++++- Docs/Layers/fire_station.md | 19 +- Docs/Layers/food.md | 34 +- Docs/Layers/forest.md | 50 -- Docs/Layers/friture.md | 445 ++++++++++++++++++ Docs/Layers/fruitboom.md | 77 --- Docs/Layers/generic_osm_object.md | 45 -- Docs/Layers/ghost_bike.md | 19 +- Docs/Layers/gps_location.md | 44 -- Docs/Layers/gps_location_history.md | 43 -- Docs/Layers/gps_track.md | 59 --- Docs/Layers/grass_in_parks.md | 16 +- Docs/Layers/grb.md | 98 ---- Docs/Layers/hackerspaces.md | 235 +++++---- ...lth_and_social_places_without_etymology.md | 162 +++++++ Docs/Layers/home_location.md | 42 -- Docs/Layers/hydrant.md | 17 +- Docs/Layers/information_board.md | 14 +- Docs/Layers/left_right_style.md | 45 -- Docs/Layers/lit_streets.md | 113 +++-- Docs/Layers/map.md | 16 +- Docs/Layers/matchpoint.md | 45 -- Docs/Layers/maybe_climbing.md | 305 ++++++++++-- Docs/Layers/named_streets.md | 12 +- Docs/Layers/nature_reserve.md | 26 +- Docs/Layers/nature_reserve_buurtnatuur.md | 46 -- Docs/Layers/node.md | 60 --- Docs/Layers/node2node.md | 58 --- Docs/Layers/note_import.md | 19 +- Docs/Layers/observation_tower.md | 25 +- Docs/Layers/orchards.md | 37 -- Docs/Layers/osm-buildings-fixme.md | 143 ------ Docs/Layers/osm-buildings.md | 51 -- Docs/Layers/parking.md | 14 +- Docs/Layers/parks.md | 48 -- .../parks_and_forests_without_etymology.md | 162 +++++++ Docs/Layers/pedestrian_path.md | 12 +- Docs/Layers/picnic_table.md | 15 +- Docs/Layers/play_forest.md | 20 +- Docs/Layers/playground.md | 27 +- Docs/Layers/postal_code_boundary.md | 39 -- Docs/Layers/postboxes.md | 71 ++- Docs/Layers/postoffices.md | 91 ++-- Docs/Layers/public_bookcase.md | 23 +- Docs/Layers/raw_inspire_polygons.md | 39 -- Docs/Layers/recycling.md | 23 +- Docs/Layers/service_ways.md | 39 -- Docs/Layers/shadow.md | 37 -- Docs/Layers/shops.md | 23 +- Docs/Layers/sidewalks.md | 118 ----- Docs/Layers/slow_roads.md | 17 +- Docs/Layers/split_point.md | 36 -- Docs/Layers/sport_pitch.md | 23 +- Docs/Layers/sport_places_without_etymology.md | 162 +++++++ Docs/Layers/street_lamps.md | 21 +- Docs/Layers/streets_without_etymology.md | 163 +++++++ Docs/Layers/surveillance_camera.md | 21 +- Docs/Layers/to_import.md | 73 --- Docs/Layers/toekomstige_fietsstraat.md | 121 ++++- Docs/Layers/toilet.md | 27 +- .../toursistic_places_without_etymology.md | 162 +++++++ Docs/Layers/town_hall.md | 41 -- Docs/Layers/trail.md | 20 +- Docs/Layers/tree_node.md | 22 +- Docs/Layers/type_node.md | 42 -- Docs/Layers/viewpoint.md | 15 +- Docs/Layers/village_green.md | 16 +- Docs/Layers/visitor_information_centre.md | 13 +- Docs/Layers/walking_routes.md | 111 ----- Docs/Layers/walls_and_buildings.md | 12 +- Docs/Layers/waste_basket.md | 15 +- Docs/Layers/waste_disposal.md | 15 +- Docs/Layers/watermill.md | 16 +- Docs/Layers/windturbine.md | 140 ++++-- Docs/Layers/wrong_postal_code.md | 34 -- Models/ThemeConfig/LayerConfig.ts | 5 +- assets/themes/{ => etymology}/etymology.json | 0 scripts/generateDocs.ts | 19 +- 124 files changed, 4450 insertions(+), 4088 deletions(-) delete mode 100644 Docs/Layers/assen.md delete mode 100644 Docs/Layers/brugge.md delete mode 100644 Docs/Layers/conflation.md create mode 100644 Docs/Layers/cultural_places_without_etymology.md delete mode 100644 Docs/Layers/current_view.md delete mode 100644 Docs/Layers/cycle_highways.md create mode 100644 Docs/Layers/education_institutions_without_etymology.md delete mode 100644 Docs/Layers/forest.md create mode 100644 Docs/Layers/friture.md delete mode 100644 Docs/Layers/fruitboom.md delete mode 100644 Docs/Layers/generic_osm_object.md delete mode 100644 Docs/Layers/gps_location.md delete mode 100644 Docs/Layers/gps_location_history.md delete mode 100644 Docs/Layers/gps_track.md delete mode 100644 Docs/Layers/grb.md create mode 100644 Docs/Layers/health_and_social_places_without_etymology.md delete mode 100644 Docs/Layers/home_location.md delete mode 100644 Docs/Layers/left_right_style.md delete mode 100644 Docs/Layers/matchpoint.md delete mode 100644 Docs/Layers/nature_reserve_buurtnatuur.md delete mode 100644 Docs/Layers/node.md delete mode 100644 Docs/Layers/node2node.md delete mode 100644 Docs/Layers/orchards.md delete mode 100644 Docs/Layers/osm-buildings-fixme.md delete mode 100644 Docs/Layers/osm-buildings.md delete mode 100644 Docs/Layers/parks.md create mode 100644 Docs/Layers/parks_and_forests_without_etymology.md delete mode 100644 Docs/Layers/postal_code_boundary.md delete mode 100644 Docs/Layers/raw_inspire_polygons.md delete mode 100644 Docs/Layers/service_ways.md delete mode 100644 Docs/Layers/shadow.md delete mode 100644 Docs/Layers/sidewalks.md delete mode 100644 Docs/Layers/split_point.md create mode 100644 Docs/Layers/sport_places_without_etymology.md create mode 100644 Docs/Layers/streets_without_etymology.md delete mode 100644 Docs/Layers/to_import.md create mode 100644 Docs/Layers/toursistic_places_without_etymology.md delete mode 100644 Docs/Layers/town_hall.md delete mode 100644 Docs/Layers/type_node.md delete mode 100644 Docs/Layers/walking_routes.md delete mode 100644 Docs/Layers/wrong_postal_code.md rename assets/themes/{ => etymology}/etymology.json (100%) diff --git a/Customizations/AllKnownLayouts.ts b/Customizations/AllKnownLayouts.ts index 2b3ce5c651..47fbe45eed 100644 --- a/Customizations/AllKnownLayouts.ts +++ b/Customizations/AllKnownLayouts.ts @@ -37,12 +37,41 @@ export class AllKnownLayouts { return allLayers } - public static GenOverviewsForSingleLayer(callback: (layer: LayerConfig, element: BaseUIElement) => void): void { + /** + * Generates documentation for the layers. + * Inline layers are included (if the theme is public) + * @param callback + * @constructor + */ + public static GenOverviewsForSingleLayer(callback: (layer: LayerConfig, element: BaseUIElement, inlineSource: string) => void): void { const allLayers: LayerConfig[] = Array.from(AllKnownLayouts.sharedLayers.values()) .filter(layer => Constants.priviliged_layers.indexOf(layer.id) < 0) - const builtinLayerIds: Set = new Set() allLayers.forEach(l => builtinLayerIds.add(l.id)) + const inlineLayers = new Map(); + + for (const layout of Array.from(AllKnownLayouts.allKnownLayouts.values())) { + if (layout.hideFromOverview) { + continue + } + + for (const layer of layout.layers) { + + if (Constants.priviliged_layers.indexOf(layer.id) >= 0) { + continue + } + if (builtinLayerIds.has(layer.id)) { + continue + } + if(layer.source.geojsonSource !== undefined){ + // Not an OSM-source + continue + } + allLayers.push(layer) + builtinLayerIds.add(layer.id) + inlineLayers.set(layer.id, layout.id) + } + } const themesPerLayer = new Map() @@ -52,6 +81,7 @@ export class AllKnownLayouts { } for (const layer of layout.layers) { if (!builtinLayerIds.has(layer.id)) { + // This is an inline layer continue } if (!themesPerLayer.has(layer.id)) { @@ -79,10 +109,14 @@ export class AllKnownLayouts { allLayers.forEach((layer) => { const element = layer.GenerateDocumentation(themesPerLayer.get(layer.id), layerIsNeededBy, DependencyCalculator.getLayerDependencies(layer)) - callback(layer, element) + callback(layer, element, inlineLayers.get(layer.id)) }) } + /** + * Generates the documentation for the layers overview page + * @constructor + */ public static GenLayerOverviewText(): BaseUIElement { for (const id of Constants.priviliged_layers) { if (!AllKnownLayouts.sharedLayers.has(id)) { @@ -171,7 +205,7 @@ export class AllKnownLayouts { private static AllLayouts(): Map { const dict: Map = new Map(); for (const layoutConfigJson of known_themes.themes) { - const layout = new LayoutConfig( layoutConfigJson, true) + const layout = new LayoutConfig(layoutConfigJson, true) dict.set(layout.id, layout) for (let i = 0; i < layout.layers.length; i++) { let layer = layout.layers[i]; diff --git a/Docs/BuiltinLayers.md b/Docs/BuiltinLayers.md index 9fdb5cd435..2d7dc9a08c 100644 --- a/Docs/BuiltinLayers.md +++ b/Docs/BuiltinLayers.md @@ -101,13 +101,12 @@ Meta layer showing the current location of the user. Add this to your theme and + - This layer is shown at zoomlevel **0** and higher - **This layer is included automatically in every theme. This layer might contain no points** - This layer cannot be toggled in the filter view. If you import this layer in your theme, override `title` to make this toggleable. - Not visible in the layer selection by default. If you want to make this layer toggable, override `name` -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/gps_location/gps_location.json) - Basic tags for this layer @@ -145,14 +144,13 @@ Meta layer which contains the previous locations of the user as single points. T + - This layer is shown at zoomlevel **0** and higher - **This layer is included automatically in every theme. This layer might contain no points** - This layer cannot be toggled in the filter view. If you import this layer in your theme, override `title` to make this toggleable. - Not visible in the layer selection by default. If you want to make this layer toggable, override `name` - Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/gps_location_history/gps_location_history.json) - Basic tags for this layer @@ -190,13 +188,12 @@ Meta layer showing the home location of the user. The home location can be set i + - This layer is shown at zoomlevel **0** and higher - **This layer is included automatically in every theme. This layer might contain no points** - This layer cannot be toggled in the filter view. If you import this layer in your theme, override `title` to make this toggleable. - Not visible in the layer selection by default. If you want to make this layer toggable, override `name` -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/home_location/home_location.json) - Basic tags for this layer @@ -234,13 +231,12 @@ Meta layer showing the previous locations of the user as single line. Add this t + - This layer is shown at zoomlevel **0** and higher - **This layer is included automatically in every theme. This layer might contain no points** - This layer is not visible by default and must be enabled in the filter by the user. - Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/gps_track/gps_track.json) - Basic tags for this layer @@ -328,11 +324,10 @@ This is a priviliged meta_layer which exports _every_ point in OSM. This only wo + - This layer is shown at zoomlevel **18** and higher - Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/type_node/type_node.json) - Basic tags for this layer @@ -370,11 +365,10 @@ This layer shows notes on OpenStreetMap. Having this layer in your theme will tr + - This layer is shown at zoomlevel **10** and higher - This layer is loaded from an external source, namely `https://api.openstreetmap.org/api/0.6/notes.json?limit=10000&closed=7&bbox={x_min},{y_min},{x_max},{y_max}` -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/note/note.json) - Basic tags for this layer @@ -462,11 +456,10 @@ Layer used in the importHelper + - This layer is shown at zoomlevel **0** and higher - Not visible in the layer selection by default. If you want to make this layer toggable, override `name` -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/import_candidate/import_candidate.json) - Basic tags for this layer @@ -514,11 +507,10 @@ If the import-button moves OSM points, the imported way points or conflates, a p + - This layer is shown at zoomlevel **1** and higher - This layer can **not** be included in a theme. It is solely used by [special renderings](SpecialRenderings.md) showing a minimap with custom data. -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/conflation/conflation.json) - Basic tags for this layer @@ -556,11 +548,10 @@ Special meta-style which will show one single line, either on the left or on the + - This layer is shown at zoomlevel **0** and higher - This layer can **not** be included in a theme. It is solely used by [special renderings](SpecialRenderings.md) showing a minimap with custom data. -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/left_right_style/left_right_style.json) - Basic tags for this layer @@ -598,11 +589,10 @@ Layer rendering the little scissors for the minimap in the 'splitRoadWizard' + - This layer is shown at zoomlevel **1** and higher - This layer can **not** be included in a theme. It is solely used by [special renderings](SpecialRenderings.md) showing a minimap with custom data. -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/split_point/split_point.json) - Basic tags for this layer @@ -642,11 +632,10 @@ The icon on the button is the default icon of the layer, but can be customized b + - This layer is shown at zoomlevel **0** and higher - This layer can **not** be included in a theme. It is solely used by [special renderings](SpecialRenderings.md) showing a minimap with custom data. -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/current_view/current_view.json) - Basic tags for this layer @@ -684,11 +673,10 @@ The default rendering for a locationInput which snaps onto another object + - This layer is shown at zoomlevel **0** and higher - This layer can **not** be included in a theme. It is solely used by [special renderings](SpecialRenderings.md) showing a minimap with custom data. -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/matchpoint/matchpoint.json) - Basic tags for this layer diff --git a/Docs/Layers/address.md b/Docs/Layers/address.md index 8942bbdb28..92e43ca079 100644 --- a/Docs/Layers/address.md +++ b/Docs/Layers/address.md @@ -12,20 +12,9 @@ Addresses -## Table of contents - -1. [address](#address) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [housenumber](#housenumber) - + [street](#street) - + [fixme](#fixme) - - - + - This layer is shown at zoomlevel **18** and higher - This layer will automatically load [named_streets](./named_streets.md) into the layout as it depends on it: A calculated tag loads features from this layer (calculatedTag[0] which calculates the value for _closest_3_street_names) @@ -40,8 +29,6 @@ Addresses - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/address/address.json) - Basic tags for this layer diff --git a/Docs/Layers/all_streets.md b/Docs/Layers/all_streets.md index b71a3a4e4f..b914abf36b 100644 --- a/Docs/Layers/all_streets.md +++ b/Docs/Layers/all_streets.md @@ -1,62 +1,124 @@ -all_streets + + + all_streets ============= -## Table of contents - -1. [all_streets](#all_streets) - * [Themes using this layer](#themes-using-this-layer) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [lit](#lit) -- Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` + -#### Themes using this layer - -- [cyclestreets](https://mapcomplete.osm.be/cyclestreets) -- [street_lighting](https://mapcomplete.osm.be/street_lighting) - -[Go to the source code](../assets/layers/all_streets/all_streets.json) +Layer to mark any street as cyclestreet -Basic tags for this layer + + + + - This layer is shown at zoomlevel **18** and higher + + + + +#### Themes using this layer + + + + + + - [cyclestreets](https://mapcomplete.osm.be/cyclestreets) + - [street_lighting](https://mapcomplete.osm.be/street_lighting) + + + + + Basic tags for this layer --------------------------- Elements must have the all of following tags to be shown on this layer: -- highway!~^$ -- service!~^driveway$ -- highway!~^platform$ -Supported attributes + + - highway=residential|highway=tertiary|highway=unclassified + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22highway%22%3D%22residential%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22highway%22%3D%22tertiary%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22highway%22%3D%22unclassified%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes ---------------------- **Warning** This quick overview is incomplete + + attribute | type | values which are supported by this layer ----------- | ------ | ------------------------------------------ -[](https://taginfo.openstreetmap.org/keys/lit#values) [lit](https://wiki.openstreetmap.org/wiki/Key:lit) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:lit%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:lit%3Dno) [24/7](https://wiki.openstreetmap.org/wiki/Tag:lit%3D24/7) +[](https://taginfo.openstreetmap.org/keys/cyclestreet#values) [cyclestreet](https://wiki.openstreetmap.org/wiki/Key:cyclestreet) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:cyclestreet%3Dyes) [yes](https://wiki.openstreetmap.org/wiki/Tag:cyclestreet%3Dyes) [](https://wiki.openstreetmap.org/wiki/Tag:cyclestreet%3D) [](https://wiki.openstreetmap.org/wiki/Tag:cyclestreet%3D) +[](https://taginfo.openstreetmap.org/keys/cyclestreet:start_date#values) [cyclestreet:start_date](https://wiki.openstreetmap.org/wiki/Key:cyclestreet:start_date) | [date](../SpecialInputElements.md#date) | -### lit -The question is **Is this street lit?** -- **This street is lit** corresponds with lit - =yes -- **This street is not lit** corresponds with - lit=no -- **This street is lit at night** corresponds - with lit - =sunset-sunrise_This option - cannot be chosen as answer_ -- **This street is lit 24/7** corresponds with - lit=24/7 -This document is autogenerated from assets/layers/all_streets/all_streets.json \ No newline at end of file +### images + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### is_cyclestreet + + + +The question is **Is the street {name} a cyclestreet?** + + + + + + - **This street is a cyclestreet (and has a speed limit of 30 km/h)** corresponds with cyclestreet=yes&maxspeed=30&overtaking:motor_vehicle=no + - **This street is a cyclestreet** corresponds with cyclestreet=yes + - **This street will become a cyclstreet soon** corresponds with proposed:cyclestreet=yes + - **This street is not a cyclestreet** corresponds with + + + + +### future_cyclestreet + + + +The question is **When will this street become a cyclestreet?** + +This rendering asks information about the property [cyclestreet:start_date](https://wiki.openstreetmap.org/wiki/Key:cyclestreet:start_date) +This is rendered with `This street will become a cyclestreet at {cyclestreet:start_date}` + + + +### questions + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### minimap + + + +_This tagrendering has no question and is thus read-only_ + + + +This document is autogenerated from [assets/themes/cyclestreets/cyclestreets.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/cyclestreets/cyclestreets.json) \ No newline at end of file diff --git a/Docs/Layers/ambulancestation.md b/Docs/Layers/ambulancestation.md index b758afd5fc..284323f517 100644 --- a/Docs/Layers/ambulancestation.md +++ b/Docs/Layers/ambulancestation.md @@ -12,24 +12,9 @@ An ambulance station is an area for storage of ambulance vehicles, medical equip -## Table of contents - -1. [ambulancestation](#ambulancestation) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [ambulance-name](#ambulance-name) - + [ambulance-street](#ambulance-street) - + [ambulance-place](#ambulance-place) - + [ambulance-agency](#ambulance-agency) - + [ambulance-operator-type](#ambulance-operator-type) - + [images](#images) - - - - + - This layer is shown at zoomlevel **12** and higher @@ -44,8 +29,6 @@ An ambulance station is an area for storage of ambulance vehicles, medical equip - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/ambulancestation/ambulancestation.json) - Basic tags for this layer diff --git a/Docs/Layers/artwork.md b/Docs/Layers/artwork.md index 9912357991..dd57515e31 100644 --- a/Docs/Layers/artwork.md +++ b/Docs/Layers/artwork.md @@ -12,23 +12,9 @@ Diverse pieces of artwork -## Table of contents - -1. [artwork](#artwork) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [artwork-artwork_type](#artwork-artwork_type) - + [artwork-artist_name](#artwork-artist_name) - + [artwork-website](#artwork-website) - + [artwork-wikidata](#artwork-wikidata) - - - - + - This layer is shown at zoomlevel **12** and higher @@ -43,8 +29,6 @@ Diverse pieces of artwork - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/artwork/artwork.json) - Basic tags for this layer diff --git a/Docs/Layers/assen.md b/Docs/Layers/assen.md deleted file mode 100644 index 4e2f170d04..0000000000 --- a/Docs/Layers/assen.md +++ /dev/null @@ -1,38 +0,0 @@ -assen -======= - -## Table of contents - -1. [assen](#assen) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [all_tags](#all_tags) - - -- This layer is loaded from an external source, namely `https://robinlinde.github.io/tiles/assen_street_lighting/{z}/{x}/{y}.json` -- This layer will automatically load [street_lamps](./street_lamps.md) into the layout as it depends on it: A - calculated tag loads features from this layer (calculatedTag[0] which calculates the value for _ - closest_osm_street_lamp) - -[Go to the source code](../assets/layers/assen/assen.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- Lichtmastnummer~^..*$ - -Supported attributes ----------------------- - -### all_tags - -_This tagrendering has no question and is thus read-only_ - -This document is autogenerated from assets/layers/assen/assen.json \ No newline at end of file diff --git a/Docs/Layers/barrier.md b/Docs/Layers/barrier.md index a9d7c930ab..d5e9a8431a 100644 --- a/Docs/Layers/barrier.md +++ b/Docs/Layers/barrier.md @@ -12,25 +12,9 @@ Obstacles while cycling, such as bollards and cycle barriers -## Table of contents - -1. [barrier](#barrier) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [bicycle=yes/no](#bicycle=yesno) - + [barrier_type](#barrier_type) - + [Bollard type](#bollard-type) - + [Cycle barrier type](#cycle-barrier-type) - + [MaxWidth](#maxwidth) - + [Space between barrier (cyclebarrier)](#space-between-barrier-(cyclebarrier)) - + [Width of opening (cyclebarrier)](#width-of-opening-(cyclebarrier)) - + [Overlap (cyclebarrier)](#overlap-(cyclebarrier)) - - - + - This layer is shown at zoomlevel **17** and higher - This layer will automatically load [cycleways_and_roads](./cycleways_and_roads.md) into the layout as it depends on it: a preset snaps to this layer (presets[0]) - This layer will automatically load [cycleways_and_roads](./cycleways_and_roads.md) into the layout as it depends on it: a preset snaps to this layer (presets[1]) @@ -47,8 +31,6 @@ Obstacles while cycling, such as bollards and cycle barriers - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/barrier/barrier.json) - Basic tags for this layer diff --git a/Docs/Layers/bench.md b/Docs/Layers/bench.md index 5dcaeaaaea..dfc1b7d439 100644 --- a/Docs/Layers/bench.md +++ b/Docs/Layers/bench.md @@ -12,25 +12,9 @@ A bench is a wooden, metal, stone, ... surface where a human can sit. This layer -## Table of contents - -1. [bench](#bench) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [bench-backrest](#bench-backrest) - + [bench-seats](#bench-seats) - + [bench-material](#bench-material) - + [bench-direction](#bench-direction) - + [bench-colour](#bench-colour) - + [bench-survey:date](#bench-surveydate) - - - - + - This layer is shown at zoomlevel **17** and higher @@ -46,8 +30,6 @@ A bench is a wooden, metal, stone, ... surface where a human can sit. This layer - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/bench/bench.json) - Basic tags for this layer diff --git a/Docs/Layers/bench_at_pt.md b/Docs/Layers/bench_at_pt.md index 1adc09b3d1..bb4a6c34a2 100644 --- a/Docs/Layers/bench_at_pt.md +++ b/Docs/Layers/bench_at_pt.md @@ -12,21 +12,9 @@ A layer showing all public-transport-stops which do have a bench -## Table of contents - -1. [bench_at_pt](#bench_at_pt) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [bench_at_pt-name](#bench_at_pt-name) - + [bench_at_pt-bench_type](#bench_at_pt-bench_type) - - - - + - This layer is shown at zoomlevel **14** and higher @@ -41,8 +29,6 @@ A layer showing all public-transport-stops which do have a bench - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/bench_at_pt/bench_at_pt.json) - Basic tags for this layer diff --git a/Docs/Layers/bicycle_library.md b/Docs/Layers/bicycle_library.md index 411ee00db9..01fb44463d 100644 --- a/Docs/Layers/bicycle_library.md +++ b/Docs/Layers/bicycle_library.md @@ -12,27 +12,9 @@ A facility where bicycles can be lent for longer period of times -## Table of contents - -1. [bicycle_library](#bicycle_library) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [bicycle_library-name](#bicycle_library-name) - + [website](#website) - + [phone](#phone) - + [email](#email) - + [opening_hours](#opening_hours) - + [bicycle_library-charge](#bicycle_library-charge) - + [bicycle-library-target-group](#bicycle-library-target-group) - + [description](#description) - - - - + - This layer is shown at zoomlevel **8** and higher @@ -48,8 +30,6 @@ A facility where bicycles can be lent for longer period of times - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/bicycle_library/bicycle_library.json) - Basic tags for this layer diff --git a/Docs/Layers/bicycle_rental.md b/Docs/Layers/bicycle_rental.md index a1dad60365..d15437c32c 100644 --- a/Docs/Layers/bicycle_rental.md +++ b/Docs/Layers/bicycle_rental.md @@ -12,41 +12,9 @@ Bicycle rental stations -## Table of contents - -1. [bicycle_rental](#bicycle_rental) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [bicycle_rental_type](#bicycle_rental_type) - + [website](#website) - + [email](#email) - + [phone](#phone) - + [opening_hours](#opening_hours) - + [payment-options](#payment-options) - + [payment-options-advanced](#payment-options-advanced) - + [bicycle-types](#bicycle-types) - + [rental-capacity-bicycle-type](#rental-capacity-bicycle-type) - + [questions](#questions) - + [rental-capacity-bicycle-type](#rental-capacity-bicycle-type) - + [questions](#questions) - + [rental-capacity-bicycle-type](#rental-capacity-bicycle-type) - + [questions](#questions) - + [rental-capacity-bicycle-type](#rental-capacity-bicycle-type) - + [questions](#questions) - + [rental-capacity-bicycle-type](#rental-capacity-bicycle-type) - + [questions](#questions) - + [rental-capacity-bicycle-type](#rental-capacity-bicycle-type) - + [questions](#questions) - + [rental-capacity-bicycle-type](#rental-capacity-bicycle-type) - + [questions](#questions) - - - - + - This layer is shown at zoomlevel **12** and higher @@ -61,8 +29,6 @@ Bicycle rental stations - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/bicycle_rental/bicycle_rental.json) - Basic tags for this layer @@ -264,16 +230,6 @@ This is rendered with `{capacity:city_bike} city bikes can be rented here` -### questions - - - -_This tagrendering has no question and is thus read-only_ - - - - - ### rental-capacity-bicycle-type @@ -285,16 +241,6 @@ This is rendered with `{capacity:ebike} electrical bikes can be rented here` -### questions - - - -_This tagrendering has no question and is thus read-only_ - - - - - ### rental-capacity-bicycle-type @@ -306,16 +252,6 @@ This is rendered with `{capacity:kid_bike} bikes for children can be rented here -### questions - - - -_This tagrendering has no question and is thus read-only_ - - - - - ### rental-capacity-bicycle-type @@ -327,16 +263,6 @@ This is rendered with `{capacity:bmx} BMX bikes can be rented here` -### questions - - - -_This tagrendering has no question and is thus read-only_ - - - - - ### rental-capacity-bicycle-type @@ -348,16 +274,6 @@ This is rendered with `{capacity:mtb} mountainbike can be rented here` -### questions - - - -_This tagrendering has no question and is thus read-only_ - - - - - ### rental-capacity-bicycle-type @@ -369,16 +285,6 @@ This is rendered with `{capacity:bicycle_pannier} bicycle panniers can be rented -### questions - - - -_This tagrendering has no question and is thus read-only_ - - - - - ### rental-capacity-bicycle-type @@ -386,16 +292,6 @@ _This tagrendering has no question and is thus read-only_ The question is **How much tandem can be rented here? ** This rendering asks information about the property [capacity:tandem_bicycle](https://wiki.openstreetmap.org/wiki/Key:capacity:tandem_bicycle) -This is rendered with `{capacity:tandem_bicycle} tandem can be rented here` - - - -### questions - - - -_This tagrendering has no question and is thus read-only_ - - +This is rendered with `{capacity:tandem_bicycle} tandem can be rented here` This document is autogenerated from [assets/layers/bicycle_rental/bicycle_rental.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/bicycle_rental/bicycle_rental.json) \ No newline at end of file diff --git a/Docs/Layers/bicycle_tube_vending_machine.md b/Docs/Layers/bicycle_tube_vending_machine.md index e1763f18ae..ea47507c93 100644 --- a/Docs/Layers/bicycle_tube_vending_machine.md +++ b/Docs/Layers/bicycle_tube_vending_machine.md @@ -12,25 +12,9 @@ A layer showing vending machines for bicycle tubes (either purpose-built bicycle -## Table of contents - -1. [bicycle_tube_vending_machine](#bicycle_tube_vending_machine) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [Still in use?](#still-in-use) - + [bicycle_tube_vending_machine-charge](#bicycle_tube_vending_machine-charge) - + [vending-machine-payment-methods](#vending-machine-payment-methods) - + [bicycle_tube_vending_machine-brand](#bicycle_tube_vending_machine-brand) - + [bicycle_tube_vending_machine-operator](#bicycle_tube_vending_machine-operator) - + [bicycle_tube_vending_maching-other-items](#bicycle_tube_vending_maching-other-items) - - - - + - This layer is shown at zoomlevel **13** and higher @@ -45,8 +29,6 @@ A layer showing vending machines for bicycle tubes (either purpose-built bicycle - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json) - Basic tags for this layer diff --git a/Docs/Layers/bike_cafe.md b/Docs/Layers/bike_cafe.md index 2c4f0142f5..c7e07882c5 100644 --- a/Docs/Layers/bike_cafe.md +++ b/Docs/Layers/bike_cafe.md @@ -12,27 +12,9 @@ A bike café is a café geared towards cyclists, for example with services such -## Table of contents - -1. [bike_cafe](#bike_cafe) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [bike_cafe-name](#bike_cafe-name) - + [bike_cafe-bike-pump](#bike_cafe-bike-pump) - + [bike_cafe-repair-tools](#bike_cafe-repair-tools) - + [bike_cafe-repair-service](#bike_cafe-repair-service) - + [bike_cafe-website](#bike_cafe-website) - + [bike_cafe-phone](#bike_cafe-phone) - + [bike_cafe-email](#bike_cafe-email) - + [bike_cafe-opening_hours](#bike_cafe-opening_hours) - - - - + - This layer is shown at zoomlevel **13** and higher @@ -47,8 +29,6 @@ A bike café is a café geared towards cyclists, for example with services such - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/bike_cafe/bike_cafe.json) - Basic tags for this layer diff --git a/Docs/Layers/bike_cleaning.md b/Docs/Layers/bike_cleaning.md index d19a00e772..f1fffea816 100644 --- a/Docs/Layers/bike_cleaning.md +++ b/Docs/Layers/bike_cleaning.md @@ -12,21 +12,9 @@ A layer showing facilities where one can clean their bike -## Table of contents - -1. [bike_cleaning](#bike_cleaning) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [bike_cleaning-service:bicycle:cleaning:charge](#bike_cleaning-servicebicycle:cleaning:charge) - + [bike_cleaning-charge](#bike_cleaning-charge) - - - - + - This layer is shown at zoomlevel **13** and higher @@ -41,8 +29,6 @@ A layer showing facilities where one can clean their bike - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/bike_cleaning/bike_cleaning.json) - Basic tags for this layer diff --git a/Docs/Layers/bike_parking.md b/Docs/Layers/bike_parking.md index 3fa0875ffe..b4bf1c4c38 100644 --- a/Docs/Layers/bike_parking.md +++ b/Docs/Layers/bike_parking.md @@ -12,26 +12,9 @@ A layer showing where you can park your bike -## Table of contents - -1. [bike_parking](#bike_parking) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [Bicycle parking type](#bicycle-parking-type) - + [Underground?](#underground) - + [Is covered?](#is-covered) - + [Capacity](#capacity) - + [Access](#access) - + [Cargo bike spaces?](#cargo-bike-spaces) - + [Cargo bike capacity?](#cargo-bike-capacity) - - - - + - This layer is shown at zoomlevel **17** and higher @@ -46,8 +29,6 @@ A layer showing where you can park your bike - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/bike_parking/bike_parking.json) - Basic tags for this layer diff --git a/Docs/Layers/bike_repair_station.md b/Docs/Layers/bike_repair_station.md index 15279c0d91..69a39283c9 100644 --- a/Docs/Layers/bike_repair_station.md +++ b/Docs/Layers/bike_repair_station.md @@ -12,33 +12,9 @@ A layer showing bicycle pumps and bicycle repair tool stands -## Table of contents - -1. [bike_repair_station](#bike_repair_station) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [bike_repair_station-available-services](#bike_repair_station-available-services) - + [Operational status](#operational-status) - + [bike_repair_station-opening_hours](#bike_repair_station-opening_hours) - + [access](#access) - + [bike_repair_station-operator](#bike_repair_station-operator) - + [bike_repair_station-email](#bike_repair_station-email) - + [bike_repair_station-phone](#bike_repair_station-phone) - + [bike_repair_station-bike-chain-tool](#bike_repair_station-bike-chain-tool) - + [bike_repair_station-bike-stand](#bike_repair_station-bike-stand) - + [Email maintainer](#email-maintainer) - + [bike_repair_station-valves](#bike_repair_station-valves) - + [bike_repair_station-electrical_pump](#bike_repair_station-electrical_pump) - + [bike_repair_station-manometer](#bike_repair_station-manometer) - + [level](#level) - - - - + - This layer is shown at zoomlevel **13** and higher @@ -53,8 +29,6 @@ A layer showing bicycle pumps and bicycle repair tool stands - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/bike_repair_station/bike_repair_station.json) - Basic tags for this layer diff --git a/Docs/Layers/bike_shop.md b/Docs/Layers/bike_shop.md index 4cbae7ee15..dc89d8c22d 100644 --- a/Docs/Layers/bike_shop.md +++ b/Docs/Layers/bike_shop.md @@ -12,35 +12,9 @@ A shop specifically selling bicycles or related items -## Table of contents - -1. [bike_shop](#bike_shop) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [bike_shop-is-bicycle_shop](#bike_shop-is-bicycle_shop) - + [bike_shop-name](#bike_shop-name) - + [bike_shop-website](#bike_shop-website) - + [bike_shop-phone](#bike_shop-phone) - + [bike_shop-email](#bike_shop-email) - + [opening_hours](#opening_hours) - + [description](#description) - + [bike_shop-access](#bike_shop-access) - + [bike_repair_sells-bikes](#bike_repair_sells-bikes) - + [bike_repair_repairs-bikes](#bike_repair_repairs-bikes) - + [bike_repair_rents-bikes](#bike_repair_rents-bikes) - + [bike_repair_second-hand-bikes](#bike_repair_second-hand-bikes) - + [bike_repair_bike-pump-service](#bike_repair_bike-pump-service) - + [bike_repair_tools-service](#bike_repair_tools-service) - + [bike_repair_bike-wash](#bike_repair_bike-wash) - + [bike_cleaning-service:bicycle:cleaning:charge](#bike_cleaning-servicebicycle:cleaning:charge) - - - - + - This layer is shown at zoomlevel **13** and higher @@ -55,8 +29,6 @@ A shop specifically selling bicycles or related items - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/bike_shop/bike_shop.json) - Basic tags for this layer diff --git a/Docs/Layers/bike_themed_object.md b/Docs/Layers/bike_themed_object.md index 4e7129bac7..2884b5fc07 100644 --- a/Docs/Layers/bike_themed_object.md +++ b/Docs/Layers/bike_themed_object.md @@ -12,24 +12,9 @@ A layer with bike-themed objects but who don't match any other layer -## Table of contents - -1. [bike_themed_object](#bike_themed_object) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [description](#description) - + [website](#website) - + [email](#email) - + [phone](#phone) - + [opening_hours](#opening_hours) - - - - + - This layer is shown at zoomlevel **13** and higher @@ -44,8 +29,6 @@ A layer with bike-themed objects but who don't match any other layer - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/bike_themed_object/bike_themed_object.json) - Basic tags for this layer diff --git a/Docs/Layers/binocular.md b/Docs/Layers/binocular.md index fb06b4b920..743d20f71d 100644 --- a/Docs/Layers/binocular.md +++ b/Docs/Layers/binocular.md @@ -12,21 +12,9 @@ Binoculas -## Table of contents - -1. [binocular](#binocular) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [binocular-charge](#binocular-charge) - + [binocular-direction](#binocular-direction) - - - - + - This layer is shown at zoomlevel **0** and higher @@ -41,8 +29,6 @@ Binoculas - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/binocular/binocular.json) - Basic tags for this layer diff --git a/Docs/Layers/birdhide.md b/Docs/Layers/birdhide.md index 87d99425fe..2152b24486 100644 --- a/Docs/Layers/birdhide.md +++ b/Docs/Layers/birdhide.md @@ -12,22 +12,9 @@ A birdhide -## Table of contents - -1. [birdhide](#birdhide) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [bird-hide-shelter-or-wall](#bird-hide-shelter-or-wall) - + [bird-hide-wheelchair](#bird-hide-wheelchair) - + [birdhide-operator](#birdhide-operator) - - - - + - This layer is shown at zoomlevel **14** and higher @@ -42,8 +29,6 @@ A birdhide - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/birdhide/birdhide.json) - Basic tags for this layer diff --git a/Docs/Layers/brugge.md b/Docs/Layers/brugge.md deleted file mode 100644 index fdddb6acd6..0000000000 --- a/Docs/Layers/brugge.md +++ /dev/null @@ -1,73 +0,0 @@ -brugge -======== - -## Table of contents - -1. [brugge](#brugge) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [status](#status) - + [has closeby](#has-closeby) - + [openbaar](#openbaar) - + [addr](#addr) - + [oh](#oh) - - -- This layer is loaded from an external source, namely `https://raw.githubusercontent.com/pietervdvn/pietervdvn.github.io/master/aeds_brugge.json` -- This layer will automatically load [defibrillator](./defibrillator.md) into the layout as it depends on it: A - calculated tag loads features from this layer (calculatedTag[0] which calculates the value for _closest_osm_aed) - -[Go to the source code](../assets/layers/brugge/brugge.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- Brugs volgnummer~^..*$ - -Supported attributes ----------------------- - - - -**Warning** This quick overview is incomplete - -attribute | type | values which are supported by this layer ------------ | ------ | ------------------------------------------ -[](https://taginfo.openstreetmap.org/keys/status#values) [status](https://wiki.openstreetmap.org/wiki/Key:status) | Multiple choice | [oud](https://wiki.openstreetmap.org/wiki/Tag:status%3Doud) -[](https://taginfo.openstreetmap.org/keys/Lokaal AED#values) [Lokaal AED](https://wiki.openstreetmap.org/wiki/Key:Lokaal AED) | Multiple choice | - -### status - -_This tagrendering has no question and is thus read-only_ - -- **
Dit datapunt is verouderd
** corresponds - with status - =oud - -### has closeby - -_This tagrendering has no question and is thus read-only_ - -### openbaar - -_This tagrendering has no question and is thus read-only_ - -- **Bevindt zich in een openbaar gebouw: {Openbare AED Gebouw} in lokaal {Lokaal AED}** corresponds with - Lokaal AED~^..*$ - -### addr - -_This tagrendering has no question and is thus read-only_ - -### oh - -_This tagrendering has no question and is thus read-only_ - -This document is autogenerated from assets/layers/brugge/brugge.json \ No newline at end of file diff --git a/Docs/Layers/cafe_pub.md b/Docs/Layers/cafe_pub.md index 5bbe7c791f..7fb6e3a368 100644 --- a/Docs/Layers/cafe_pub.md +++ b/Docs/Layers/cafe_pub.md @@ -12,29 +12,9 @@ A layer showing cafés and pubs where one can gather around a drink. The layer a -## Table of contents - -1. [cafe_pub](#cafe_pub) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [Name](#name) - + [Classification](#classification) - + [opening_hours](#opening_hours) - + [website](#website) - + [email](#email) - + [phone](#phone) - + [payment-options](#payment-options) - + [wheelchair-access](#wheelchair-access) - + [service:electricity](#serviceelectricity) - + [dog-access](#dog-access) - - - - + - This layer is shown at zoomlevel **0** and higher @@ -49,8 +29,6 @@ A layer showing cafés and pubs where one can gather around a drink. The layer a - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/cafe_pub/cafe_pub.json) - Basic tags for this layer diff --git a/Docs/Layers/caravansites.md b/Docs/Layers/caravansites.md index a46f676c71..99d105517a 100644 --- a/Docs/Layers/caravansites.md +++ b/Docs/Layers/caravansites.md @@ -1,196 +1,306 @@ -caravansites + + + caravansites ============== - + camper sites -## Table of contents - -1. [caravansites](#caravansites) - * [Themes using this layer](#themes-using-this-layer) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [images](#images) - + [caravansites-name](#caravansites-name) - + [caravansites-fee](#caravansites-fee) - + [caravansites-charge](#caravansites-charge) - + [caravansites-sanitary-dump](#caravansites-sanitary-dump) - + [caravansites-capacity](#caravansites-capacity) - + [caravansites-internet](#caravansites-internet) - + [caravansites-internet-fee](#caravansites-internet-fee) - + [caravansites-toilets](#caravansites-toilets) - + [caravansites-website](#caravansites-website) - + [caravansites-long-term](#caravansites-long-term) - + [caravansites-description](#caravansites-description) - + [questions](#questions) - + [reviews](#reviews) - -#### Themes using this layer - -- [campersite](https://mapcomplete.osm.be/campersite) - -[Go to the source code](../assets/layers/caravansites/caravansites.json) -Basic tags for this layer + + + - This layer is shown at zoomlevel **10** and higher + + + + +#### Themes using this layer + + + + + + - [campersite](https://mapcomplete.osm.be/campersite) + + + + + Basic tags for this layer --------------------------- Elements must have the all of following tags to be shown on this layer: -- tourism - =caravan_site -- permanent_camping!~^only$ -Supported attributes + + - tourism=caravan_site + - permanent_camping!~^only$ + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22tourism%22%3D%22caravan_site%22%5D%5B%22permanent_camping%22!~%22%5Eonly%24%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes ---------------------- **Warning** This quick overview is incomplete + + attribute | type | values which are supported by this layer ----------- | ------ | ------------------------------------------ -[](https://taginfo.openstreetmap.org/keys/name#values) [name](https://wiki.openstreetmap.org/wiki/Key:name) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/name#values) [name](https://wiki.openstreetmap.org/wiki/Key:name) | [string](../SpecialInputElements.md#string) | [](https://taginfo.openstreetmap.org/keys/fee#values) [fee](https://wiki.openstreetmap.org/wiki/Key:fee) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:fee%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:fee%3Dno) -[](https://taginfo.openstreetmap.org/keys/charge#values) [charge](https://wiki.openstreetmap.org/wiki/Key:charge) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/charge#values) [charge](https://wiki.openstreetmap.org/wiki/Key:charge) | [string](../SpecialInputElements.md#string) | [](https://taginfo.openstreetmap.org/keys/sanitary_dump_station#values) [sanitary_dump_station](https://wiki.openstreetmap.org/wiki/Key:sanitary_dump_station) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:sanitary_dump_station%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:sanitary_dump_station%3Dno) -[](https://taginfo.openstreetmap.org/keys/capacity#values) [capacity](https://wiki.openstreetmap.org/wiki/Key:capacity) | [pnat](../SpecialInputElements.md#pnat) | +[](https://taginfo.openstreetmap.org/keys/capacity#values) [capacity](https://wiki.openstreetmap.org/wiki/Key:capacity) | [pnat](../SpecialInputElements.md#pnat) | [](https://taginfo.openstreetmap.org/keys/internet_access#values) [internet_access](https://wiki.openstreetmap.org/wiki/Key:internet_access) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:internet_access%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:internet_access%3Dno) [](https://taginfo.openstreetmap.org/keys/internet_access:fee#values) [internet_access:fee](https://wiki.openstreetmap.org/wiki/Key:internet_access:fee) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:internet_access:fee%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:internet_access:fee%3Dno) [](https://taginfo.openstreetmap.org/keys/toilets#values) [toilets](https://wiki.openstreetmap.org/wiki/Key:toilets) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:toilets%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:toilets%3Dno) -[](https://taginfo.openstreetmap.org/keys/website#values) [website](https://wiki.openstreetmap.org/wiki/Key:website) | [url](../SpecialInputElements.md#url) | +[](https://taginfo.openstreetmap.org/keys/website#values) [website](https://wiki.openstreetmap.org/wiki/Key:website) | [url](../SpecialInputElements.md#url) | [](https://taginfo.openstreetmap.org/keys/permanent_camping#values) [permanent_camping](https://wiki.openstreetmap.org/wiki/Key:permanent_camping) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:permanent_camping%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:permanent_camping%3Dno) [only](https://wiki.openstreetmap.org/wiki/Tag:permanent_camping%3Donly) -[](https://taginfo.openstreetmap.org/keys/description#values) [description](https://wiki.openstreetmap.org/wiki/Key:description) | [text](../SpecialInputElements.md#text) | +[](https://taginfo.openstreetmap.org/keys/description#values) [description](https://wiki.openstreetmap.org/wiki/Key:description) | [text](../SpecialInputElements.md#text) | +[](https://taginfo.openstreetmap.org/keys/operator#values) [operator](https://wiki.openstreetmap.org/wiki/Key:operator) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/power_supply#values) [power_supply](https://wiki.openstreetmap.org/wiki/Key:power_supply) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:power_supply%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:power_supply%3Dno) + + + + +### images + -### images _This tagrendering has no question and is thus read-only_ -### caravansites-name + + + + +### caravansites-name + + The question is **What is this place called?** -This rendering asks information about the property [name](https://wiki.openstreetmap.org/wiki/Key:name) +This rendering asks information about the property [name](https://wiki.openstreetmap.org/wiki/Key:name) This is rendered with `This place is called {name}` -### caravansites-fee + + +### caravansites-fee + + The question is **Does this place charge a fee?** -- **You need to pay for use** corresponds with - fee=yes -- **Can be used for free** corresponds with - fee=no -- **Can be used for free** corresponds with - fee=no_This option cannot be chosen - as answer_ -### caravansites-charge + + + + - **You need to pay for use** corresponds with fee=yes + - **Can be used for free** corresponds with fee=no + + + + +### caravansites-charge + + The question is **How much does this place charge?** -This rendering asks information about the property [charge](https://wiki.openstreetmap.org/wiki/Key:charge) +This rendering asks information about the property [charge](https://wiki.openstreetmap.org/wiki/Key:charge) This is rendered with `This place charges {charge}` -### caravansites-sanitary-dump + + +### caravansites-sanitary-dump + + The question is **Does this place have a sanitary dump station?** -- **This place has a sanitary dump station** corresponds - with sanitary_dump_station - =yes -- **This place does not have a sanitary dump station** corresponds - with sanitary_dump_station - =no -### caravansites-capacity + + + + - **This place has a sanitary dump station** corresponds with sanitary_dump_station=yes + - **This place does not have a sanitary dump station** corresponds with sanitary_dump_station=no + + + + +### caravansites-capacity + + The question is **How many campers can stay here? (skip if there is no obvious number of spaces or allowed vehicles)** -This rendering asks information about the property [capacity](https://wiki.openstreetmap.org/wiki/Key:capacity) +This rendering asks information about the property [capacity](https://wiki.openstreetmap.org/wiki/Key:capacity) This is rendered with `{capacity} campers can use this place at the same time` -### caravansites-internet + + +### caravansites-internet + + The question is **Does this place provide internet access?** -- **There is internet access** corresponds - with internet_access - =yes -- **There is internet access** corresponds - with internet_access - =wifi - |internet_access - =wlan_This option cannot - be chosen as answer_ -- **There is no internet access** corresponds - with internet_access - =no -### caravansites-internet-fee + + + + - **There is internet access** corresponds with internet_access=yes + - **There is internet access** corresponds with internet_access=wifi|internet_access=wlan_This option cannot be chosen as answer_ + - **There is no internet access** corresponds with internet_access=no + + + + +### caravansites-internet-fee + + The question is **Do you have to pay for the internet access?** -- **You need to pay extra for internet access** corresponds - with internet_access:fee - =yes -- **You do not need to pay extra for internet access** corresponds - with internet_access:fee - =no -### caravansites-toilets + + + + - **You need to pay extra for internet access** corresponds with internet_access:fee=yes + - **You do not need to pay extra for internet access** corresponds with internet_access:fee=no + + + + +### caravansites-toilets + + The question is **Does this place have toilets?** -- **This place has toilets** corresponds with - toilets=yes -- **This place does not have toilets** corresponds - with toilets - =no -### caravansites-website + + + + - **This place has toilets** corresponds with toilets=yes + - **This place does not have toilets** corresponds with toilets=no + + + + +### caravansites-website + + The question is **Does this place have a website?** -This rendering asks information about the property [website](https://wiki.openstreetmap.org/wiki/Key:website) +This rendering asks information about the property [website](https://wiki.openstreetmap.org/wiki/Key:website) This is rendered with `Official website: {website}` -### caravansites-long-term + + +### caravansites-long-term + + The question is **Does this place offer spots for long term rental?** -- **Yes, there are some spots for long term rental, but you can also stay on a daily basis** corresponds - with permanent_camping - =yes -- **No, there are no permanent guests here** corresponds - with permanent_camping - =no -- **It is only possible to stay here if you have a long term contract(this place will disappear from this map if you - choose this)** corresponds with - permanent_camping= - only -### caravansites-description -The question is **Would you like to add a general description of this place? (Do not repeat information previously asked -or shown above. Please keep it objective - opinions go into the reviews)** -This rendering asks information about the property [description](https://wiki.openstreetmap.org/wiki/Key:description) + + - **Yes, there are some spots for long term rental, but you can also stay on a daily basis** corresponds with permanent_camping=yes + - **No, there are no permanent guests here** corresponds with permanent_camping=no + - **It is only possible to stay here if you have a long term contract(this place will disappear from this map if you choose this)** corresponds with permanent_camping=only + + + + +### caravansites-description + + + +The question is **Would you like to add a general description of this place? (Do not repeat information previously asked or shown above. Please keep it objective - opinions go into the reviews)** + +This rendering asks information about the property [description](https://wiki.openstreetmap.org/wiki/Key:description) This is rendered with `More details about this place: {description}` -### questions + + +### questions + + _This tagrendering has no question and is thus read-only_ -### reviews + + + + +### reviews + + _This tagrendering has no question and is thus read-only_ -This document is autogenerated from assets/layers/caravansites/caravansites.json \ No newline at end of file + + + + +### operator + + + +The question is **Who operates this place?** + +This rendering asks information about the property [operator](https://wiki.openstreetmap.org/wiki/Key:operator) +This is rendered with `This place is operated by {operator}` + + + +### power_supply + + + +The question is **Does this place have a power supply?** + + + + + + - **This place has a power supply** corresponds with power_supply=yes + - **This place does not have power supply** corresponds with power_supply=no + + + + +### questions + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### minimap + + + +_This tagrendering has no question and is thus read-only_ + + + +This document is autogenerated from [assets/themes/campersite/campersite.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/campersite/campersite.json) \ No newline at end of file diff --git a/Docs/Layers/charging_station.md b/Docs/Layers/charging_station.md index e518c60447..e0b3838a49 100644 --- a/Docs/Layers/charging_station.md +++ b/Docs/Layers/charging_station.md @@ -12,105 +12,9 @@ A charging station -## Table of contents - -1. [charging_station](#charging_station) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [Type](#type) - + [access](#access) - + [capacity](#capacity) - + [Available_charging_stations (generated)](#available_charging_stations-(generated)) - + [plugs-0](#plugs-0) - + [plugs-1](#plugs-1) - + [plugs-2](#plugs-2) - + [plugs-3](#plugs-3) - + [plugs-4](#plugs-4) - + [plugs-5](#plugs-5) - + [plugs-6](#plugs-6) - + [plugs-7](#plugs-7) - + [plugs-8](#plugs-8) - + [plugs-9](#plugs-9) - + [plugs-10](#plugs-10) - + [plugs-11](#plugs-11) - + [plugs-12](#plugs-12) - + [plugs-13](#plugs-13) - + [plugs-14](#plugs-14) - + [plugs-15](#plugs-15) - + [voltage-0](#voltage-0) - + [current-0](#current-0) - + [power-output-0](#power-output-0) - + [voltage-1](#voltage-1) - + [current-1](#current-1) - + [power-output-1](#power-output-1) - + [voltage-2](#voltage-2) - + [current-2](#current-2) - + [power-output-2](#power-output-2) - + [voltage-3](#voltage-3) - + [current-3](#current-3) - + [power-output-3](#power-output-3) - + [voltage-4](#voltage-4) - + [current-4](#current-4) - + [power-output-4](#power-output-4) - + [voltage-5](#voltage-5) - + [current-5](#current-5) - + [power-output-5](#power-output-5) - + [voltage-6](#voltage-6) - + [current-6](#current-6) - + [power-output-6](#power-output-6) - + [voltage-7](#voltage-7) - + [current-7](#current-7) - + [power-output-7](#power-output-7) - + [voltage-8](#voltage-8) - + [current-8](#current-8) - + [power-output-8](#power-output-8) - + [voltage-9](#voltage-9) - + [current-9](#current-9) - + [power-output-9](#power-output-9) - + [voltage-10](#voltage-10) - + [current-10](#current-10) - + [power-output-10](#power-output-10) - + [voltage-11](#voltage-11) - + [current-11](#current-11) - + [power-output-11](#power-output-11) - + [voltage-12](#voltage-12) - + [current-12](#current-12) - + [power-output-12](#power-output-12) - + [voltage-13](#voltage-13) - + [current-13](#current-13) - + [power-output-13](#power-output-13) - + [voltage-14](#voltage-14) - + [current-14](#current-14) - + [power-output-14](#power-output-14) - + [voltage-15](#voltage-15) - + [current-15](#current-15) - + [power-output-15](#power-output-15) - + [OH](#oh) - + [fee](#fee) - + [charge](#charge) - + [payment-options-advanced](#payment-options-advanced) - + [Authentication](#authentication) - + [Auth phone](#auth-phone) - + [maxstay](#maxstay) - + [Network](#network) - + [Operator](#operator) - + [phone](#phone) - + [email](#email) - + [website](#website) - + [level](#level) - + [ref](#ref) - + [Operational status](#operational-status) - + [Parking:fee](#parkingfee) - + [questions](#questions) - + [questions](#questions) - - - - + - This layer is shown at zoomlevel **10** and higher @@ -125,8 +29,6 @@ A charging station - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/charging_station/charging_station.json) - Basic tags for this layer diff --git a/Docs/Layers/climbing.md b/Docs/Layers/climbing.md index 3a77e5d9bb..4d89002e30 100644 --- a/Docs/Layers/climbing.md +++ b/Docs/Layers/climbing.md @@ -1,4 +1,6 @@ -climbing + + + climbing ========== @@ -7,125 +9,378 @@ climbing A climbing opportunity -## Table of contents - -1. [climbing](#climbing) - * [Themes using this layer](#themes-using-this-layer) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [images](#images) - + [questions](#questions) - + [minimap](#minimap) - + [Contained routes length hist](#contained-routes-length-hist) - + [Contained routes hist](#contained-routes-hist) - + [Contained_climbing_routes](#contained_climbing_routes) - + [name](#name) - + [Type](#type) - + [Rock type (crag/rock/cliff only)](#rock-type-(cragrock/cliff-only)) - + [reviews](#reviews) - - -- This layer will automatically load [climbing_route](./climbing_route.md) into the layout as it depends on it: A - calculated tag loads features from this layer (calculatedTag[0] which calculates the value for _ - contained_climbing_routes_properties) - -#### Themes using this layer - -- [climbing](https://mapcomplete.osm.be/climbing) - -[Go to the source code](../assets/layers/climbing/climbing.json) -Basic tags for this layer + + + - This layer is shown at zoomlevel **10** and higher + - This layer will automatically load [climbing](./climbing.md) into the layout as it depends on it: A calculated tag loads features from this layer (calculatedTag[0] which calculates the value for _embedding_feature_properties) + - This layer will automatically load [climbing_route](./climbing_route.md) into the layout as it depends on it: A calculated tag loads features from this layer (calculatedTag[8] which calculates the value for _contained_climbing_routes_properties) + - This layer is needed as dependency for layer [climbing_club](#climbing_club) + - This layer is needed as dependency for layer [climbing_gym](#climbing_gym) + - This layer is needed as dependency for layer [climbing_route](#climbing_route) + - This layer is needed as dependency for layer [climbing](#climbing) + - This layer is needed as dependency for layer [maybe_climbing](#maybe_climbing) + + + + +#### Themes using this layer + + + + + + - [climbing](https://mapcomplete.osm.be/climbing) + + + + + Basic tags for this layer --------------------------- Elements must have the all of following tags to be shown on this layer: -- sport - =climbing -- climbing!~^route$ -- leisure!~^sports_centre$ -- climbing!~^route_top$ -- climbing!~^route_bottom$ -Supported attributes + + - sport=climbing + - climbing!~^route$ + - leisure!~^sports_centre$ + - climbing!~^route_top$ + - climbing!~^route_bottom$ + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22sport%22%3D%22climbing%22%5D%5B%22climbing%22!~%22%5Eroute%24%22%5D%5B%22climbing%22!~%22%5Eroute_top%24%22%5D%5B%22climbing%22!~%22%5Eroute_bottom%24%22%5D%5B%22leisure%22!~%22%5Esports_centre%24%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes ---------------------- **Warning** This quick overview is incomplete + + attribute | type | values which are supported by this layer ----------- | ------ | ------------------------------------------ [](https://taginfo.openstreetmap.org/keys/name#values) [name](https://wiki.openstreetmap.org/wiki/Key:name) | [string](../SpecialInputElements.md#string) | [](https://wiki.openstreetmap.org/wiki/Tag:name%3D) [](https://taginfo.openstreetmap.org/keys/climbing#values) [climbing](https://wiki.openstreetmap.org/wiki/Key:climbing) | Multiple choice | [boulder](https://wiki.openstreetmap.org/wiki/Tag:climbing%3Dboulder) [crag](https://wiki.openstreetmap.org/wiki/Tag:climbing%3Dcrag) [area](https://wiki.openstreetmap.org/wiki/Tag:climbing%3Darea) [](https://taginfo.openstreetmap.org/keys/rock#values) [rock](https://wiki.openstreetmap.org/wiki/Key:rock) | [string](../SpecialInputElements.md#string) | [limestone](https://wiki.openstreetmap.org/wiki/Tag:rock%3Dlimestone) +[](https://taginfo.openstreetmap.org/keys/url#values) [url](https://wiki.openstreetmap.org/wiki/Key:url) | [url](../SpecialInputElements.md#url) | +[](https://taginfo.openstreetmap.org/keys/_embedding_feature:access#values) [_embedding_feature:access](https://wiki.openstreetmap.org/wiki/Key:_embedding_feature:access) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dyes) [permit](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dpermit) [customers](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dcustomers) [members](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dmembers) [no](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dno) +[](https://taginfo.openstreetmap.org/keys/access#values) [access](https://wiki.openstreetmap.org/wiki/Key:access) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:access%3Dyes) [permit](https://wiki.openstreetmap.org/wiki/Tag:access%3Dpermit) [customers](https://wiki.openstreetmap.org/wiki/Tag:access%3Dcustomers) [members](https://wiki.openstreetmap.org/wiki/Tag:access%3Dmembers) [no](https://wiki.openstreetmap.org/wiki/Tag:access%3Dno) +[](https://taginfo.openstreetmap.org/keys/access:description#values) [access:description](https://wiki.openstreetmap.org/wiki/Key:access:description) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/climbing:length#values) [climbing:length](https://wiki.openstreetmap.org/wiki/Key:climbing:length) | [pnat](../SpecialInputElements.md#pnat) | +[](https://taginfo.openstreetmap.org/keys/climbing:grade:french:min#values) [climbing:grade:french:min](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:min) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/climbing:grade:french:max#values) [climbing:grade:french:max](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:max) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/climbing:boulder#values) [climbing:boulder](https://wiki.openstreetmap.org/wiki/Key:climbing:boulder) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:boulder%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:boulder%3Dno) [limited](https://wiki.openstreetmap.org/wiki/Tag:climbing:boulder%3Dlimited) +[](https://taginfo.openstreetmap.org/keys/climbing:toprope#values) [climbing:toprope](https://wiki.openstreetmap.org/wiki/Key:climbing:toprope) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:toprope%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:toprope%3Dno) +[](https://taginfo.openstreetmap.org/keys/climbing:sport#values) [climbing:sport](https://wiki.openstreetmap.org/wiki/Key:climbing:sport) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:sport%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:sport%3Dno) +[](https://taginfo.openstreetmap.org/keys/climbing:traditional#values) [climbing:traditional](https://wiki.openstreetmap.org/wiki/Key:climbing:traditional) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:traditional%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:traditional%3Dno) +[](https://taginfo.openstreetmap.org/keys/climbing:speed#values) [climbing:speed](https://wiki.openstreetmap.org/wiki/Key:climbing:speed) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:speed%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:speed%3Dno) + + + + +### images + -### images _This tagrendering has no question and is thus read-only_ -### questions + + + + +### questions + + _This tagrendering has no question and is thus read-only_ -### minimap + + + + +### minimap + + _This tagrendering has no question and is thus read-only_ -### Contained routes length hist + + + + +### Contained routes length hist + + _This tagrendering has no question and is thus read-only_ -### Contained routes hist + + + + +### Contained routes hist + + _This tagrendering has no question and is thus read-only_ -### Contained_climbing_routes + + + + +### Contained_climbing_routes + + _This tagrendering has no question and is thus read-only_ -### name + + + + +### name + + The question is **What is the name of this climbing opportunity?** -This rendering asks information about the property [name](https://wiki.openstreetmap.org/wiki/Key:name) +This rendering asks information about the property [name](https://wiki.openstreetmap.org/wiki/Key:name) This is rendered with `{name}` -- **This climbing opportunity doesn't have a name** corresponds - with noname - =yes -### Type + + - **This climbing opportunity doesn't have a name** corresponds with noname=yes + + + + +### Type + + The question is **What kind of climbing opportunity is this?** -- **A climbing boulder - a single rock or cliff with one or a few climbing routes which can be climbed safely without - rope** corresponds with climbing - =boulder -- **A climbing crag - a single rock or cliff with at least a few climbing routes** corresponds - with climbing - =crag -- **A climbing area with one or more climbing crags and/or boulders** corresponds - with climbing - =area -### Rock type (crag/rock/cliff only) + + + + - **A climbing boulder - a single rock or cliff with one or a few climbing routes which can be climbed safely without rope** corresponds with climbing=boulder + - **A climbing crag - a single rock or cliff with at least a few climbing routes** corresponds with climbing=crag + - **A climbing area with one or more climbing crags and/or boulders** corresponds with climbing=area + + + + +### Rock type (crag/rock/cliff only) + + The question is **What is the rock type here?** -This rendering asks information about the property [rock](https://wiki.openstreetmap.org/wiki/Key:rock) +This rendering asks information about the property [rock](https://wiki.openstreetmap.org/wiki/Key:rock) This is rendered with `The rock type is {rock}` -- **Limestone** corresponds with rock - =limestone -### reviews + + - **Limestone** corresponds with rock=limestone + + + + +### reviews + + _This tagrendering has no question and is thus read-only_ -This document is autogenerated from assets/layers/climbing/climbing.json \ No newline at end of file + + + + +### Website + + + +The question is **Is there a (unofficial) website with more informations (e.g. topos)?** + +This rendering asks information about the property [url](https://wiki.openstreetmap.org/wiki/Key:url) +This is rendered with `{url}` + + + +### Access from containing feature + + + +_This tagrendering has no question and is thus read-only_ + + + + + + - **The containing feature states that this is publicly accessible
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=yes + - **The containing feature states that a permit is needed to access
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=permit + - **The containing feature states that this is only accessible to customers
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=customers + - **The containing feature states that this is only accessible to club members
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=members + - **Not accessible as stated by the containing feature** corresponds with _embedding_feature:access=no + + + + +### Access + + + +The question is **Who can access here?** + + + + + + - **Publicly accessible to anyone** corresponds with access=yes + - **You need a permit to access here** corresponds with access=permit + - **Only customers** corresponds with access=customers + - **Only club members** corresponds with access=members + - **Not accessible** corresponds with access=no + + + + +### Access description (without _embedding_feature:access:description) + + + +_This tagrendering has no question and is thus read-only_ + +This rendering asks information about the property [access:description](https://wiki.openstreetmap.org/wiki/Key:access:description) +This is rendered with `{access:description}` + + + +### Avg length? + + + +The question is **What is the (average) length of the routes in meters?** + +This rendering asks information about the property [climbing:length](https://wiki.openstreetmap.org/wiki/Key:climbing:length) +This is rendered with `The routes are {canonical(climbing:length)} long on average` + + + +### Difficulty-min + + + +The question is **What is the grade of the easiest route here, according to the french classification system?** + +This rendering asks information about the property [climbing:grade:french:min](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:min) +This is rendered with `The lowest grade is {climbing:grade:french:min} according to the french/belgian system` + + + +### Difficulty-max + + + +The question is **What is the highest grade route here, according to the french classification system?** + +This rendering asks information about the property [climbing:grade:french:max](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:max) +This is rendered with `The highest grade is {climbing:grade:french:max} according to the french/belgian system` + + + +### Boldering? + + + +The question is **Is bouldering possible here?** + + + + + + - **Bouldering is possible here** corresponds with climbing:boulder=yes + - **Bouldering is not possible here** corresponds with climbing:boulder=no + - **Bouldering is possible, allthough there are only a few routes** corresponds with climbing:boulder=limited + - **There are {climbing:boulder} boulder routes** corresponds with climbing:boulder~^..*$_This option cannot be chosen as answer_ + + + + +### Toproping? + + + +The question is **Is toprope climbing possible here?** + + + + + + - **Toprope climbing is possible here** corresponds with climbing:toprope=yes + - **Toprope climbing is not possible here** corresponds with climbing:toprope=no + - **There are {climbing:toprope} toprope routes** corresponds with climbing:toprope~^..*$_This option cannot be chosen as answer_ + + + + +### Sportclimbing? + + + +The question is **Is sport climbing possible here on fixed anchors?** + + + + + + - **Sport climbing is possible here** corresponds with climbing:sport=yes + - **Sport climbing is not possible here** corresponds with climbing:sport=no + - **There are {climbing:sport} sport climbing routes** corresponds with climbing:sport~^..*$_This option cannot be chosen as answer_ + + + + +### Traditional climbing? + + + +The question is **Is traditional climbing possible here (using own gear e.g. chocks)?** + + + + + + - **Traditional climbing is possible here** corresponds with climbing:traditional=yes + - **Traditional climbing is not possible here** corresponds with climbing:traditional=no + - **There are {climbing:traditional} traditional climbing routes** corresponds with climbing:traditional~^..*$_This option cannot be chosen as answer_ + + + + +### Speed climbing? + + + +The question is **Is there a speed climbing wall?** + + + + + + - **There is a speed climbing wall** corresponds with climbing:speed=yes + - **There is no speed climbing wall** corresponds with climbing:speed=no + - **There are {climbing:speed} speed climbing walls** corresponds with climbing:speed~^..*$_This option cannot be chosen as answer_ + + +This document is autogenerated from [assets/themes/climbing/climbing.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/climbing/climbing.json) \ No newline at end of file diff --git a/Docs/Layers/climbing_club.md b/Docs/Layers/climbing_club.md index 562cb6137f..622a32de47 100644 --- a/Docs/Layers/climbing_club.md +++ b/Docs/Layers/climbing_club.md @@ -1,109 +1,339 @@ -climbing_club + + + climbing_club =============== -A climbing club or organisations - -## Table of contents - -1. [climbing_club](#climbing_club) - * [Themes using this layer](#themes-using-this-layer) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [climbing_club-name](#climbing_club-name) - + [minimap](#minimap) - + [website](#website) - + [email](#email) - + [phone](#phone) - + [opening_hours](#opening_hours) - -#### Themes using this layer - -- [climbing](https://mapcomplete.osm.be/climbing) - -[Go to the source code](../assets/layers/climbing_club/climbing_club.json) +A climbing club or organisation -Basic tags for this layer + + + + - This layer is shown at zoomlevel **10** and higher + - This layer will automatically load [climbing](./climbing.md) into the layout as it depends on it: A calculated tag loads features from this layer (calculatedTag[0] which calculates the value for _embedding_feature_properties) + + + + +#### Themes using this layer + + + + + + - [climbing](https://mapcomplete.osm.be/climbing) + + + + + Basic tags for this layer --------------------------- Elements must have the all of following tags to be shown on this layer: -- club - =climbing - |sport - =climbing&office~^..*$|club~ - ^..*$ -Supported attributes + + - club=climbing|sport=climbing&office~^..*$|club~^..*$ + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22club%22%3D%22climbing%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22sport%22%3D%22climbing%22%5D%5B%22club%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22sport%22%3D%22climbing%22%5D%5B%22office%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes ---------------------- **Warning** This quick overview is incomplete + + attribute | type | values which are supported by this layer ----------- | ------ | ------------------------------------------ -[](https://taginfo.openstreetmap.org/keys/name#values) [name](https://wiki.openstreetmap.org/wiki/Key:name) | [string](../SpecialInputElements.md#string) | -[](https://taginfo.openstreetmap.org/keys/website#values) [website](https://wiki.openstreetmap.org/wiki/Key:website) | [url](../SpecialInputElements.md#url) | -[](https://taginfo.openstreetmap.org/keys/email#values) [email](https://wiki.openstreetmap.org/wiki/Key:email) | [email](../SpecialInputElements.md#email) | -[](https://taginfo.openstreetmap.org/keys/phone#values) [phone](https://wiki.openstreetmap.org/wiki/Key:phone) | [phone](../SpecialInputElements.md#phone) | -[](https://taginfo.openstreetmap.org/keys/opening_hours#values) [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) | [opening_hours](../SpecialInputElements.md#opening_hours) | +[](https://taginfo.openstreetmap.org/keys/name#values) [name](https://wiki.openstreetmap.org/wiki/Key:name) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/website#values) [website](https://wiki.openstreetmap.org/wiki/Key:website) | [url](../SpecialInputElements.md#url) | +[](https://taginfo.openstreetmap.org/keys/email#values) [email](https://wiki.openstreetmap.org/wiki/Key:email) | [email](../SpecialInputElements.md#email) | +[](https://taginfo.openstreetmap.org/keys/phone#values) [phone](https://wiki.openstreetmap.org/wiki/Key:phone) | [phone](../SpecialInputElements.md#phone) | +[](https://taginfo.openstreetmap.org/keys/opening_hours#values) [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) | [opening_hours](../SpecialInputElements.md#opening_hours) | +[](https://taginfo.openstreetmap.org/keys/url#values) [url](https://wiki.openstreetmap.org/wiki/Key:url) | [url](../SpecialInputElements.md#url) | +[](https://taginfo.openstreetmap.org/keys/_embedding_feature:access#values) [_embedding_feature:access](https://wiki.openstreetmap.org/wiki/Key:_embedding_feature:access) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dyes) [permit](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dpermit) [customers](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dcustomers) [members](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dmembers) [no](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dno) +[](https://taginfo.openstreetmap.org/keys/access#values) [access](https://wiki.openstreetmap.org/wiki/Key:access) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:access%3Dyes) [permit](https://wiki.openstreetmap.org/wiki/Tag:access%3Dpermit) [customers](https://wiki.openstreetmap.org/wiki/Tag:access%3Dcustomers) [members](https://wiki.openstreetmap.org/wiki/Tag:access%3Dmembers) [no](https://wiki.openstreetmap.org/wiki/Tag:access%3Dno) +[](https://taginfo.openstreetmap.org/keys/access:description#values) [access:description](https://wiki.openstreetmap.org/wiki/Key:access:description) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/climbing:length#values) [climbing:length](https://wiki.openstreetmap.org/wiki/Key:climbing:length) | [pnat](../SpecialInputElements.md#pnat) | +[](https://taginfo.openstreetmap.org/keys/climbing:grade:french:min#values) [climbing:grade:french:min](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:min) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/climbing:grade:french:max#values) [climbing:grade:french:max](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:max) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/climbing:boulder#values) [climbing:boulder](https://wiki.openstreetmap.org/wiki/Key:climbing:boulder) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:boulder%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:boulder%3Dno) [limited](https://wiki.openstreetmap.org/wiki/Tag:climbing:boulder%3Dlimited) +[](https://taginfo.openstreetmap.org/keys/climbing:toprope#values) [climbing:toprope](https://wiki.openstreetmap.org/wiki/Key:climbing:toprope) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:toprope%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:toprope%3Dno) +[](https://taginfo.openstreetmap.org/keys/climbing:sport#values) [climbing:sport](https://wiki.openstreetmap.org/wiki/Key:climbing:sport) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:sport%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:sport%3Dno) +[](https://taginfo.openstreetmap.org/keys/climbing:traditional#values) [climbing:traditional](https://wiki.openstreetmap.org/wiki/Key:climbing:traditional) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:traditional%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:traditional%3Dno) +[](https://taginfo.openstreetmap.org/keys/climbing:speed#values) [climbing:speed](https://wiki.openstreetmap.org/wiki/Key:climbing:speed) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:speed%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:speed%3Dno) + + + + +### climbing_club-name + -### climbing_club-name The question is **What is the name of this climbing club or NGO?** -This rendering asks information about the property [name](https://wiki.openstreetmap.org/wiki/Key:name) +This rendering asks information about the property [name](https://wiki.openstreetmap.org/wiki/Key:name) This is rendered with `{name}` -### minimap + + +### minimap + + _This tagrendering has no question and is thus read-only_ -### website -The question is **What is the website of {name}?** -This rendering asks information about the property [website](https://wiki.openstreetmap.org/wiki/Key:website) + + +### website + + + +The question is **What is the website of {title()}?** + +This rendering asks information about the property [website](https://wiki.openstreetmap.org/wiki/Key:website) This is rendered with `{website}` -- **{contact:website}** corresponds with contact:website~^..*$_This - option cannot be chosen as answer_ -### email -The question is **What is the email address of {name}?** + - **{contact:website}** corresponds with contact:website~^..*$_This option cannot be chosen as answer_ -This rendering asks information about the property [email](https://wiki.openstreetmap.org/wiki/Key:email) + + + +### email + + + +The question is **What is the email address of {title()}?** + +This rendering asks information about the property [email](https://wiki.openstreetmap.org/wiki/Key:email) This is rendered with `{email}` -- **{contact:email}** corresponds with contact:email~^..*$_This - option cannot be chosen as answer_ -### phone -The question is **What is the phone number of {name}?** + - **{contact:email}** corresponds with contact:email~^..*$_This option cannot be chosen as answer_ -This rendering asks information about the property [phone](https://wiki.openstreetmap.org/wiki/Key:phone) + + + +### phone + + + +The question is **What is the phone number of {title()}?** + +This rendering asks information about the property [phone](https://wiki.openstreetmap.org/wiki/Key:phone) This is rendered with `{phone}` -- **{contact:phone}** corresponds with contact:phone~^..*$_This option cannot be - chosen as answer_ -### opening_hours -The question is **What are the opening hours of {name}?** + - **{contact:phone}** corresponds with contact:phone~^..*$_This option cannot be chosen as answer_ -This rendering asks information about the -property [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) + + + +### opening_hours + + + +The question is **What are the opening hours of {title()}?** + +This rendering asks information about the property [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) This is rendered with `

Opening hours

{opening_hours_table(opening_hours)}` -This document is autogenerated from assets/layers/climbing_club/climbing_club.json \ No newline at end of file + + +### Website + + + +The question is **Is there a (unofficial) website with more informations (e.g. topos)?** + +This rendering asks information about the property [url](https://wiki.openstreetmap.org/wiki/Key:url) +This is rendered with `{url}` + + + +### Access from containing feature + + + +_This tagrendering has no question and is thus read-only_ + + + + + + - **The containing feature states that this is publicly accessible
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=yes + - **The containing feature states that a permit is needed to access
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=permit + - **The containing feature states that this is only accessible to customers
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=customers + - **The containing feature states that this is only accessible to club members
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=members + - **Not accessible as stated by the containing feature** corresponds with _embedding_feature:access=no + + + + +### Access + + + +The question is **Who can access here?** + + + + + + - **Publicly accessible to anyone** corresponds with access=yes + - **You need a permit to access here** corresponds with access=permit + - **Only customers** corresponds with access=customers + - **Only club members** corresponds with access=members + - **Not accessible** corresponds with access=no + + + + +### Access description (without _embedding_feature:access:description) + + + +_This tagrendering has no question and is thus read-only_ + +This rendering asks information about the property [access:description](https://wiki.openstreetmap.org/wiki/Key:access:description) +This is rendered with `{access:description}` + + + +### Avg length? + + + +The question is **What is the (average) length of the routes in meters?** + +This rendering asks information about the property [climbing:length](https://wiki.openstreetmap.org/wiki/Key:climbing:length) +This is rendered with `The routes are {canonical(climbing:length)} long on average` + + + +### Difficulty-min + + + +The question is **What is the grade of the easiest route here, according to the french classification system?** + +This rendering asks information about the property [climbing:grade:french:min](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:min) +This is rendered with `The lowest grade is {climbing:grade:french:min} according to the french/belgian system` + + + +### Difficulty-max + + + +The question is **What is the highest grade route here, according to the french classification system?** + +This rendering asks information about the property [climbing:grade:french:max](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:max) +This is rendered with `The highest grade is {climbing:grade:french:max} according to the french/belgian system` + + + +### Boldering? + + + +The question is **Is bouldering possible here?** + + + + + + - **Bouldering is possible here** corresponds with climbing:boulder=yes + - **Bouldering is not possible here** corresponds with climbing:boulder=no + - **Bouldering is possible, allthough there are only a few routes** corresponds with climbing:boulder=limited + - **There are {climbing:boulder} boulder routes** corresponds with climbing:boulder~^..*$_This option cannot be chosen as answer_ + + + + +### Toproping? + + + +The question is **Is toprope climbing possible here?** + + + + + + - **Toprope climbing is possible here** corresponds with climbing:toprope=yes + - **Toprope climbing is not possible here** corresponds with climbing:toprope=no + - **There are {climbing:toprope} toprope routes** corresponds with climbing:toprope~^..*$_This option cannot be chosen as answer_ + + + + +### Sportclimbing? + + + +The question is **Is sport climbing possible here on fixed anchors?** + + + + + + - **Sport climbing is possible here** corresponds with climbing:sport=yes + - **Sport climbing is not possible here** corresponds with climbing:sport=no + - **There are {climbing:sport} sport climbing routes** corresponds with climbing:sport~^..*$_This option cannot be chosen as answer_ + + + + +### Traditional climbing? + + + +The question is **Is traditional climbing possible here (using own gear e.g. chocks)?** + + + + + + - **Traditional climbing is possible here** corresponds with climbing:traditional=yes + - **Traditional climbing is not possible here** corresponds with climbing:traditional=no + - **There are {climbing:traditional} traditional climbing routes** corresponds with climbing:traditional~^..*$_This option cannot be chosen as answer_ + + + + +### Speed climbing? + + + +The question is **Is there a speed climbing wall?** + + + + + + - **There is a speed climbing wall** corresponds with climbing:speed=yes + - **There is no speed climbing wall** corresponds with climbing:speed=no + - **There are {climbing:speed} speed climbing walls** corresponds with climbing:speed~^..*$_This option cannot be chosen as answer_ + + +This document is autogenerated from [assets/themes/climbing/climbing.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/climbing/climbing.json) \ No newline at end of file diff --git a/Docs/Layers/climbing_gym.md b/Docs/Layers/climbing_gym.md index 14a8611191..16993bf7ab 100644 --- a/Docs/Layers/climbing_gym.md +++ b/Docs/Layers/climbing_gym.md @@ -1,4 +1,6 @@ -climbing_gym + + + climbing_gym ============== @@ -7,117 +9,362 @@ climbing_gym A climbing gym -## Table of contents - -1. [climbing_gym](#climbing_gym) - * [Themes using this layer](#themes-using-this-layer) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [images](#images) - + [questions](#questions) - + [minimap](#minimap) - + [name](#name) - + [website](#website) - + [phone](#phone) - + [email](#email) - + [opening_hours](#opening_hours) - + [reviews](#reviews) - -#### Themes using this layer - -- [climbing](https://mapcomplete.osm.be/climbing) - -[Go to the source code](../assets/layers/climbing_gym/climbing_gym.json) -Basic tags for this layer + + + - This layer is shown at zoomlevel **10** and higher + - This layer will automatically load [climbing](./climbing.md) into the layout as it depends on it: A calculated tag loads features from this layer (calculatedTag[0] which calculates the value for _embedding_feature_properties) + + + + +#### Themes using this layer + + + + + + - [climbing](https://mapcomplete.osm.be/climbing) + + + + + Basic tags for this layer --------------------------- Elements must have the all of following tags to be shown on this layer: -- sport - =climbing -- leisure - =sports_centre -Supported attributes + + - sport=climbing + - leisure=sports_centre + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22sport%22%3D%22climbing%22%5D%5B%22leisure%22%3D%22sports_centre%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes ---------------------- **Warning** This quick overview is incomplete + + attribute | type | values which are supported by this layer ----------- | ------ | ------------------------------------------ -[](https://taginfo.openstreetmap.org/keys/name#values) [name](https://wiki.openstreetmap.org/wiki/Key:name) | [string](../SpecialInputElements.md#string) | -[](https://taginfo.openstreetmap.org/keys/website#values) [website](https://wiki.openstreetmap.org/wiki/Key:website) | [url](../SpecialInputElements.md#url) | -[](https://taginfo.openstreetmap.org/keys/phone#values) [phone](https://wiki.openstreetmap.org/wiki/Key:phone) | [phone](../SpecialInputElements.md#phone) | -[](https://taginfo.openstreetmap.org/keys/email#values) [email](https://wiki.openstreetmap.org/wiki/Key:email) | [email](../SpecialInputElements.md#email) | -[](https://taginfo.openstreetmap.org/keys/opening_hours#values) [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) | [opening_hours](../SpecialInputElements.md#opening_hours) | +[](https://taginfo.openstreetmap.org/keys/name#values) [name](https://wiki.openstreetmap.org/wiki/Key:name) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/website#values) [website](https://wiki.openstreetmap.org/wiki/Key:website) | [url](../SpecialInputElements.md#url) | +[](https://taginfo.openstreetmap.org/keys/phone#values) [phone](https://wiki.openstreetmap.org/wiki/Key:phone) | [phone](../SpecialInputElements.md#phone) | +[](https://taginfo.openstreetmap.org/keys/email#values) [email](https://wiki.openstreetmap.org/wiki/Key:email) | [email](../SpecialInputElements.md#email) | +[](https://taginfo.openstreetmap.org/keys/opening_hours#values) [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) | [opening_hours](../SpecialInputElements.md#opening_hours) | +[](https://taginfo.openstreetmap.org/keys/url#values) [url](https://wiki.openstreetmap.org/wiki/Key:url) | [url](../SpecialInputElements.md#url) | +[](https://taginfo.openstreetmap.org/keys/_embedding_feature:access#values) [_embedding_feature:access](https://wiki.openstreetmap.org/wiki/Key:_embedding_feature:access) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dyes) [permit](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dpermit) [customers](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dcustomers) [members](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dmembers) [no](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dno) +[](https://taginfo.openstreetmap.org/keys/access#values) [access](https://wiki.openstreetmap.org/wiki/Key:access) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:access%3Dyes) [permit](https://wiki.openstreetmap.org/wiki/Tag:access%3Dpermit) [customers](https://wiki.openstreetmap.org/wiki/Tag:access%3Dcustomers) [members](https://wiki.openstreetmap.org/wiki/Tag:access%3Dmembers) [no](https://wiki.openstreetmap.org/wiki/Tag:access%3Dno) +[](https://taginfo.openstreetmap.org/keys/access:description#values) [access:description](https://wiki.openstreetmap.org/wiki/Key:access:description) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/climbing:length#values) [climbing:length](https://wiki.openstreetmap.org/wiki/Key:climbing:length) | [pnat](../SpecialInputElements.md#pnat) | +[](https://taginfo.openstreetmap.org/keys/climbing:grade:french:min#values) [climbing:grade:french:min](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:min) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/climbing:grade:french:max#values) [climbing:grade:french:max](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:max) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/climbing:boulder#values) [climbing:boulder](https://wiki.openstreetmap.org/wiki/Key:climbing:boulder) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:boulder%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:boulder%3Dno) [limited](https://wiki.openstreetmap.org/wiki/Tag:climbing:boulder%3Dlimited) +[](https://taginfo.openstreetmap.org/keys/climbing:toprope#values) [climbing:toprope](https://wiki.openstreetmap.org/wiki/Key:climbing:toprope) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:toprope%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:toprope%3Dno) +[](https://taginfo.openstreetmap.org/keys/climbing:sport#values) [climbing:sport](https://wiki.openstreetmap.org/wiki/Key:climbing:sport) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:sport%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:sport%3Dno) +[](https://taginfo.openstreetmap.org/keys/climbing:traditional#values) [climbing:traditional](https://wiki.openstreetmap.org/wiki/Key:climbing:traditional) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:traditional%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:traditional%3Dno) +[](https://taginfo.openstreetmap.org/keys/climbing:speed#values) [climbing:speed](https://wiki.openstreetmap.org/wiki/Key:climbing:speed) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:speed%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:speed%3Dno) + + + + +### images + -### images _This tagrendering has no question and is thus read-only_ -### questions + + + + +### questions + + _This tagrendering has no question and is thus read-only_ -### minimap + + + + +### minimap + + _This tagrendering has no question and is thus read-only_ -### name + + + + +### name + + The question is **What is the name of this climbing gym?** -This rendering asks information about the property [name](https://wiki.openstreetmap.org/wiki/Key:name) +This rendering asks information about the property [name](https://wiki.openstreetmap.org/wiki/Key:name) This is rendered with `{name}` -### website -The question is **What is the website of {name}?** -This rendering asks information about the property [website](https://wiki.openstreetmap.org/wiki/Key:website) +### website + + + +The question is **What is the website of {title()}?** + +This rendering asks information about the property [website](https://wiki.openstreetmap.org/wiki/Key:website) This is rendered with `{website}` -- **{contact:website}** corresponds with contact:website~^..*$_This - option cannot be chosen as answer_ -### phone -The question is **What is the phone number of {name}?** + - **{contact:website}** corresponds with contact:website~^..*$_This option cannot be chosen as answer_ -This rendering asks information about the property [phone](https://wiki.openstreetmap.org/wiki/Key:phone) + + + +### phone + + + +The question is **What is the phone number of {title()}?** + +This rendering asks information about the property [phone](https://wiki.openstreetmap.org/wiki/Key:phone) This is rendered with `{phone}` -- **{contact:phone}** corresponds with contact:phone~^..*$_This option cannot be - chosen as answer_ -### email -The question is **What is the email address of {name}?** + - **{contact:phone}** corresponds with contact:phone~^..*$_This option cannot be chosen as answer_ -This rendering asks information about the property [email](https://wiki.openstreetmap.org/wiki/Key:email) + + + +### email + + + +The question is **What is the email address of {title()}?** + +This rendering asks information about the property [email](https://wiki.openstreetmap.org/wiki/Key:email) This is rendered with `{email}` -- **{contact:email}** corresponds with contact:email~^..*$_This - option cannot be chosen as answer_ -### opening_hours -The question is **What are the opening hours of {name}?** + - **{contact:email}** corresponds with contact:email~^..*$_This option cannot be chosen as answer_ -This rendering asks information about the -property [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) + + + +### opening_hours + + + +The question is **What are the opening hours of {title()}?** + +This rendering asks information about the property [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) This is rendered with `

Opening hours

{opening_hours_table(opening_hours)}` -### reviews + + +### reviews + + _This tagrendering has no question and is thus read-only_ -This document is autogenerated from assets/layers/climbing_gym/climbing_gym.json \ No newline at end of file + + + + +### Website + + + +The question is **Is there a (unofficial) website with more informations (e.g. topos)?** + +This rendering asks information about the property [url](https://wiki.openstreetmap.org/wiki/Key:url) +This is rendered with `{url}` + + + +### Access from containing feature + + + +_This tagrendering has no question and is thus read-only_ + + + + + + - **The containing feature states that this is publicly accessible
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=yes + - **The containing feature states that a permit is needed to access
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=permit + - **The containing feature states that this is only accessible to customers
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=customers + - **The containing feature states that this is only accessible to club members
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=members + - **Not accessible as stated by the containing feature** corresponds with _embedding_feature:access=no + + + + +### Access + + + +The question is **Who can access here?** + + + + + + - **Publicly accessible to anyone** corresponds with access=yes + - **You need a permit to access here** corresponds with access=permit + - **Only customers** corresponds with access=customers + - **Only club members** corresponds with access=members + - **Not accessible** corresponds with access=no + + + + +### Access description (without _embedding_feature:access:description) + + + +_This tagrendering has no question and is thus read-only_ + +This rendering asks information about the property [access:description](https://wiki.openstreetmap.org/wiki/Key:access:description) +This is rendered with `{access:description}` + + + +### Avg length? + + + +The question is **What is the (average) length of the routes in meters?** + +This rendering asks information about the property [climbing:length](https://wiki.openstreetmap.org/wiki/Key:climbing:length) +This is rendered with `The routes are {canonical(climbing:length)} long on average` + + + +### Difficulty-min + + + +The question is **What is the grade of the easiest route here, according to the french classification system?** + +This rendering asks information about the property [climbing:grade:french:min](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:min) +This is rendered with `The lowest grade is {climbing:grade:french:min} according to the french/belgian system` + + + +### Difficulty-max + + + +The question is **What is the highest grade route here, according to the french classification system?** + +This rendering asks information about the property [climbing:grade:french:max](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:max) +This is rendered with `The highest grade is {climbing:grade:french:max} according to the french/belgian system` + + + +### Boldering? + + + +The question is **Is bouldering possible here?** + + + + + + - **Bouldering is possible here** corresponds with climbing:boulder=yes + - **Bouldering is not possible here** corresponds with climbing:boulder=no + - **Bouldering is possible, allthough there are only a few routes** corresponds with climbing:boulder=limited + - **There are {climbing:boulder} boulder routes** corresponds with climbing:boulder~^..*$_This option cannot be chosen as answer_ + + + + +### Toproping? + + + +The question is **Is toprope climbing possible here?** + + + + + + - **Toprope climbing is possible here** corresponds with climbing:toprope=yes + - **Toprope climbing is not possible here** corresponds with climbing:toprope=no + - **There are {climbing:toprope} toprope routes** corresponds with climbing:toprope~^..*$_This option cannot be chosen as answer_ + + + + +### Sportclimbing? + + + +The question is **Is sport climbing possible here on fixed anchors?** + + + + + + - **Sport climbing is possible here** corresponds with climbing:sport=yes + - **Sport climbing is not possible here** corresponds with climbing:sport=no + - **There are {climbing:sport} sport climbing routes** corresponds with climbing:sport~^..*$_This option cannot be chosen as answer_ + + + + +### Traditional climbing? + + + +The question is **Is traditional climbing possible here (using own gear e.g. chocks)?** + + + + + + - **Traditional climbing is possible here** corresponds with climbing:traditional=yes + - **Traditional climbing is not possible here** corresponds with climbing:traditional=no + - **There are {climbing:traditional} traditional climbing routes** corresponds with climbing:traditional~^..*$_This option cannot be chosen as answer_ + + + + +### Speed climbing? + + + +The question is **Is there a speed climbing wall?** + + + + + + - **There is a speed climbing wall** corresponds with climbing:speed=yes + - **There is no speed climbing wall** corresponds with climbing:speed=no + - **There are {climbing:speed} speed climbing walls** corresponds with climbing:speed~^..*$_This option cannot be chosen as answer_ + + +This document is autogenerated from [assets/themes/climbing/climbing.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/climbing/climbing.json) \ No newline at end of file diff --git a/Docs/Layers/climbing_route.md b/Docs/Layers/climbing_route.md index c60b3159ca..ffd8afe5c0 100644 --- a/Docs/Layers/climbing_route.md +++ b/Docs/Layers/climbing_route.md @@ -1,139 +1,376 @@ -climbing_route + + + climbing_route ================ - - -## Table of contents - -1. [climbing_route](#climbing_route) - * [Themes using this layer](#themes-using-this-layer) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [images](#images) - + [questions](#questions) - + [minimap](#minimap) - + [Name](#name) - + [Length](#length) - + [Difficulty](#difficulty) - + [Bolts](#bolts) - + [Description](#description) - + [Rock type](#rock-type) - + [reviews](#reviews) - - -- This layer is needed as dependency for layer [climbing](#climbing) - -#### Themes using this layer - -- [climbing](https://mapcomplete.osm.be/climbing) - -[Go to the source code](../assets/layers/climbing_route/climbing_route.json) + -Basic tags for this layer + + + + - This layer is shown at zoomlevel **18** and higher + - This layer will automatically load [climbing](./climbing.md) into the layout as it depends on it: A calculated tag loads features from this layer (calculatedTag[0] which calculates the value for _embedding_feature_properties) + - This layer is needed as dependency for layer [climbing](#climbing) + + + + +#### Themes using this layer + + + + + + - [climbing](https://mapcomplete.osm.be/climbing) + + + + + Basic tags for this layer --------------------------- Elements must have the all of following tags to be shown on this layer: -- climbing - =route -Supported attributes + + - climbing=route + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22climbing%22%3D%22route%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes ---------------------- **Warning** This quick overview is incomplete + + attribute | type | values which are supported by this layer ----------- | ------ | ------------------------------------------ [](https://taginfo.openstreetmap.org/keys/name#values) [name](https://wiki.openstreetmap.org/wiki/Key:name) | [string](../SpecialInputElements.md#string) | [](https://wiki.openstreetmap.org/wiki/Tag:name%3D) -[](https://taginfo.openstreetmap.org/keys/climbing:length#values) [climbing:length](https://wiki.openstreetmap.org/wiki/Key:climbing:length) | [pnat](../SpecialInputElements.md#pnat) | -[](https://taginfo.openstreetmap.org/keys/climbing:grade:french#values) [climbing:grade:french](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french) | [string](../SpecialInputElements.md#string) | -[](https://taginfo.openstreetmap.org/keys/climbing:bolts#values) [climbing:bolts](https://wiki.openstreetmap.org/wiki/Key:climbing:bolts) | [pnat](../SpecialInputElements.md#pnat) | -[](https://taginfo.openstreetmap.org/keys/description#values) [description](https://wiki.openstreetmap.org/wiki/Key:description) | [string](../SpecialInputElements.md#string) | -[](https://taginfo.openstreetmap.org/keys/_embedding_features_with_rock:rock#values) [_embedding_features_with_rock:rock](https://wiki.openstreetmap.org/wiki/Key:_embedding_features_with_rock:rock) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/climbing:length#values) [climbing:length](https://wiki.openstreetmap.org/wiki/Key:climbing:length) | [pnat](../SpecialInputElements.md#pnat) | +[](https://taginfo.openstreetmap.org/keys/climbing:grade:french#values) [climbing:grade:french](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/climbing:bolts#values) [climbing:bolts](https://wiki.openstreetmap.org/wiki/Key:climbing:bolts) | [pnat](../SpecialInputElements.md#pnat) | +[](https://taginfo.openstreetmap.org/keys/description#values) [description](https://wiki.openstreetmap.org/wiki/Key:description) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/_embedding_features_with_rock:rock#values) [_embedding_features_with_rock:rock](https://wiki.openstreetmap.org/wiki/Key:_embedding_features_with_rock:rock) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/url#values) [url](https://wiki.openstreetmap.org/wiki/Key:url) | [url](../SpecialInputElements.md#url) | +[](https://taginfo.openstreetmap.org/keys/_embedding_feature:access#values) [_embedding_feature:access](https://wiki.openstreetmap.org/wiki/Key:_embedding_feature:access) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dyes) [permit](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dpermit) [customers](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dcustomers) [members](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dmembers) [no](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dno) +[](https://taginfo.openstreetmap.org/keys/access#values) [access](https://wiki.openstreetmap.org/wiki/Key:access) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:access%3Dyes) [permit](https://wiki.openstreetmap.org/wiki/Tag:access%3Dpermit) [customers](https://wiki.openstreetmap.org/wiki/Tag:access%3Dcustomers) [members](https://wiki.openstreetmap.org/wiki/Tag:access%3Dmembers) [no](https://wiki.openstreetmap.org/wiki/Tag:access%3Dno) +[](https://taginfo.openstreetmap.org/keys/access:description#values) [access:description](https://wiki.openstreetmap.org/wiki/Key:access:description) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/climbing:length#values) [climbing:length](https://wiki.openstreetmap.org/wiki/Key:climbing:length) | [pnat](../SpecialInputElements.md#pnat) | +[](https://taginfo.openstreetmap.org/keys/climbing:grade:french:min#values) [climbing:grade:french:min](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:min) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/climbing:grade:french:max#values) [climbing:grade:french:max](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:max) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/climbing:boulder#values) [climbing:boulder](https://wiki.openstreetmap.org/wiki/Key:climbing:boulder) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:boulder%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:boulder%3Dno) [limited](https://wiki.openstreetmap.org/wiki/Tag:climbing:boulder%3Dlimited) +[](https://taginfo.openstreetmap.org/keys/climbing:toprope#values) [climbing:toprope](https://wiki.openstreetmap.org/wiki/Key:climbing:toprope) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:toprope%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:toprope%3Dno) +[](https://taginfo.openstreetmap.org/keys/climbing:sport#values) [climbing:sport](https://wiki.openstreetmap.org/wiki/Key:climbing:sport) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:sport%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:sport%3Dno) +[](https://taginfo.openstreetmap.org/keys/climbing:traditional#values) [climbing:traditional](https://wiki.openstreetmap.org/wiki/Key:climbing:traditional) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:traditional%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:traditional%3Dno) +[](https://taginfo.openstreetmap.org/keys/climbing:speed#values) [climbing:speed](https://wiki.openstreetmap.org/wiki/Key:climbing:speed) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:speed%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:speed%3Dno) + + + + +### images + -### images _This tagrendering has no question and is thus read-only_ -### questions + + + + +### questions + + _This tagrendering has no question and is thus read-only_ -### minimap + + + + +### minimap + + _This tagrendering has no question and is thus read-only_ -### Name + + + + +### Name + + The question is **What is the name of this climbing route?** -This rendering asks information about the property [name](https://wiki.openstreetmap.org/wiki/Key:name) +This rendering asks information about the property [name](https://wiki.openstreetmap.org/wiki/Key:name) This is rendered with `{name}` -- **This climbing route doesn't have a name** corresponds - with noname - =yes -### Length + + - **This climbing route doesn't have a name** corresponds with noname=yes + + + + +### Length + + The question is **How long is this climbing route (in meters)?** -This rendering asks information about the -property [climbing:length](https://wiki.openstreetmap.org/wiki/Key:climbing:length) +This rendering asks information about the property [climbing:length](https://wiki.openstreetmap.org/wiki/Key:climbing:length) This is rendered with `This route is {canonical(climbing:length)} long` -### Difficulty -The question is **What is the difficulty of this climbing route according to the french/belgian system?** -This rendering asks information about the -property [climbing:grade:french](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french) -This is rendered with `The difficulty is {climbing:grade:french} according to the french/belgian system` +### Difficulty -### Bolts -The question is **How much bolts does this route have before reaching the moulinette?** -This rendering asks information about the -property [climbing:bolts](https://wiki.openstreetmap.org/wiki/Key:climbing:bolts) +The question is **What is the grade of this climbing route according to the french/belgian system?** + +This rendering asks information about the property [climbing:grade:french](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french) +This is rendered with `The grade is {climbing:grade:french} according to the french/belgian system` + + + +### Bolts + + + +The question is **How many bolts does this route have before reaching the anchor?** + +This rendering asks information about the property [climbing:bolts](https://wiki.openstreetmap.org/wiki/Key:climbing:bolts) This is rendered with `This route has {climbing:bolts} bolts` -- **This route is not bolted** corresponds - with climbing:bolted - =no_This option cannot be - chosen as answer_ -- **This route is not bolted** corresponds - with climbing:bolted - =no&climbing: - bolts= -### Description + + - **This route is not bolted** corresponds with climbing:bolted=no_This option cannot be chosen as answer_ + - **This route is not bolted** corresponds with climbing:bolted=no&climbing:bolts= + + + + +### Description + + The question is **Is there other relevant info?** -This rendering asks information about the property [description](https://wiki.openstreetmap.org/wiki/Key:description) +This rendering asks information about the property [description](https://wiki.openstreetmap.org/wiki/Key:description) This is rendered with `

Description


{description}` -### Rock type + + +### Rock type + + _This tagrendering has no question and is thus read-only_ -This rendering asks information about the -property [_embedding_features_with_rock:rock](https://wiki.openstreetmap.org/wiki/Key:_embedding_features_with_rock:rock) -This is rendered -with `The rock type is {_embedding_features_with_rock:rock} as stated on the surrounding crag` +This rendering asks information about the property [_embedding_features_with_rock:rock](https://wiki.openstreetmap.org/wiki/Key:_embedding_features_with_rock:rock) +This is rendered with `The rock type is {_embedding_features_with_rock:rock} as stated on the surrounding crag` + + + +### reviews + -### reviews _This tagrendering has no question and is thus read-only_ -This document is autogenerated from assets/layers/climbing_route/climbing_route.json \ No newline at end of file + + + + +### Website + + + +The question is **Is there a (unofficial) website with more informations (e.g. topos)?** + +This rendering asks information about the property [url](https://wiki.openstreetmap.org/wiki/Key:url) +This is rendered with `{url}` + + + +### Access from containing feature + + + +_This tagrendering has no question and is thus read-only_ + + + + + + - **The containing feature states that this is publicly accessible
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=yes + - **The containing feature states that a permit is needed to access
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=permit + - **The containing feature states that this is only accessible to customers
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=customers + - **The containing feature states that this is only accessible to club members
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=members + - **Not accessible as stated by the containing feature** corresponds with _embedding_feature:access=no + + + + +### Access + + + +The question is **Who can access here?** + + + + + + - **Publicly accessible to anyone** corresponds with access=yes + - **You need a permit to access here** corresponds with access=permit + - **Only customers** corresponds with access=customers + - **Only club members** corresponds with access=members + - **Not accessible** corresponds with access=no + + + + +### Access description (without _embedding_feature:access:description) + + + +_This tagrendering has no question and is thus read-only_ + +This rendering asks information about the property [access:description](https://wiki.openstreetmap.org/wiki/Key:access:description) +This is rendered with `{access:description}` + + + +### Avg length? + + + +The question is **What is the (average) length of the routes in meters?** + +This rendering asks information about the property [climbing:length](https://wiki.openstreetmap.org/wiki/Key:climbing:length) +This is rendered with `The routes are {canonical(climbing:length)} long on average` + + + +### Difficulty-min + + + +The question is **What is the grade of the easiest route here, according to the french classification system?** + +This rendering asks information about the property [climbing:grade:french:min](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:min) +This is rendered with `The lowest grade is {climbing:grade:french:min} according to the french/belgian system` + + + +### Difficulty-max + + + +The question is **What is the highest grade route here, according to the french classification system?** + +This rendering asks information about the property [climbing:grade:french:max](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:max) +This is rendered with `The highest grade is {climbing:grade:french:max} according to the french/belgian system` + + + +### Boldering? + + + +The question is **Is bouldering possible here?** + + + + + + - **Bouldering is possible here** corresponds with climbing:boulder=yes + - **Bouldering is not possible here** corresponds with climbing:boulder=no + - **Bouldering is possible, allthough there are only a few routes** corresponds with climbing:boulder=limited + - **There are {climbing:boulder} boulder routes** corresponds with climbing:boulder~^..*$_This option cannot be chosen as answer_ + + + + +### Toproping? + + + +The question is **Is toprope climbing possible here?** + + + + + + - **Toprope climbing is possible here** corresponds with climbing:toprope=yes + - **Toprope climbing is not possible here** corresponds with climbing:toprope=no + - **There are {climbing:toprope} toprope routes** corresponds with climbing:toprope~^..*$_This option cannot be chosen as answer_ + + + + +### Sportclimbing? + + + +The question is **Is sport climbing possible here on fixed anchors?** + + + + + + - **Sport climbing is possible here** corresponds with climbing:sport=yes + - **Sport climbing is not possible here** corresponds with climbing:sport=no + - **There are {climbing:sport} sport climbing routes** corresponds with climbing:sport~^..*$_This option cannot be chosen as answer_ + + + + +### Traditional climbing? + + + +The question is **Is traditional climbing possible here (using own gear e.g. chocks)?** + + + + + + - **Traditional climbing is possible here** corresponds with climbing:traditional=yes + - **Traditional climbing is not possible here** corresponds with climbing:traditional=no + - **There are {climbing:traditional} traditional climbing routes** corresponds with climbing:traditional~^..*$_This option cannot be chosen as answer_ + + + + +### Speed climbing? + + + +The question is **Is there a speed climbing wall?** + + + + + + - **There is a speed climbing wall** corresponds with climbing:speed=yes + - **There is no speed climbing wall** corresponds with climbing:speed=no + - **There are {climbing:speed} speed climbing walls** corresponds with climbing:speed~^..*$_This option cannot be chosen as answer_ + + +This document is autogenerated from [assets/themes/climbing/climbing.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/climbing/climbing.json) \ No newline at end of file diff --git a/Docs/Layers/cluster_style.md b/Docs/Layers/cluster_style.md index 10d8d13a37..8e37cae340 100644 --- a/Docs/Layers/cluster_style.md +++ b/Docs/Layers/cluster_style.md @@ -12,18 +12,9 @@ The style for the clustering in all themes. Enable `debug=true` to peak into clu -## Table of contents - -1. [cluster_style](#cluster_style) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [all_tags](#all_tags) - - - + - This layer is shown at zoomlevel **0** and higher - Not visible in the layer selection by default. If you want to make this layer toggable, override `name` @@ -38,8 +29,6 @@ The style for the clustering in all themes. Enable `debug=true` to peak into clu - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/cluster_style/cluster_style.json) - Basic tags for this layer diff --git a/Docs/Layers/conflation.md b/Docs/Layers/conflation.md deleted file mode 100644 index d5f0480cdc..0000000000 --- a/Docs/Layers/conflation.md +++ /dev/null @@ -1,39 +0,0 @@ -conflation -============ - - - - - -If the import-button moves OSM points, the imported way points or conflates, a preview is shown. This layer defines how -this preview is rendered. This layer cannot be included in a theme. - -## Table of contents - -1. [conflation](#conflation) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - -[Go to the source code](../assets/layers/conflation/conflation.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- move - =yes - |newpoint - =yes - -Supported attributes ----------------------- - - - -This document is autogenerated from assets/layers/conflation/conflation.json \ No newline at end of file diff --git a/Docs/Layers/crab_address.md b/Docs/Layers/crab_address.md index 5a0f274962..dd23caa61b 100644 --- a/Docs/Layers/crab_address.md +++ b/Docs/Layers/crab_address.md @@ -12,18 +12,9 @@ Address data for Flanders by the governement, suited for import into OpenStreetM -## Table of contents - -1. [crab_address](#crab_address) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [render_crab](#render_crab) - - - + - This layer is shown at zoomlevel **0** and higher - This layer is loaded from an external source, namely `https://raw.githubusercontent.com/pietervdvn/MapComplete-data/main/CRAB_2021_10_26/tile_{z}_{x}_{y}.geojson` @@ -38,8 +29,6 @@ Address data for Flanders by the governement, suited for import into OpenStreetM - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/crab_address/crab_address.json) - Basic tags for this layer diff --git a/Docs/Layers/crossings.md b/Docs/Layers/crossings.md index 8eb2c1a2fa..8a4a8c041e 100644 --- a/Docs/Layers/crossings.md +++ b/Docs/Layers/crossings.md @@ -12,25 +12,9 @@ Crossings for pedestrians and cyclists -## Table of contents - -1. [crossings](#crossings) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [crossing-type](#crossing-type) - + [crossing-is-zebra](#crossing-is-zebra) - + [crossing-bicycle-allowed](#crossing-bicycle-allowed) - + [crossing-has-island](#crossing-has-island) - + [crossing-tactile](#crossing-tactile) - + [crossing-button](#crossing-button) - + [crossing-right-turn-through-red](#crossing-right-turn-through-red) - + [crossing-continue-through-red](#crossing-continue-through-red) - - - + - This layer is shown at zoomlevel **17** and higher - This layer will automatically load [cycleways_and_roads](./cycleways_and_roads.md) into the layout as it depends on it: a preset snaps to this layer (presets[0]) - This layer will automatically load [cycleways_and_roads](./cycleways_and_roads.md) into the layout as it depends on it: a preset snaps to this layer (presets[1]) @@ -47,8 +31,6 @@ Crossings for pedestrians and cyclists - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/crossings/crossings.json) - Basic tags for this layer diff --git a/Docs/Layers/cultural_places_without_etymology.md b/Docs/Layers/cultural_places_without_etymology.md new file mode 100644 index 0000000000..2a0bb034a8 --- /dev/null +++ b/Docs/Layers/cultural_places_without_etymology.md @@ -0,0 +1,162 @@ + + + cultural_places_without_etymology +=================================== + + + + + +All objects which have an etymology known + + + + + + + - This layer is shown at zoomlevel **18** and higher + + + + +#### Themes using this layer + + + + + + - [etymology](https://mapcomplete.osm.be/etymology) + + + + + Basic tags for this layer +--------------------------- + + + +Elements must have the all of following tags to be shown on this layer: + + + + - name~^..*$ + - amenity=arts_centre|amenity=cinema|amenity=community_centre|amenity=library|amenity=theatre + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22amenity%22%3D%22arts_centre%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22amenity%22%3D%22cinema%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22amenity%22%3D%22community_centre%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22amenity%22%3D%22library%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22amenity%22%3D%22theatre%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes +---------------------- + + + +**Warning** This quick overview is incomplete + + + +attribute | type | values which are supported by this layer +----------- | ------ | ------------------------------------------ +[](https://taginfo.openstreetmap.org/keys/name:etymology:wikidata#values) [name:etymology:wikidata](https://wiki.openstreetmap.org/wiki/Key:name:etymology:wikidata) | [wikidata](../SpecialInputElements.md#wikidata) | +[](https://taginfo.openstreetmap.org/keys/name:etymology#values) [name:etymology](https://wiki.openstreetmap.org/wiki/Key:name:etymology) | [string](../SpecialInputElements.md#string) | [unknown](https://wiki.openstreetmap.org/wiki/Tag:name:etymology%3Dunknown) + + + + +### etymology-images-from-wikipedia + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### wikipedia-etymology + + + +The question is **What is the Wikidata-item that this object is named after?** + +This rendering asks information about the property [name:etymology:wikidata](https://wiki.openstreetmap.org/wiki/Key:name:etymology:wikidata) +This is rendered with `

Wikipedia article of the name giver

{wikipedia(name:etymology:wikidata):max-height:20rem}` + + + +### zoeken op inventaris onroerend erfgoed + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### simple etymology + + + +The question is **What is this object named after?
This might be written on the street name sign** + +This rendering asks information about the property [name:etymology](https://wiki.openstreetmap.org/wiki/Key:name:etymology) +This is rendered with `Named after {name:etymology}` + + + + - **The origin of this name is unknown in all literature** corresponds with name:etymology=unknown + + + + +### questions + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### street-name-sign-image + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### minimap + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### etymology_multi_apply + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### wikipedia + + + +_This tagrendering has no question and is thus read-only_ + + + +This document is autogenerated from [assets/themes/etymology/etymology.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/etymology/etymology.json) \ No newline at end of file diff --git a/Docs/Layers/current_view.md b/Docs/Layers/current_view.md deleted file mode 100644 index 2425feeca5..0000000000 --- a/Docs/Layers/current_view.md +++ /dev/null @@ -1,44 +0,0 @@ -current_view -============== - - - - - -A meta-layer which contains one single feature, namely the BBOX of the current map view. This can be used to trigger -special actions. If a popup is defined for this layer, this popup will be accessible via an extra button on screen. - -The icon on the button is the default icon of the layer, but can be customized by detecting 'button=yes'. - -## Table of contents - -1. [current_view](#current_view) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - - -- This layer is not visible by default and must be enabled in the filter by the user. -- Not visible in the layer selection by default. If you want to make this layer toggable, override `name` -- Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` - -[Go to the source code](../assets/layers/current_view/current_view.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- current_view - =yes - -Supported attributes ----------------------- - - - -This document is autogenerated from assets/layers/current_view/current_view.json \ No newline at end of file diff --git a/Docs/Layers/cycle_highways.md b/Docs/Layers/cycle_highways.md deleted file mode 100644 index f190ce448b..0000000000 --- a/Docs/Layers/cycle_highways.md +++ /dev/null @@ -1,107 +0,0 @@ -cycle_highways -================ - -## Table of contents - -1. [cycle_highways](#cycle_highways) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [cycle_highways-name](#cycle_highways-name) - + [cycle_highways-ref](#cycle_highways-ref) - + [cycle_highways-state](#cycle_highways-state) - + [cycle-highway-length](#cycle-highway-length) - + [website](#website) - + [all_tags](#all_tags) - - -- Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` - -[Go to the source code](../assets/layers/cycle_highways/cycle_highways.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- cycle_network - =BE-VLG: - cycle_highway - -Supported attributes ----------------------- - - - -**Warning** This quick overview is incomplete - -attribute | type | values which are supported by this layer ------------ | ------ | ------------------------------------------ -[](https://taginfo.openstreetmap.org/keys/name#values) [name](https://wiki.openstreetmap.org/wiki/Key:name) | [string](../SpecialInputElements.md#string) | -[](https://taginfo.openstreetmap.org/keys/ref#values) [ref](https://wiki.openstreetmap.org/wiki/Key:ref) | [string](../SpecialInputElements.md#string) | -[](https://taginfo.openstreetmap.org/keys/state#values) [state](https://wiki.openstreetmap.org/wiki/Key:state) | [string](../SpecialInputElements.md#string) | [proposed](https://wiki.openstreetmap.org/wiki/Tag:state%3Dproposed) [proposed](https://wiki.openstreetmap.org/wiki/Tag:state%3Dproposed) [proposed](https://wiki.openstreetmap.org/wiki/Tag:state%3Dproposed) [temporary](https://wiki.openstreetmap.org/wiki/Tag:state%3Dtemporary) [](https://wiki.openstreetmap.org/wiki/Tag:state%3D) -[](https://taginfo.openstreetmap.org/keys/website#values) [website](https://wiki.openstreetmap.org/wiki/Key:website) | [url](../SpecialInputElements.md#url) | - -### cycle_highways-name - -The question is **What is the name of this cycle highway?** - -This rendering asks information about the property [name](https://wiki.openstreetmap.org/wiki/Key:name) -This is rendered with `The name is {name}` - -### cycle_highways-ref - -The question is **What is the reference number of this cycle highway?** - -This rendering asks information about the property [ref](https://wiki.openstreetmap.org/wiki/Key:ref) -This is rendered with `Referentienummer is {ref}` - -### cycle_highways-state - -The question is **What is the state of this link?** - -This rendering asks information about the property [state](https://wiki.openstreetmap.org/wiki/Key:state) -This is rendered with `The current state of this link is {state}` - -- **This is a proposed route which can be cycled** corresponds - with state - =proposed -- **This is a proposed route which has missing links (thus: some parts don't even have a building permit yet)** - corresponds with state - =proposed - &note:state - =has_highway_no -- **This is a proposed route which has some links which are under construction** corresponds - with state - =proposed - &note:state - = - has_highway_under_construction -- **This is a temporary deviation** corresponds - with state - =temporary -- **This link is operational and signposted** corresponds with - -### cycle-highway-length - -_This tagrendering has no question and is thus read-only_ - -### website - -The question is **What is the website of {name}?** - -This rendering asks information about the property [website](https://wiki.openstreetmap.org/wiki/Key:website) -This is rendered with `{website}` - -- **{contact:website}** corresponds with contact:website~^..*$_This - option cannot be chosen as answer_ - -### all_tags - -_This tagrendering has no question and is thus read-only_ - -This document is autogenerated from assets/layers/cycle_highways/cycle_highways.json \ No newline at end of file diff --git a/Docs/Layers/cycleways_and_roads.md b/Docs/Layers/cycleways_and_roads.md index 25db981c39..bf812cea5e 100644 --- a/Docs/Layers/cycleways_and_roads.md +++ b/Docs/Layers/cycleways_and_roads.md @@ -12,32 +12,9 @@ All infrastructure that someone can cycle over, accompanied with questions about -## Table of contents - -1. [cycleways_and_roads](#cycleways_and_roads) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [Cycleway type for a road](#cycleway-type-for-a-road) - + [is lit?](#is-lit) - + [Is this a cyclestreet? (For a road)](#is-this-a-cyclestreet-(for-a-road)) - + [Maxspeed (for road)](#maxspeed-(for-road)) - + [Cycleway:surface](#cyclewaysurface) - + [Cycleway:smoothness](#cyclewaysmoothness) - + [Surface of the road](#surface-of-the-road) - + [Surface of the street](#surface-of-the-street) - + [width:carriageway](#widthcarriageway) - + [cycleway-lane-track-traffic-signs](#cycleway-lane-track-traffic-signs) - + [cycleway-traffic-signs](#cycleway-traffic-signs) - + [cycleway-traffic-signs-supplementary](#cycleway-traffic-signs-supplementary) - + [cycleways_and_roads-cycleway:buffer](#cycleways_and_roads-cyclewaybuffer) - + [cyclelan-segregation](#cyclelan-segregation) - + [cycleway-segregation](#cycleway-segregation) - - - + - This layer is shown at zoomlevel **16** and higher - This layer is needed as dependency for layer [barrier](#barrier) - This layer is needed as dependency for layer [crossings](#crossings) @@ -54,8 +31,6 @@ All infrastructure that someone can cycle over, accompanied with questions about - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/cycleways_and_roads/cycleways_and_roads.json) - Basic tags for this layer diff --git a/Docs/Layers/defibrillator.md b/Docs/Layers/defibrillator.md index dc04ad735c..2716008ae0 100644 --- a/Docs/Layers/defibrillator.md +++ b/Docs/Layers/defibrillator.md @@ -12,33 +12,9 @@ A layer showing defibrillators which can be used in case of emergency. This cont -## Table of contents - -1. [defibrillator](#defibrillator) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [defibrillator-indoors](#defibrillator-indoors) - + [defibrillator-access](#defibrillator-access) - + [defibrillator-defibrillator](#defibrillator-defibrillator) - + [defibrillator-level](#defibrillator-level) - + [defibrillator-defibrillator:location](#defibrillator-defibrillatorlocation) - + [defibrillator-defibrillator:location:en](#defibrillator-defibrillatorlocation:en) - + [defibrillator-defibrillator:location:fr](#defibrillator-defibrillatorlocation:fr) - + [wheelchair-access](#wheelchair-access) - + [defibrillator-ref](#defibrillator-ref) - + [defibrillator-email](#defibrillator-email) - + [defibrillator-phone](#defibrillator-phone) - + [defibrillator-opening_hours](#defibrillator-opening_hours) - + [defibrillator-description](#defibrillator-description) - + [defibrillator-survey:date](#defibrillator-surveydate) - + [defibrillator-fixme](#defibrillator-fixme) - - - + - This layer is shown at zoomlevel **12** and higher - This layer will automatically load [walls_and_buildings](./walls_and_buildings.md) into the layout as it depends on it: a preset snaps to this layer (presets[1]) @@ -54,8 +30,6 @@ A layer showing defibrillators which can be used in case of emergency. This cont - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/defibrillator/defibrillator.json) - Basic tags for this layer diff --git a/Docs/Layers/direction.md b/Docs/Layers/direction.md index 04b086b9ae..9b419f3a81 100644 --- a/Docs/Layers/direction.md +++ b/Docs/Layers/direction.md @@ -12,17 +12,9 @@ This layer visualizes directions -## Table of contents - -1. [direction](#direction) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - - - + - This layer is shown at zoomlevel **16** and higher - This layer cannot be toggled in the filter view. If you import this layer in your theme, override `title` to make this toggleable. @@ -38,8 +30,6 @@ This layer visualizes directions - [surveillance](https://mapcomplete.osm.be/surveillance) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/direction/direction.json) - Basic tags for this layer diff --git a/Docs/Layers/drinking_water.md b/Docs/Layers/drinking_water.md index e139ea2280..df7a790fd2 100644 --- a/Docs/Layers/drinking_water.md +++ b/Docs/Layers/drinking_water.md @@ -12,21 +12,9 @@ A layer showing drinking water fountains -## Table of contents - -1. [drinking_water](#drinking_water) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [Still in use?](#still-in-use) - + [Bottle refill](#bottle-refill) - + [render-closest-drinking-water](#render-closest-drinking-water) - - - + - This layer is shown at zoomlevel **13** and higher - This layer will automatically load [drinking_water](./drinking_water.md) into the layout as it depends on it: A calculated tag loads features from this layer (calculatedTag[0] which calculates the value for _closest_other_drinking_water) - This layer is needed as dependency for layer [drinking_water](#drinking_water) @@ -45,8 +33,6 @@ A layer showing drinking water fountains - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/drinking_water/drinking_water.json) - Basic tags for this layer diff --git a/Docs/Layers/dumpstations.md b/Docs/Layers/dumpstations.md index 5b4414abef..12bed82549 100644 --- a/Docs/Layers/dumpstations.md +++ b/Docs/Layers/dumpstations.md @@ -1,145 +1,233 @@ -dumpstations + + + dumpstations ============== - + Sanitary dump stations -## Table of contents - -1. [dumpstations](#dumpstations) - * [Themes using this layer](#themes-using-this-layer) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [images](#images) - + [dumpstations-fee](#dumpstations-fee) - + [dumpstations-charge](#dumpstations-charge) - + [dumpstations-waterpoint](#dumpstations-waterpoint) - + [dumpstations-grey-water](#dumpstations-grey-water) - + [dumpstations-chemical-waste](#dumpstations-chemical-waste) - + [dumpstations-access](#dumpstations-access) - + [dumpstations-network](#dumpstations-network) - -#### Themes using this layer - -- [campersite](https://mapcomplete.osm.be/campersite) - -[Go to the source code](../assets/layers/dumpstations/dumpstations.json) -Basic tags for this layer + + + - This layer is shown at zoomlevel **10** and higher + + + + +#### Themes using this layer + + + + + + - [campersite](https://mapcomplete.osm.be/campersite) + + + + + Basic tags for this layer --------------------------- Elements must have the all of following tags to be shown on this layer: -- amenity - = - sanitary_dump_station -- vehicle!~^no$ -Supported attributes + + - amenity=sanitary_dump_station + - vehicle!~^no$ + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22amenity%22%3D%22sanitary_dump_station%22%5D%5B%22vehicle%22!~%22%5Eno%24%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes ---------------------- **Warning** This quick overview is incomplete + + attribute | type | values which are supported by this layer ----------- | ------ | ------------------------------------------ [](https://taginfo.openstreetmap.org/keys/fee#values) [fee](https://wiki.openstreetmap.org/wiki/Key:fee) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:fee%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:fee%3Dno) -[](https://taginfo.openstreetmap.org/keys/charge#values) [charge](https://wiki.openstreetmap.org/wiki/Key:charge) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/charge#values) [charge](https://wiki.openstreetmap.org/wiki/Key:charge) | [string](../SpecialInputElements.md#string) | [](https://taginfo.openstreetmap.org/keys/water_point#values) [water_point](https://wiki.openstreetmap.org/wiki/Key:water_point) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:water_point%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:water_point%3Dno) [](https://taginfo.openstreetmap.org/keys/sanitary_dump_station:grey_water#values) [sanitary_dump_station:grey_water](https://wiki.openstreetmap.org/wiki/Key:sanitary_dump_station:grey_water) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:sanitary_dump_station:grey_water%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:sanitary_dump_station:grey_water%3Dno) [](https://taginfo.openstreetmap.org/keys/sanitary_dump_station:chemical_toilet#values) [sanitary_dump_station:chemical_toilet](https://wiki.openstreetmap.org/wiki/Key:sanitary_dump_station:chemical_toilet) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:sanitary_dump_station:chemical_toilet%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:sanitary_dump_station:chemical_toilet%3Dno) [](https://taginfo.openstreetmap.org/keys/access#values) [access](https://wiki.openstreetmap.org/wiki/Key:access) | Multiple choice | [network](https://wiki.openstreetmap.org/wiki/Tag:access%3Dnetwork) [customers](https://wiki.openstreetmap.org/wiki/Tag:access%3Dcustomers) [yes](https://wiki.openstreetmap.org/wiki/Tag:access%3Dyes) -[](https://taginfo.openstreetmap.org/keys/network#values) [network](https://wiki.openstreetmap.org/wiki/Key:network) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/network#values) [network](https://wiki.openstreetmap.org/wiki/Key:network) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/operator#values) [operator](https://wiki.openstreetmap.org/wiki/Key:operator) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/power_supply#values) [power_supply](https://wiki.openstreetmap.org/wiki/Key:power_supply) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:power_supply%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:power_supply%3Dno) + + + + +### images + -### images _This tagrendering has no question and is thus read-only_ -### dumpstations-fee + + + + +### dumpstations-fee + + The question is **Does this place charge a fee?** -- **You need to pay for use** corresponds with - fee=yes -- **Can be used for free** corresponds with - fee=no -### dumpstations-charge + + + + - **You need to pay for use** corresponds with fee=yes + - **Can be used for free** corresponds with fee=no + + + + +### dumpstations-charge + + The question is **How much does this place charge?** -This rendering asks information about the property [charge](https://wiki.openstreetmap.org/wiki/Key:charge) +This rendering asks information about the property [charge](https://wiki.openstreetmap.org/wiki/Key:charge) This is rendered with `This place charges {charge}` -### dumpstations-waterpoint + + +### dumpstations-waterpoint + + The question is **Does this place have a water point?** -- **This place has a water point** corresponds - with water_point - =yes -- **This place does not have a water point** corresponds - with water_point - =no -### dumpstations-grey-water + + + + - **This place has a water point** corresponds with water_point=yes + - **This place does not have a water point** corresponds with water_point=no + + + + +### dumpstations-grey-water + + The question is **Can you dispose of grey water here?** -- **You can dispose of grey water here** corresponds - with - sanitary_dump_station:grey_water - =yes -- **You cannot dispose of gray water here** corresponds - with - sanitary_dump_station:grey_water - =no -### dumpstations-chemical-waste + + + + - **You can dispose of grey water here** corresponds with sanitary_dump_station:grey_water=yes + - **You cannot dispose of gray water here** corresponds with sanitary_dump_station:grey_water=no + + + + +### dumpstations-chemical-waste + + The question is **Can you dispose of chemical toilet waste here?** -- **You can dispose of chemical toilet waste here** corresponds - with - sanitary_dump_station:chemical_toilet - =yes -- **You cannot dispose of chemical toilet waste here** corresponds - with - sanitary_dump_station:chemical_toilet - =no -### dumpstations-access + + + + - **You can dispose of chemical toilet waste here** corresponds with sanitary_dump_station:chemical_toilet=yes + - **You cannot dispose of chemical toilet waste here** corresponds with sanitary_dump_station:chemical_toilet=no + + + + +### dumpstations-access + + The question is **Who can use this dump station?** -- **You need a network key/code to use this** corresponds - with access - =network -- **You need to be a customer of camping/campersite to use this place** corresponds - with access - =customers -- **Anyone can use this dump station** corresponds - with access - =public_This option cannot be - chosen as answer_ -- **Anyone can use this dump station** corresponds - with access - =yes -### dumpstations-network + + + + - **You need a network key/code to use this** corresponds with access=network + - **You need to be a customer of camping/campersite to use this place** corresponds with access=customers + - **Anyone can use this dump station** corresponds with access=public_This option cannot be chosen as answer_ + - **Anyone can use this dump station** corresponds with access=yes + + + + +### dumpstations-network + + The question is **What network is this place a part of? (skip if none)** -This rendering asks information about the property [network](https://wiki.openstreetmap.org/wiki/Key:network) +This rendering asks information about the property [network](https://wiki.openstreetmap.org/wiki/Key:network) This is rendered with `This station is part of network {network}` -This document is autogenerated from assets/layers/dumpstations/dumpstations.json \ No newline at end of file + + +### operator + + + +The question is **Who operates this place?** + +This rendering asks information about the property [operator](https://wiki.openstreetmap.org/wiki/Key:operator) +This is rendered with `This place is operated by {operator}` + + + +### power_supply + + + +The question is **Does this place have a power supply?** + + + + + + - **This place has a power supply** corresponds with power_supply=yes + - **This place does not have power supply** corresponds with power_supply=no + + + + +### questions + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### minimap + + + +_This tagrendering has no question and is thus read-only_ + + + +This document is autogenerated from [assets/themes/campersite/campersite.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/campersite/campersite.json) \ No newline at end of file diff --git a/Docs/Layers/education_institutions_without_etymology.md b/Docs/Layers/education_institutions_without_etymology.md new file mode 100644 index 0000000000..b4555ec049 --- /dev/null +++ b/Docs/Layers/education_institutions_without_etymology.md @@ -0,0 +1,162 @@ + + + education_institutions_without_etymology +========================================== + + + + + +All objects which have an etymology known + + + + + + + - This layer is shown at zoomlevel **18** and higher + + + + +#### Themes using this layer + + + + + + - [etymology](https://mapcomplete.osm.be/etymology) + + + + + Basic tags for this layer +--------------------------- + + + +Elements must have the all of following tags to be shown on this layer: + + + + - name~^..*$ + - amenity=school|amenity=kindergarten|amenity=university|amenity=college|landuse=education + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22amenity%22%3D%22school%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22amenity%22%3D%22kindergarten%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22amenity%22%3D%22university%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22amenity%22%3D%22college%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22landuse%22%3D%22education%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes +---------------------- + + + +**Warning** This quick overview is incomplete + + + +attribute | type | values which are supported by this layer +----------- | ------ | ------------------------------------------ +[](https://taginfo.openstreetmap.org/keys/name:etymology:wikidata#values) [name:etymology:wikidata](https://wiki.openstreetmap.org/wiki/Key:name:etymology:wikidata) | [wikidata](../SpecialInputElements.md#wikidata) | +[](https://taginfo.openstreetmap.org/keys/name:etymology#values) [name:etymology](https://wiki.openstreetmap.org/wiki/Key:name:etymology) | [string](../SpecialInputElements.md#string) | [unknown](https://wiki.openstreetmap.org/wiki/Tag:name:etymology%3Dunknown) + + + + +### etymology-images-from-wikipedia + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### wikipedia-etymology + + + +The question is **What is the Wikidata-item that this object is named after?** + +This rendering asks information about the property [name:etymology:wikidata](https://wiki.openstreetmap.org/wiki/Key:name:etymology:wikidata) +This is rendered with `

Wikipedia article of the name giver

{wikipedia(name:etymology:wikidata):max-height:20rem}` + + + +### zoeken op inventaris onroerend erfgoed + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### simple etymology + + + +The question is **What is this object named after?
This might be written on the street name sign** + +This rendering asks information about the property [name:etymology](https://wiki.openstreetmap.org/wiki/Key:name:etymology) +This is rendered with `Named after {name:etymology}` + + + + - **The origin of this name is unknown in all literature** corresponds with name:etymology=unknown + + + + +### questions + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### street-name-sign-image + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### minimap + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### etymology_multi_apply + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### wikipedia + + + +_This tagrendering has no question and is thus read-only_ + + + +This document is autogenerated from [assets/themes/etymology/etymology.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/etymology/etymology.json) \ No newline at end of file diff --git a/Docs/Layers/entrance.md b/Docs/Layers/entrance.md index fa867ae210..fe78376551 100644 --- a/Docs/Layers/entrance.md +++ b/Docs/Layers/entrance.md @@ -12,22 +12,9 @@ A layer showing entrances and offering capabilities to survey some advanced data -## Table of contents - -1. [entrance](#entrance) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [Entrance type](#entrance-type) - + [Door_type](#door_type) - + [automatic_door](#automatic_door) - + [width](#width) - - - + - This layer is shown at zoomlevel **14** and higher - This layer will automatically load [walls_and_buildings](./walls_and_buildings.md) into the layout as it depends on it: a preset snaps to this layer (presets[0]) - This layer will automatically load [pedestrian_path](./pedestrian_path.md) into the layout as it depends on it: a preset snaps to this layer (presets[0]) @@ -44,8 +31,6 @@ A layer showing entrances and offering capabilities to survey some advanced data - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/entrance/entrance.json) - Basic tags for this layer diff --git a/Docs/Layers/etymology.md b/Docs/Layers/etymology.md index 79bedbca64..f2766a3ec2 100644 --- a/Docs/Layers/etymology.md +++ b/Docs/Layers/etymology.md @@ -12,27 +12,9 @@ All objects which have an etymology known -## Table of contents - -1. [etymology](#etymology) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [etymology-images-from-wikipedia](#etymology-images-from-wikipedia) - + [wikipedia-etymology](#wikipedia-etymology) - + [zoeken op inventaris onroerend erfgoed](#zoeken-op-inventaris-onroerend-erfgoed) - + [simple etymology](#simple-etymology) - + [questions](#questions) - + [street-name-sign-image](#street-name-sign-image) - + [minimap](#minimap) - + [etymology_multi_apply](#etymology_multi_apply) - + [wikipedia](#wikipedia) - - - - + - This layer is shown at zoomlevel **12** and higher @@ -47,8 +29,6 @@ All objects which have an etymology known - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/etymology/etymology.json) - Basic tags for this layer diff --git a/Docs/Layers/extinguisher.md b/Docs/Layers/extinguisher.md index a671eb662a..394ec9bf1b 100644 --- a/Docs/Layers/extinguisher.md +++ b/Docs/Layers/extinguisher.md @@ -12,20 +12,9 @@ Map layer to show fire extinguishers. -## Table of contents - -1. [extinguisher](#extinguisher) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [extinguisher-location](#extinguisher-location) - + [images](#images) - - - - + - This layer is shown at zoomlevel **14** and higher @@ -40,8 +29,6 @@ Map layer to show fire extinguishers. - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/extinguisher/extinguisher.json) - Basic tags for this layer diff --git a/Docs/Layers/facadegardens.md b/Docs/Layers/facadegardens.md index e29139bfa4..c207a738c8 100644 --- a/Docs/Layers/facadegardens.md +++ b/Docs/Layers/facadegardens.md @@ -1,138 +1,200 @@ -facadegardens + + + facadegardens =============== - + Facade gardens -## Table of contents - -1. [facadegardens](#facadegardens) - * [Themes using this layer](#themes-using-this-layer) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [images](#images) - + [facadegardens-direction](#facadegardens-direction) - + [facadegardens-sunshine](#facadegardens-sunshine) - + [facadegardens-rainbarrel](#facadegardens-rainbarrel) - + [facadegardens-start_date](#facadegardens-start_date) - + [facadegardens-edible](#facadegardens-edible) - + [facadegardens-plants](#facadegardens-plants) - + [facadegardens-description](#facadegardens-description) - -#### Themes using this layer - -- [facadegardens](https://mapcomplete.osm.be/facadegardens) - -[Go to the source code](../assets/layers/facadegardens/facadegardens.json) -Basic tags for this layer + + + - This layer is shown at zoomlevel **12** and higher + + + + +#### Themes using this layer + + + + + + - [facadegardens](https://mapcomplete.osm.be/facadegardens) + + + + + Basic tags for this layer --------------------------- Elements must have the all of following tags to be shown on this layer: -- leisure - =garden -- garden:type - =facade_garden -Supported attributes + + - leisure=garden + - garden:type=facade_garden + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22garden%3Atype%22%3D%22facade_garden%22%5D%5B%22leisure%22%3D%22garden%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes ---------------------- **Warning** This quick overview is incomplete + + attribute | type | values which are supported by this layer ----------- | ------ | ------------------------------------------ -[](https://taginfo.openstreetmap.org/keys/direction#values) [direction](https://wiki.openstreetmap.org/wiki/Key:direction) | [direction](../SpecialInputElements.md#direction) | +[](https://taginfo.openstreetmap.org/keys/direction#values) [direction](https://wiki.openstreetmap.org/wiki/Key:direction) | [direction](../SpecialInputElements.md#direction) | [](https://taginfo.openstreetmap.org/keys/direct_sunlight#values) [direct_sunlight](https://wiki.openstreetmap.org/wiki/Key:direct_sunlight) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:direct_sunlight%3Dyes) [partial](https://wiki.openstreetmap.org/wiki/Tag:direct_sunlight%3Dpartial) [no](https://wiki.openstreetmap.org/wiki/Tag:direct_sunlight%3Dno) [](https://taginfo.openstreetmap.org/keys/rain_barrel#values) [rain_barrel](https://wiki.openstreetmap.org/wiki/Key:rain_barrel) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:rain_barrel%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:rain_barrel%3Dno) -[](https://taginfo.openstreetmap.org/keys/start_date#values) [start_date](https://wiki.openstreetmap.org/wiki/Key:start_date) | [text](../SpecialInputElements.md#text) | +[](https://taginfo.openstreetmap.org/keys/start_date#values) [start_date](https://wiki.openstreetmap.org/wiki/Key:start_date) | [text](../SpecialInputElements.md#text) | [](https://taginfo.openstreetmap.org/keys/edible#values) [edible](https://wiki.openstreetmap.org/wiki/Key:edible) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:edible%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:edible%3Dno) [](https://taginfo.openstreetmap.org/keys/plant#values) [plant](https://wiki.openstreetmap.org/wiki/Key:plant) | Multiple choice | [vine](https://wiki.openstreetmap.org/wiki/Tag:plant%3Dvine) [flower](https://wiki.openstreetmap.org/wiki/Tag:plant%3Dflower) [shrub](https://wiki.openstreetmap.org/wiki/Tag:plant%3Dshrub) [groundcover](https://wiki.openstreetmap.org/wiki/Tag:plant%3Dgroundcover) -[](https://taginfo.openstreetmap.org/keys/description#values) [description](https://wiki.openstreetmap.org/wiki/Key:description) | [text](../SpecialInputElements.md#text) | +[](https://taginfo.openstreetmap.org/keys/description#values) [description](https://wiki.openstreetmap.org/wiki/Key:description) | [text](../SpecialInputElements.md#text) | + + + + +### images + -### images _This tagrendering has no question and is thus read-only_ -### facadegardens-direction + + + + +### facadegardens-direction + + The question is **What is the orientation of the garden?** -This rendering asks information about the property [direction](https://wiki.openstreetmap.org/wiki/Key:direction) +This rendering asks information about the property [direction](https://wiki.openstreetmap.org/wiki/Key:direction) This is rendered with `Orientation: {direction} (where 0=N and 90=O)` -### facadegardens-sunshine + + +### facadegardens-sunshine + + The question is **Is the garden shaded or sunny?** -- **The garden is in full sun** corresponds - with direct_sunlight - =yes -- **The garden is in partial shade** corresponds - with direct_sunlight - =partial -- **The garden is in the shade** corresponds - with direct_sunlight - =no -### facadegardens-rainbarrel + + + + - **The garden is in full sun** corresponds with direct_sunlight=yes + - **The garden is in partial shade** corresponds with direct_sunlight=partial + - **The garden is in the shade** corresponds with direct_sunlight=no + + + + +### facadegardens-rainbarrel + + The question is **Is there a water barrel installed for the garden?** -- **There is a rain barrel** corresponds - with rain_barrel - =yes -- **There is no rain barrel** corresponds - with rain_barrel - =no -### facadegardens-start_date + + + + - **There is a rain barrel** corresponds with rain_barrel=yes + - **There is no rain barrel** corresponds with rain_barrel=no + + + + +### facadegardens-start_date + + The question is **When was the garden constructed? (a year is sufficient)** -This rendering asks information about the property [start_date](https://wiki.openstreetmap.org/wiki/Key:start_date) +This rendering asks information about the property [start_date](https://wiki.openstreetmap.org/wiki/Key:start_date) This is rendered with `Construction date of the garden: {start_date}` -### facadegardens-edible + + +### facadegardens-edible + + The question is **Are there any edible plants?** -- **There are edible plants** corresponds with - edible=yes -- **There are no edible plants** corresponds - with edible - =no -### facadegardens-plants + + + + - **There are edible plants** corresponds with edible=yes + - **There are no edible plants** corresponds with edible=no + + + + +### facadegardens-plants + + The question is **What kinds of plants grow here?** -- **There are vines** corresponds with plant - =vine -- **There are flowering plants** corresponds - with plant - =flower -- **There are shrubs** corresponds with - plant=shrub -- **There are groundcovering plants** corresponds - with plant - =groundcover -### facadegardens-description + + + + - **There are vines** corresponds with plant=vine + - **There are flowering plants** corresponds with plant=flower + - **There are shrubs** corresponds with plant=shrub + - **There are groundcovering plants** corresponds with plant=groundcover + + + + +### facadegardens-description + + The question is **Extra describing info about the garden (if needed and not yet described above)** -This rendering asks information about the property [description](https://wiki.openstreetmap.org/wiki/Key:description) +This rendering asks information about the property [description](https://wiki.openstreetmap.org/wiki/Key:description) This is rendered with `More details: {description}` -This document is autogenerated from assets/layers/facadegardens/facadegardens.json \ No newline at end of file + + +### questions + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### minimap + + + +_This tagrendering has no question and is thus read-only_ + + + +This document is autogenerated from [assets/themes/facadegardens/facadegardens.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/facadegardens/facadegardens.json) \ No newline at end of file diff --git a/Docs/Layers/fietsstraat.md b/Docs/Layers/fietsstraat.md index 327223b219..37ff789bcd 100644 --- a/Docs/Layers/fietsstraat.md +++ b/Docs/Layers/fietsstraat.md @@ -1,4 +1,6 @@ -fietsstraat + + + fietsstraat ============= @@ -7,38 +9,115 @@ fietsstraat A cyclestreet is a street where motorized traffic is not allowed to overtake a cyclist -## Table of contents - -1. [fietsstraat](#fietsstraat) - * [Themes using this layer](#themes-using-this-layer) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [images](#images) - -#### Themes using this layer - -- [cyclestreets](https://mapcomplete.osm.be/cyclestreets) - -[Go to the source code](../assets/layers/fietsstraat/fietsstraat.json) -Basic tags for this layer + + + - This layer is shown at zoomlevel **7** and higher + + + + +#### Themes using this layer + + + + + + - [cyclestreets](https://mapcomplete.osm.be/cyclestreets) + + + + + Basic tags for this layer --------------------------- Elements must have the all of following tags to be shown on this layer: -- cyclestreet - =yes -Supported attributes + + - cyclestreet=yes + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22cyclestreet%22%3D%22yes%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes ---------------------- -### images + + +**Warning** This quick overview is incomplete + + + +attribute | type | values which are supported by this layer +----------- | ------ | ------------------------------------------ +[](https://taginfo.openstreetmap.org/keys/cyclestreet#values) [cyclestreet](https://wiki.openstreetmap.org/wiki/Key:cyclestreet) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:cyclestreet%3Dyes) [yes](https://wiki.openstreetmap.org/wiki/Tag:cyclestreet%3Dyes) [](https://wiki.openstreetmap.org/wiki/Tag:cyclestreet%3D) [](https://wiki.openstreetmap.org/wiki/Tag:cyclestreet%3D) +[](https://taginfo.openstreetmap.org/keys/cyclestreet:start_date#values) [cyclestreet:start_date](https://wiki.openstreetmap.org/wiki/Key:cyclestreet:start_date) | [date](../SpecialInputElements.md#date) | + + + + +### images + + _This tagrendering has no question and is thus read-only_ -This document is autogenerated from assets/layers/fietsstraat/fietsstraat.json \ No newline at end of file + + + + +### is_cyclestreet + + + +The question is **Is the street {name} a cyclestreet?** + + + + + + - **This street is a cyclestreet (and has a speed limit of 30 km/h)** corresponds with cyclestreet=yes&maxspeed=30&overtaking:motor_vehicle=no + - **This street is a cyclestreet** corresponds with cyclestreet=yes + - **This street will become a cyclstreet soon** corresponds with proposed:cyclestreet=yes + - **This street is not a cyclestreet** corresponds with + + + + +### future_cyclestreet + + + +The question is **When will this street become a cyclestreet?** + +This rendering asks information about the property [cyclestreet:start_date](https://wiki.openstreetmap.org/wiki/Key:cyclestreet:start_date) +This is rendered with `This street will become a cyclestreet at {cyclestreet:start_date}` + + + +### questions + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### minimap + + + +_This tagrendering has no question and is thus read-only_ + + + +This document is autogenerated from [assets/themes/cyclestreets/cyclestreets.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/cyclestreets/cyclestreets.json) \ No newline at end of file diff --git a/Docs/Layers/fire_station.md b/Docs/Layers/fire_station.md index 3c3a784cad..36a76ced97 100644 --- a/Docs/Layers/fire_station.md +++ b/Docs/Layers/fire_station.md @@ -12,24 +12,9 @@ Map layer to show fire stations. -## Table of contents - -1. [fire_station](#fire_station) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [station-name](#station-name) - + [station-street](#station-street) - + [station-place](#station-place) - + [station-agency](#station-agency) - + [station-operator](#station-operator) - + [images](#images) - - - - + - This layer is shown at zoomlevel **12** and higher @@ -44,8 +29,6 @@ Map layer to show fire stations. - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/fire_station/fire_station.json) - Basic tags for this layer diff --git a/Docs/Layers/food.md b/Docs/Layers/food.md index 390468ab90..b6f2ad1ff3 100644 --- a/Docs/Layers/food.md +++ b/Docs/Layers/food.md @@ -12,39 +12,9 @@ A layer showing restaurants and fast-food amenities (with a special rendering fo -## Table of contents - -1. [food](#food) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [Name](#name) - + [Fastfood vs restaurant](#fastfood-vs-restaurant) - + [opening_hours](#opening_hours) - + [website](#website) - + [email](#email) - + [phone](#phone) - + [payment-options](#payment-options) - + [wheelchair-access](#wheelchair-access) - + [Cuisine](#cuisine) - + [Takeaway](#takeaway) - + [Vegetarian (no friture)](#vegetarian-(no-friture)) - + [Vegan (no friture)](#vegan-(no-friture)) - + [halal (no friture)](#halal-(no-friture)) - + [friture-vegetarian](#friture-vegetarian) - + [friture-vegan](#friture-vegan) - + [friture-oil](#friture-oil) - + [friture-take-your-container](#friture-take-your-container) - + [service:electricity](#serviceelectricity) - + [dog-access](#dog-access) - + [reviews](#reviews) - - - - + - This layer is shown at zoomlevel **12** and higher @@ -60,8 +30,6 @@ A layer showing restaurants and fast-food amenities (with a special rendering fo - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/food/food.json) - Basic tags for this layer diff --git a/Docs/Layers/forest.md b/Docs/Layers/forest.md deleted file mode 100644 index 6688ee8c4a..0000000000 --- a/Docs/Layers/forest.md +++ /dev/null @@ -1,50 +0,0 @@ -forest -======== - - - - - -Een bos is een verzameling bomen, al dan niet als productiehout. - -## Table of contents - -1. [forest](#forest) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [images](#images) - - -- This layer will automatically load [parks](./parks.md) into the layout as it depends on it: A calculated tag loads - features from this layer (calculatedTag[0] which calculates the value for _overlapWithUpperLayers) -- This layer will automatically load [nature_reserve_buurtnatuur](./nature_reserve_buurtnatuur.md) into the layout as - it depends on it: A calculated tag loads features from this layer (calculatedTag[0] which calculates the value for _ - overlapWithUpperLayers) - -[Go to the source code](../assets/layers/forest/forest.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- landuse - =forest - |natural - =wood - |natural - =scrub - -Supported attributes ----------------------- - -### images - -_This tagrendering has no question and is thus read-only_ - -This document is autogenerated from assets/layers/forest/forest.json \ No newline at end of file diff --git a/Docs/Layers/friture.md b/Docs/Layers/friture.md new file mode 100644 index 0000000000..cf8d6024f0 --- /dev/null +++ b/Docs/Layers/friture.md @@ -0,0 +1,445 @@ + + + friture +========= + + + + + +A layer showing restaurants and fast-food amenities (with a special rendering for friteries) + + + + + + + - This layer is shown at zoomlevel **12** and higher + + + + +#### Themes using this layer + + + + + + - [fritures](https://mapcomplete.osm.be/fritures) + + + + + Basic tags for this layer +--------------------------- + + + +Elements must have the all of following tags to be shown on this layer: + + + + - cuisine=friture + - amenity=fast_food|amenity=restaurant + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22cuisine%22%3D%22friture%22%5D%5B%22amenity%22%3D%22fast_food%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22cuisine%22%3D%22friture%22%5D%5B%22amenity%22%3D%22restaurant%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes +---------------------- + + + +**Warning** This quick overview is incomplete + + + +attribute | type | values which are supported by this layer +----------- | ------ | ------------------------------------------ +[](https://taginfo.openstreetmap.org/keys/name#values) [name](https://wiki.openstreetmap.org/wiki/Key:name) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/amenity#values) [amenity](https://wiki.openstreetmap.org/wiki/Key:amenity) | Multiple choice | [fast_food](https://wiki.openstreetmap.org/wiki/Tag:amenity%3Dfast_food) [restaurant](https://wiki.openstreetmap.org/wiki/Tag:amenity%3Drestaurant) +[](https://taginfo.openstreetmap.org/keys/opening_hours#values) [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) | [opening_hours](../SpecialInputElements.md#opening_hours) | +[](https://taginfo.openstreetmap.org/keys/website#values) [website](https://wiki.openstreetmap.org/wiki/Key:website) | [url](../SpecialInputElements.md#url) | +[](https://taginfo.openstreetmap.org/keys/email#values) [email](https://wiki.openstreetmap.org/wiki/Key:email) | [email](../SpecialInputElements.md#email) | +[](https://taginfo.openstreetmap.org/keys/phone#values) [phone](https://wiki.openstreetmap.org/wiki/Key:phone) | [phone](../SpecialInputElements.md#phone) | +[](https://taginfo.openstreetmap.org/keys/wheelchair#values) [wheelchair](https://wiki.openstreetmap.org/wiki/Key:wheelchair) | Multiple choice | [designated](https://wiki.openstreetmap.org/wiki/Tag:wheelchair%3Ddesignated) [yes](https://wiki.openstreetmap.org/wiki/Tag:wheelchair%3Dyes) [limited](https://wiki.openstreetmap.org/wiki/Tag:wheelchair%3Dlimited) [no](https://wiki.openstreetmap.org/wiki/Tag:wheelchair%3Dno) +[](https://taginfo.openstreetmap.org/keys/cuisine#values) [cuisine](https://wiki.openstreetmap.org/wiki/Key:cuisine) | [string](../SpecialInputElements.md#string) | [pizza](https://wiki.openstreetmap.org/wiki/Tag:cuisine%3Dpizza) [friture](https://wiki.openstreetmap.org/wiki/Tag:cuisine%3Dfriture) [pasta](https://wiki.openstreetmap.org/wiki/Tag:cuisine%3Dpasta) [kebab](https://wiki.openstreetmap.org/wiki/Tag:cuisine%3Dkebab) [sandwich](https://wiki.openstreetmap.org/wiki/Tag:cuisine%3Dsandwich) [burger](https://wiki.openstreetmap.org/wiki/Tag:cuisine%3Dburger) [sushi](https://wiki.openstreetmap.org/wiki/Tag:cuisine%3Dsushi) [coffee](https://wiki.openstreetmap.org/wiki/Tag:cuisine%3Dcoffee) [italian](https://wiki.openstreetmap.org/wiki/Tag:cuisine%3Ditalian) [french](https://wiki.openstreetmap.org/wiki/Tag:cuisine%3Dfrench) [chinese](https://wiki.openstreetmap.org/wiki/Tag:cuisine%3Dchinese) [greek](https://wiki.openstreetmap.org/wiki/Tag:cuisine%3Dgreek) [indian](https://wiki.openstreetmap.org/wiki/Tag:cuisine%3Dindian) [turkish](https://wiki.openstreetmap.org/wiki/Tag:cuisine%3Dturkish) [thai](https://wiki.openstreetmap.org/wiki/Tag:cuisine%3Dthai) +[](https://taginfo.openstreetmap.org/keys/takeaway#values) [takeaway](https://wiki.openstreetmap.org/wiki/Key:takeaway) | Multiple choice | [only](https://wiki.openstreetmap.org/wiki/Tag:takeaway%3Donly) [yes](https://wiki.openstreetmap.org/wiki/Tag:takeaway%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:takeaway%3Dno) +[](https://taginfo.openstreetmap.org/keys/diet:vegetarian#values) [diet:vegetarian](https://wiki.openstreetmap.org/wiki/Key:diet:vegetarian) | Multiple choice | [no](https://wiki.openstreetmap.org/wiki/Tag:diet:vegetarian%3Dno) [limited](https://wiki.openstreetmap.org/wiki/Tag:diet:vegetarian%3Dlimited) [yes](https://wiki.openstreetmap.org/wiki/Tag:diet:vegetarian%3Dyes) [only](https://wiki.openstreetmap.org/wiki/Tag:diet:vegetarian%3Donly) +[](https://taginfo.openstreetmap.org/keys/diet:vegan#values) [diet:vegan](https://wiki.openstreetmap.org/wiki/Key:diet:vegan) | Multiple choice | [no](https://wiki.openstreetmap.org/wiki/Tag:diet:vegan%3Dno) [limited](https://wiki.openstreetmap.org/wiki/Tag:diet:vegan%3Dlimited) [yes](https://wiki.openstreetmap.org/wiki/Tag:diet:vegan%3Dyes) [only](https://wiki.openstreetmap.org/wiki/Tag:diet:vegan%3Donly) +[](https://taginfo.openstreetmap.org/keys/diet:halal#values) [diet:halal](https://wiki.openstreetmap.org/wiki/Key:diet:halal) | Multiple choice | [no](https://wiki.openstreetmap.org/wiki/Tag:diet:halal%3Dno) [limited](https://wiki.openstreetmap.org/wiki/Tag:diet:halal%3Dlimited) [yes](https://wiki.openstreetmap.org/wiki/Tag:diet:halal%3Dyes) [only](https://wiki.openstreetmap.org/wiki/Tag:diet:halal%3Donly) +[](https://taginfo.openstreetmap.org/keys/diet:vegetarian#values) [diet:vegetarian](https://wiki.openstreetmap.org/wiki/Key:diet:vegetarian) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:diet:vegetarian%3Dyes) [limited](https://wiki.openstreetmap.org/wiki/Tag:diet:vegetarian%3Dlimited) [no](https://wiki.openstreetmap.org/wiki/Tag:diet:vegetarian%3Dno) +[](https://taginfo.openstreetmap.org/keys/diet:vegan#values) [diet:vegan](https://wiki.openstreetmap.org/wiki/Key:diet:vegan) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:diet:vegan%3Dyes) [limited](https://wiki.openstreetmap.org/wiki/Tag:diet:vegan%3Dlimited) [no](https://wiki.openstreetmap.org/wiki/Tag:diet:vegan%3Dno) +[](https://taginfo.openstreetmap.org/keys/friture:oil#values) [friture:oil](https://wiki.openstreetmap.org/wiki/Key:friture:oil) | Multiple choice | [vegetable](https://wiki.openstreetmap.org/wiki/Tag:friture:oil%3Dvegetable) [animal](https://wiki.openstreetmap.org/wiki/Tag:friture:oil%3Danimal) +[](https://taginfo.openstreetmap.org/keys/reusable_packaging:accept#values) [reusable_packaging:accept](https://wiki.openstreetmap.org/wiki/Key:reusable_packaging:accept) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:reusable_packaging:accept%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:reusable_packaging:accept%3Dno) [only](https://wiki.openstreetmap.org/wiki/Tag:reusable_packaging:accept%3Donly) +[](https://taginfo.openstreetmap.org/keys/service:electricity#values) [service:electricity](https://wiki.openstreetmap.org/wiki/Key:service:electricity) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:service:electricity%3Dyes) [limited](https://wiki.openstreetmap.org/wiki/Tag:service:electricity%3Dlimited) [ask](https://wiki.openstreetmap.org/wiki/Tag:service:electricity%3Dask) [no](https://wiki.openstreetmap.org/wiki/Tag:service:electricity%3Dno) +[](https://taginfo.openstreetmap.org/keys/dog#values) [dog](https://wiki.openstreetmap.org/wiki/Key:dog) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:dog%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:dog%3Dno) [leashed](https://wiki.openstreetmap.org/wiki/Tag:dog%3Dleashed) [unleashed](https://wiki.openstreetmap.org/wiki/Tag:dog%3Dunleashed) + + + + +### images + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### Name + + + +The question is **What is the name of this restaurant?** + +This rendering asks information about the property [name](https://wiki.openstreetmap.org/wiki/Key:name) +This is rendered with `The name of this restaurant is {name}` + + + +### Fastfood vs restaurant + + + +The question is **What type of business is this?** + + + + + + - **This is a fastfood-business, focussed on fast service. If seating is available, these are rather limited and functional.** corresponds with amenity=fast_food + - **A restaurant, focussed on creating a nice experience where one is served at the table** corresponds with amenity=restaurant + + + + +### opening_hours + + + +The question is **What are the opening hours of {title()}?** + +This rendering asks information about the property [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) +This is rendered with `

Opening hours

{opening_hours_table(opening_hours)}` + + + +### website + + + +The question is **What is the website of {title()}?** + +This rendering asks information about the property [website](https://wiki.openstreetmap.org/wiki/Key:website) +This is rendered with `{website}` + + + + - **{contact:website}** corresponds with contact:website~^..*$_This option cannot be chosen as answer_ + + + + +### email + + + +The question is **What is the email address of {title()}?** + +This rendering asks information about the property [email](https://wiki.openstreetmap.org/wiki/Key:email) +This is rendered with `{email}` + + + + - **{contact:email}** corresponds with contact:email~^..*$_This option cannot be chosen as answer_ + + + + +### phone + + + +The question is **What is the phone number of {title()}?** + +This rendering asks information about the property [phone](https://wiki.openstreetmap.org/wiki/Key:phone) +This is rendered with `{phone}` + + + + - **{contact:phone}** corresponds with contact:phone~^..*$_This option cannot be chosen as answer_ + + + + +### payment-options + + + +The question is **Which methods of payment are accepted here?** + + + + + + - **Cash is accepted here** corresponds with payment:cash=yesUnselecting this answer will add payment:cash=no + - **Payment cards are accepted here** corresponds with payment:cards=yesUnselecting this answer will add payment:cards=no + + + + +### wheelchair-access + + + +The question is **Is this place accessible with a wheelchair?** + + + + + + - **This place is specially adapted for wheelchair users** corresponds with wheelchair=designated + - **This place is easily reachable with a wheelchair** corresponds with wheelchair=yes + - **It is possible to reach this place in a wheelchair, but it is not easy** corresponds with wheelchair=limited + - **This place is not reachable with a wheelchair** corresponds with wheelchair=no + + + + +### Cuisine + + + +The question is **Which food is served here?** + +This rendering asks information about the property [cuisine](https://wiki.openstreetmap.org/wiki/Key:cuisine) +This is rendered with `This place mostly serves {cuisine}` + + + + - **This is a pizzeria** corresponds with cuisine=pizza + - **This is a friture** corresponds with cuisine=friture + - **Mainly serves pasta** corresponds with cuisine=pasta + - **This is kebab shop** corresponds with cuisine=kebab + - **This is a sandwichbar** corresponds with cuisine=sandwich + - **Burgers are served here** corresponds with cuisine=burger + - **Sushi is served here** corresponds with cuisine=sushi + - **Coffee is served here** corresponds with cuisine=coffee + - **This is an italian restaurant (which serves more then pasta and pizza)** corresponds with cuisine=italian + - **French dishes are served here** corresponds with cuisine=french + - **Chinese dishes are served here** corresponds with cuisine=chinese + - **Greek dishes are served here** corresponds with cuisine=greek + - **Indian dishes are served here** corresponds with cuisine=indian + - **Turkish dishes are served here** corresponds with cuisine=turkish + - **Thai dishes are served here** corresponds with cuisine=thai + + + + +### Takeaway + + + +The question is **Does this place offer takea-way?** + + + + + + - **This is a take-away only business** corresponds with takeaway=only + - **Take-away is possible here** corresponds with takeaway=yes + - **Take-away is not possible here** corresponds with takeaway=no + + + + +### Vegetarian (no friture) + + + +The question is **Does this restaurant have a vegetarian option?** + + + + + + - **No vegetarian options are available** corresponds with diet:vegetarian=no + - **Some vegetarian options are available** corresponds with diet:vegetarian=limited + - **Vegetarian options are available** corresponds with diet:vegetarian=yes + - **All dishes are vegetarian** corresponds with diet:vegetarian=only + + + + +### Vegan (no friture) + + + +The question is **Does this business serve vegan meals?** + + + + + + - **No vegan options available** corresponds with diet:vegan=no + - **Some vegan options are available** corresponds with diet:vegan=limited + - **Vegan options are available** corresponds with diet:vegan=yes + - **All dishes are vegan** corresponds with diet:vegan=only + + + + +### halal (no friture) + + + +The question is **Does this restaurant offer a halal menu?** + + + + + + - **There are no halal options available** corresponds with diet:halal=no + - **There is a small halal menu** corresponds with diet:halal=limited + - **There is a halal menu** corresponds with diet:halal=yes + - **Only halal options are available** corresponds with diet:halal=only + + + + +### friture-vegetarian + + + +The question is **Does this fries shop have vegetarian snacks?** + + + + + + - **Vegetarian snacks are available** corresponds with diet:vegetarian=yes + - **Only a small selection of snacks are vegetarian** corresponds with diet:vegetarian=limited + - **No vegetarian snacks are available** corresponds with diet:vegetarian=no + + + + +### friture-vegan + + + +The question is **Does this fries shop have vegan snacks?** + + + + + + - **Vegan snacks are available** corresponds with diet:vegan=yes + - **A small selection of vegan snacks are available** corresponds with diet:vegan=limited + - **No vegan snacks are available** corresponds with diet:vegan=no + + + + +### friture-oil + + + +The question is **Does this fries shop use vegetable or animal cooking?** + + + + + + - **Vegetable oil** corresponds with friture:oil=vegetable + - **Animal oil** corresponds with friture:oil=animal + + + + +### friture-take-your-container + + + +The question is **If you bring your own container (such as a cooking pot and small pots), is it used to package your order?
** + + + + + + - **You can bring your own containers to get your order, saving on single-use packaging material and thus waste** corresponds with reusable_packaging:accept=yes + - **Bringing your own container is not allowed** corresponds with reusable_packaging:accept=no + - **You must bring your own container to order here.** corresponds with reusable_packaging:accept=only + + + + +### service:electricity + + + +The question is **Does this amenity have electrical outlets, available to customers when they are inside?** + + + + + + - **There are plenty of domestic sockets available to customers seated indoors, where they can charge their electronics** corresponds with service:electricity=yes + - **There are a few domestic sockets available to customers seated indoors, where they can charge their electronics** corresponds with service:electricity=limited + - **There are no sockets available indoors to customers, but charging might be possible if the staff is asked** corresponds with service:electricity=ask + - **There are a no domestic sockets available to customers seated indoors** corresponds with service:electricity=no + + + + +### dog-access + + + +The question is **Are dogs allowed in this business?** + + + + + + - **Dogs are allowed** corresponds with dog=yes + - **Dogs are not allowed** corresponds with dog=no + - **Dogs are allowed, but they have to be leashed** corresponds with dog=leashed + - **Dogs are allowed and can run around freely** corresponds with dog=unleashed + + + + +### reviews + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### questions + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### minimap + + + +_This tagrendering has no question and is thus read-only_ + + + +This document is autogenerated from [assets/themes/fritures/fritures.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/fritures/fritures.json) \ No newline at end of file diff --git a/Docs/Layers/fruitboom.md b/Docs/Layers/fruitboom.md deleted file mode 100644 index e1ded5c7c3..0000000000 --- a/Docs/Layers/fruitboom.md +++ /dev/null @@ -1,77 +0,0 @@ -fruitboom -=========== - - - - - -Een boom - -## Table of contents - -1. [fruitboom](#fruitboom) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [fruitboom-species:nl](#fruitboom-speciesnl) - + [fruitboom-taxon](#fruitboom-taxon) - + [fruitboom-description](#fruitboom-description) - + [fruitboom-ref](#fruitboom-ref) - -[Go to the source code](../assets/layers/fruitboom/fruitboom.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- natural - =tree - -Supported attributes ----------------------- - - - -**Warning** This quick overview is incomplete - -attribute | type | values which are supported by this layer ------------ | ------ | ------------------------------------------ -[](https://taginfo.openstreetmap.org/keys/species:nl#values) [species:nl](https://wiki.openstreetmap.org/wiki/Key:species:nl) | [string](../SpecialInputElements.md#string) | -[](https://taginfo.openstreetmap.org/keys/taxon#values) [taxon](https://wiki.openstreetmap.org/wiki/Key:taxon) | [string](../SpecialInputElements.md#string) | -[](https://taginfo.openstreetmap.org/keys/description#values) [description](https://wiki.openstreetmap.org/wiki/Key:description) | [string](../SpecialInputElements.md#string) | -[](https://taginfo.openstreetmap.org/keys/ref#values) [ref](https://wiki.openstreetmap.org/wiki/Key:ref) | [string](../SpecialInputElements.md#string) | - -### fruitboom-species:nl - -The question is **Wat is de soort van deze boom (in het Nederlands)?** - -This rendering asks information about the property [species:nl](https://wiki.openstreetmap.org/wiki/Key:species:nl) -This is rendered with `De soort is {species:nl}` - -### fruitboom-taxon - -The question is **Wat is het taxon (ras) van deze boom?** - -This rendering asks information about the property [taxon](https://wiki.openstreetmap.org/wiki/Key:taxon) -This is rendered with `Het ras (taxon) van deze boom is {taxon}` - -### fruitboom-description - -The question is **Welke beschrijving past bij deze boom?** - -This rendering asks information about the property [description](https://wiki.openstreetmap.org/wiki/Key:description) -This is rendered with `Beschrijving: {description}` - -### fruitboom-ref - -The question is **Is er een refernetienummer?** - -This rendering asks information about the property [ref](https://wiki.openstreetmap.org/wiki/Key:ref) -This is rendered with `Referentienummer: {ref}` - -This document is autogenerated from assets/layers/fruitboom/fruitboom.json \ No newline at end of file diff --git a/Docs/Layers/generic_osm_object.md b/Docs/Layers/generic_osm_object.md deleted file mode 100644 index eccc852941..0000000000 --- a/Docs/Layers/generic_osm_object.md +++ /dev/null @@ -1,45 +0,0 @@ -generic_osm_object -==================== - -## Table of contents - -1. [generic_osm_object](#generic_osm_object) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [all_tags](#all_tags) - - -- Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` -- This layer is needed as dependency for layer [grb](#grb) - -[Go to the source code](../assets/layers/generic_osm_object/generic_osm_object.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- id~^..*$ -- -- -- -- type!~^boundary$ -- -- |level - =0 -- layer - =0| - -Supported attributes ----------------------- - -### all_tags - -_This tagrendering has no question and is thus read-only_ - -This document is autogenerated from assets/layers/generic_osm_object/generic_osm_object.json \ No newline at end of file diff --git a/Docs/Layers/ghost_bike.md b/Docs/Layers/ghost_bike.md index 0788cb4cb1..6cfaffb53a 100644 --- a/Docs/Layers/ghost_bike.md +++ b/Docs/Layers/ghost_bike.md @@ -12,24 +12,9 @@ A layer showing memorials for cyclists, killed in road accidents -## Table of contents - -1. [ghost_bike](#ghost_bike) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [ghost-bike-explanation](#ghost-bike-explanation) - + [images](#images) - + [ghost_bike-name](#ghost_bike-name) - + [ghost_bike-source](#ghost_bike-source) - + [ghost_bike-inscription](#ghost_bike-inscription) - + [ghost_bike-start_date](#ghost_bike-start_date) - - - - + - This layer is shown at zoomlevel **0** and higher @@ -44,8 +29,6 @@ A layer showing memorials for cyclists, killed in road accidents - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/ghost_bike/ghost_bike.json) - Basic tags for this layer diff --git a/Docs/Layers/gps_location.md b/Docs/Layers/gps_location.md deleted file mode 100644 index 2e196b1b84..0000000000 --- a/Docs/Layers/gps_location.md +++ /dev/null @@ -1,44 +0,0 @@ -gps_location -============== - - - - - -Meta layer showing the current location of the user. Add this to your theme and override the icon to change the -appearance of the current location. The object will always have `id=gps` and will have _all_ the properties included in -the [`Coordinates`-object](https://developer.mozilla.org/en-US/docs/Web/API/GeolocationCoordinates) returned by the -browser. - -## Table of contents - -1. [gps_location](#gps_location) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - - -- This layer cannot be toggled in the filter view. If you import this layer in your theme, override `title` to make this - toggleable. -- Not visible in the layer selection by default. If you want to make this layer toggable, override `name` - -[Go to the source code](../assets/layers/gps_location/gps_location.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- id - =gps - -Supported attributes ----------------------- - - - -This document is autogenerated from assets/layers/gps_location/gps_location.json \ No newline at end of file diff --git a/Docs/Layers/gps_location_history.md b/Docs/Layers/gps_location_history.md deleted file mode 100644 index cdfe7f6103..0000000000 --- a/Docs/Layers/gps_location_history.md +++ /dev/null @@ -1,43 +0,0 @@ -gps_location_history -====================== - - - - - -Meta layer which contains the previous locations of the user as single points. This is mainly for technical reasons, -e.g. to keep match the distance to the modified object - -## Table of contents - -1. [gps_location_history](#gps_location_history) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - - -- This layer cannot be toggled in the filter view. If you import this layer in your theme, override `title` to make this - toggleable. -- Not visible in the layer selection by default. If you want to make this layer toggable, override `name` -- Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` - -[Go to the source code](../assets/layers/gps_location_history/gps_location_history.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- user:location - =yes - -Supported attributes ----------------------- - - - -This document is autogenerated from assets/layers/gps_location_history/gps_location_history.json \ No newline at end of file diff --git a/Docs/Layers/gps_track.md b/Docs/Layers/gps_track.md deleted file mode 100644 index d10ccff474..0000000000 --- a/Docs/Layers/gps_track.md +++ /dev/null @@ -1,59 +0,0 @@ -gps_track -=========== - - - - - -Meta layer showing the previous locations of the user as single line. Add this to your theme and override the icon to -change the appearance of the current location. - -## Table of contents - -1. [gps_track](#gps_track) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [Privacy notice](#privacy-notice) - + [export_as_gpx](#export_as_gpx) - + [minimap](#minimap) - + [delete](#delete) - - -- This layer is not visible by default and must be enabled in the filter by the user. -- Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` - -[Go to the source code](../assets/layers/gps_track/gps_track.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- id - =location_track - -Supported attributes ----------------------- - -### Privacy notice - -_This tagrendering has no question and is thus read-only_ - -### export_as_gpx - -_This tagrendering has no question and is thus read-only_ - -### minimap - -_This tagrendering has no question and is thus read-only_ - -### delete - -_This tagrendering has no question and is thus read-only_ - -This document is autogenerated from assets/layers/gps_track/gps_track.json \ No newline at end of file diff --git a/Docs/Layers/grass_in_parks.md b/Docs/Layers/grass_in_parks.md index a73c659d20..c974348487 100644 --- a/Docs/Layers/grass_in_parks.md +++ b/Docs/Layers/grass_in_parks.md @@ -12,21 +12,9 @@ Searches for all accessible grass patches within public parks - these are 'groen -## Table of contents - -1. [grass_in_parks](#grass_in_parks) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [explanation](#explanation) - + [grass-in-parks-reviews](#grass-in-parks-reviews) - - - - + - This layer is shown at zoomlevel **0** and higher @@ -40,8 +28,6 @@ Searches for all accessible grass patches within public parks - these are 'groen - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/grass_in_parks/grass_in_parks.json) - Basic tags for this layer diff --git a/Docs/Layers/grb.md b/Docs/Layers/grb.md deleted file mode 100644 index 6e339fdf10..0000000000 --- a/Docs/Layers/grb.md +++ /dev/null @@ -1,98 +0,0 @@ -grb -===== - - - - - -Geometry which comes from GRB with tools to import them - -## Table of contents - -1. [grb](#grb) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [Import-button](#import-button) - + [Building info](#building-info) - + [overlapping building address](#overlapping-building-address) - + [grb_address_diff](#grb_address_diff) - + [overlapping building type](#overlapping-building-type) - + [apply-id](#apply-id) - + [apply-building-type](#apply-building-type) - - -- This layer is loaded from an external source, namely `https://betadata.grbosm.site/grb?bbox={x_min},{y_min},{x_max},{y_max}` -- This layer will automatically load [osm-buildings](./osm-buildings.md) into the layout as it depends on it: a - tagrendering needs this layer (Import-button) -- This layer will automatically load [type_node](./type_node.md) into the layout as it depends on it: a tagrendering - needs this layer (Import-button) -- This layer will automatically load [osm-buildings](./osm-buildings.md) into the layout as it depends on it: A - calculated tag loads features from this layer (calculatedTag[0] which calculates the value for _ - overlaps_with_buildings) -- This layer will automatically load [generic_osm_object](./generic_osm_object.md) into the layout as it depends on - it: A calculated tag loads features from this layer (calculatedTag[18] which calculates the value for _ - intersects_with_other_features) - -[Go to the source code](../assets/layers/grb/grb.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- HUISNR~^..*$ -- man_made!~^mast$ - -Supported attributes ----------------------- - -### Import-button - -_This tagrendering has no question and is thus read-only_ - -- **{conflate_button(osm-buildings,building=$_target_building_type; source:geometry:date=$_grb_date; source:geometry: - ref=$_grb_ref; addr:street=$addr:street; addr:housenumber=$addr:housenumber, Replace the geometry in OpenStreetMap and - add the address,,_osm_obj:id)}** corresponds with _overlap_percentage>50&_reverse_overlap_percentage>50&_ - overlaps_with!~^$&addr:street~^..*$&addr:housenumber~^..*$&addr:street!=&addr:housenumber!= -- **{conflate_button(osm-buildings,building=$_target_building_type; source:geometry:date=$_grb_date; source:geometry: - ref=$_grb_ref, Replace the geometry in OpenStreetMap,,_osm_obj:id)}** corresponds with _overlap_percentage>50&_ - reverse_overlap_percentage>50&_overlaps_with!~^$ - -### Building info - -_This tagrendering has no question and is thus read-only_ - -### overlapping building address - -_This tagrendering has no question and is thus read-only_ - -- **The overlapping openstreetmap-building has address {_osm_obj:addr:street} {_osm_obj:addr:housenumber}** corresponds - with _osm_obj:addr:street~^..*$&_osm_obj:addr:housenumber~^..*$ -- **The overlapping building only has a street known: {_osm_obj:addr:street}** corresponds with _osm_obj:addr:street~ - ^..*$ -- **The overlapping building only has a housenumber known: {_osm_obj:addr:housenumber}** corresponds with _osm_obj:addr: - housenumber~^..*$ -- **No overlapping OpenStreetMap-building found** corresponds with - -### grb_address_diff - -_This tagrendering has no question and is thus read-only_ - -### overlapping building type - -_This tagrendering has no question and is thus read-only_ - -### apply-id - -_This tagrendering has no question and is thus read-only_ - -### apply-building-type - -_This tagrendering has no question and is thus read-only_ - -This document is autogenerated from assets/layers/grb/grb.json \ No newline at end of file diff --git a/Docs/Layers/hackerspaces.md b/Docs/Layers/hackerspaces.md index cfc1dd152d..3c0e8953dd 100644 --- a/Docs/Layers/hackerspaces.md +++ b/Docs/Layers/hackerspaces.md @@ -1,4 +1,6 @@ -hackerspaces + + + hackerspaces ============== @@ -7,150 +9,219 @@ hackerspaces Hackerspace -## Table of contents - -1. [hackerspaces](#hackerspaces) - * [Themes using this layer](#themes-using-this-layer) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [is_makerspace](#is_makerspace) - + [hackerspaces-name](#hackerspaces-name) - + [website](#website) - + [email](#email) - + [phone](#phone) - + [hackerspaces-opening_hours](#hackerspaces-opening_hours) - + [wheelchair-access](#wheelchair-access) - + [hs-club-mate](#hs-club-mate) - + [hackerspaces-start_date](#hackerspaces-start_date) - -#### Themes using this layer - -- [hackerspaces](https://mapcomplete.osm.be/hackerspaces) - -[Go to the source code](../assets/layers/hackerspaces/hackerspaces.json) -Basic tags for this layer + + + - This layer is shown at zoomlevel **8** and higher + + + + +#### Themes using this layer + + + + + + - [hackerspaces](https://mapcomplete.osm.be/hackerspaces) + + + + + Basic tags for this layer --------------------------- Elements must have the all of following tags to be shown on this layer: -- leisure - =hackerspace -Supported attributes + + - leisure=hackerspace + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22leisure%22%3D%22hackerspace%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes ---------------------- **Warning** This quick overview is incomplete + + attribute | type | values which are supported by this layer ----------- | ------ | ------------------------------------------ [](https://taginfo.openstreetmap.org/keys/hackerspace#values) [hackerspace](https://wiki.openstreetmap.org/wiki/Key:hackerspace) | Multiple choice | [makerspace](https://wiki.openstreetmap.org/wiki/Tag:hackerspace%3Dmakerspace) [](https://wiki.openstreetmap.org/wiki/Tag:hackerspace%3D) -[](https://taginfo.openstreetmap.org/keys/name#values) [name](https://wiki.openstreetmap.org/wiki/Key:name) | [string](../SpecialInputElements.md#string) | -[](https://taginfo.openstreetmap.org/keys/website#values) [website](https://wiki.openstreetmap.org/wiki/Key:website) | [url](../SpecialInputElements.md#url) | -[](https://taginfo.openstreetmap.org/keys/email#values) [email](https://wiki.openstreetmap.org/wiki/Key:email) | [email](../SpecialInputElements.md#email) | -[](https://taginfo.openstreetmap.org/keys/phone#values) [phone](https://wiki.openstreetmap.org/wiki/Key:phone) | [phone](../SpecialInputElements.md#phone) | +[](https://taginfo.openstreetmap.org/keys/name#values) [name](https://wiki.openstreetmap.org/wiki/Key:name) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/website#values) [website](https://wiki.openstreetmap.org/wiki/Key:website) | [url](../SpecialInputElements.md#url) | +[](https://taginfo.openstreetmap.org/keys/email#values) [email](https://wiki.openstreetmap.org/wiki/Key:email) | [email](../SpecialInputElements.md#email) | +[](https://taginfo.openstreetmap.org/keys/phone#values) [phone](https://wiki.openstreetmap.org/wiki/Key:phone) | [phone](../SpecialInputElements.md#phone) | [](https://taginfo.openstreetmap.org/keys/opening_hours#values) [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) | [opening_hours](../SpecialInputElements.md#opening_hours) | [24/7](https://wiki.openstreetmap.org/wiki/Tag:opening_hours%3D24/7) [](https://taginfo.openstreetmap.org/keys/wheelchair#values) [wheelchair](https://wiki.openstreetmap.org/wiki/Key:wheelchair) | Multiple choice | [designated](https://wiki.openstreetmap.org/wiki/Tag:wheelchair%3Ddesignated) [yes](https://wiki.openstreetmap.org/wiki/Tag:wheelchair%3Dyes) [limited](https://wiki.openstreetmap.org/wiki/Tag:wheelchair%3Dlimited) [no](https://wiki.openstreetmap.org/wiki/Tag:wheelchair%3Dno) [](https://taginfo.openstreetmap.org/keys/drink:club-mate#values) [drink:club-mate](https://wiki.openstreetmap.org/wiki/Key:drink:club-mate) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:drink:club-mate%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:drink:club-mate%3Dno) -[](https://taginfo.openstreetmap.org/keys/start_date#values) [start_date](https://wiki.openstreetmap.org/wiki/Key:start_date) | [date](../SpecialInputElements.md#date) | +[](https://taginfo.openstreetmap.org/keys/start_date#values) [start_date](https://wiki.openstreetmap.org/wiki/Key:start_date) | [date](../SpecialInputElements.md#date) | + + + + +### is_makerspace + -### is_makerspace The question is **Is this a hackerspace or a makerspace?** -- **This is a makerspace** corresponds - with hackerspace - =makerspace -- **This is a traditional (software oriented) hackerspace** corresponds with -### hackerspaces-name + + + + - **This is a makerspace** corresponds with hackerspace=makerspace + - **This is a traditional (software oriented) hackerspace** corresponds with + + + + +### hackerspaces-name + + The question is **What is the name of this hackerspace?** -This rendering asks information about the property [name](https://wiki.openstreetmap.org/wiki/Key:name) +This rendering asks information about the property [name](https://wiki.openstreetmap.org/wiki/Key:name) This is rendered with `This hackerspace is named {name}` -### website -The question is **What is the website of {name}?** -This rendering asks information about the property [website](https://wiki.openstreetmap.org/wiki/Key:website) +### website + + + +The question is **What is the website of {title()}?** + +This rendering asks information about the property [website](https://wiki.openstreetmap.org/wiki/Key:website) This is rendered with `{website}` -- **{contact:website}** corresponds with contact:website~^..*$_This - option cannot be chosen as answer_ -### email -The question is **What is the email address of {name}?** + - **{contact:website}** corresponds with contact:website~^..*$_This option cannot be chosen as answer_ -This rendering asks information about the property [email](https://wiki.openstreetmap.org/wiki/Key:email) + + + +### email + + + +The question is **What is the email address of {title()}?** + +This rendering asks information about the property [email](https://wiki.openstreetmap.org/wiki/Key:email) This is rendered with `{email}` -- **{contact:email}** corresponds with contact:email~^..*$_This - option cannot be chosen as answer_ -### phone -The question is **What is the phone number of {name}?** + - **{contact:email}** corresponds with contact:email~^..*$_This option cannot be chosen as answer_ -This rendering asks information about the property [phone](https://wiki.openstreetmap.org/wiki/Key:phone) + + + +### phone + + + +The question is **What is the phone number of {title()}?** + +This rendering asks information about the property [phone](https://wiki.openstreetmap.org/wiki/Key:phone) This is rendered with `{phone}` -- **{contact:phone}** corresponds with contact:phone~^..*$_This option cannot be - chosen as answer_ -### hackerspaces-opening_hours + + - **{contact:phone}** corresponds with contact:phone~^..*$_This option cannot be chosen as answer_ + + + + +### hackerspaces-opening_hours + + The question is **When is this hackerspace opened?** -This rendering asks information about the -property [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) +This rendering asks information about the property [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) This is rendered with `{opening_hours_table()}` -- **Opened 24/7** corresponds with - opening_hours=24/7 -### wheelchair-access + + - **Opened 24/7** corresponds with opening_hours=24/7 + + + + +### wheelchair-access + + The question is **Is this place accessible with a wheelchair?** -- **This place is specially adapted for wheelchair users** corresponds - with wheelchair - =designated -- **This place is easily reachable with a wheelchair** corresponds - with wheelchair - =yes -- **It is possible to reach this place in a wheelchair, but it is not easy** corresponds - with wheelchair - =limited -- **This place is not reachable with a wheelchair** corresponds - with wheelchair - =no -### hs-club-mate + + + + - **This place is specially adapted for wheelchair users** corresponds with wheelchair=designated + - **This place is easily reachable with a wheelchair** corresponds with wheelchair=yes + - **It is possible to reach this place in a wheelchair, but it is not easy** corresponds with wheelchair=limited + - **This place is not reachable with a wheelchair** corresponds with wheelchair=no + + + + +### hs-club-mate + + The question is **Does this hackerspace serve Club Mate?** -- **This hackerspace serves club mate** corresponds - with drink:club-mate - =yes -- **This hackerspace does not serve club mate** corresponds - with drink:club-mate - =no -### hackerspaces-start_date + + + + - **This hackerspace serves club mate** corresponds with drink:club-mate=yes + - **This hackerspace does not serve club mate** corresponds with drink:club-mate=no + + + + +### hackerspaces-start_date + + The question is **When was this hackerspace founded?** -This rendering asks information about the property [start_date](https://wiki.openstreetmap.org/wiki/Key:start_date) +This rendering asks information about the property [start_date](https://wiki.openstreetmap.org/wiki/Key:start_date) This is rendered with `This hackerspace was founded at {start_date}` -This document is autogenerated from assets/layers/hackerspaces/hackerspaces.json \ No newline at end of file + + +### questions + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### minimap + + + +_This tagrendering has no question and is thus read-only_ + + + +This document is autogenerated from [assets/themes/hackerspaces/hackerspaces.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/hackerspaces/hackerspaces.json) \ No newline at end of file diff --git a/Docs/Layers/health_and_social_places_without_etymology.md b/Docs/Layers/health_and_social_places_without_etymology.md new file mode 100644 index 0000000000..0fba7b0537 --- /dev/null +++ b/Docs/Layers/health_and_social_places_without_etymology.md @@ -0,0 +1,162 @@ + + + health_and_social_places_without_etymology +============================================ + + + + + +All objects which have an etymology known + + + + + + + - This layer is shown at zoomlevel **18** and higher + + + + +#### Themes using this layer + + + + + + - [etymology](https://mapcomplete.osm.be/etymology) + + + + + Basic tags for this layer +--------------------------- + + + +Elements must have the all of following tags to be shown on this layer: + + + + - name~^..*$ + - amenity=clinic|amenity=hospital|amenity=social_facility + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22amenity%22%3D%22clinic%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22amenity%22%3D%22hospital%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22amenity%22%3D%22social_facility%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes +---------------------- + + + +**Warning** This quick overview is incomplete + + + +attribute | type | values which are supported by this layer +----------- | ------ | ------------------------------------------ +[](https://taginfo.openstreetmap.org/keys/name:etymology:wikidata#values) [name:etymology:wikidata](https://wiki.openstreetmap.org/wiki/Key:name:etymology:wikidata) | [wikidata](../SpecialInputElements.md#wikidata) | +[](https://taginfo.openstreetmap.org/keys/name:etymology#values) [name:etymology](https://wiki.openstreetmap.org/wiki/Key:name:etymology) | [string](../SpecialInputElements.md#string) | [unknown](https://wiki.openstreetmap.org/wiki/Tag:name:etymology%3Dunknown) + + + + +### etymology-images-from-wikipedia + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### wikipedia-etymology + + + +The question is **What is the Wikidata-item that this object is named after?** + +This rendering asks information about the property [name:etymology:wikidata](https://wiki.openstreetmap.org/wiki/Key:name:etymology:wikidata) +This is rendered with `

Wikipedia article of the name giver

{wikipedia(name:etymology:wikidata):max-height:20rem}` + + + +### zoeken op inventaris onroerend erfgoed + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### simple etymology + + + +The question is **What is this object named after?
This might be written on the street name sign** + +This rendering asks information about the property [name:etymology](https://wiki.openstreetmap.org/wiki/Key:name:etymology) +This is rendered with `Named after {name:etymology}` + + + + - **The origin of this name is unknown in all literature** corresponds with name:etymology=unknown + + + + +### questions + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### street-name-sign-image + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### minimap + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### etymology_multi_apply + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### wikipedia + + + +_This tagrendering has no question and is thus read-only_ + + + +This document is autogenerated from [assets/themes/etymology/etymology.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/etymology/etymology.json) \ No newline at end of file diff --git a/Docs/Layers/home_location.md b/Docs/Layers/home_location.md deleted file mode 100644 index c8b3734a2b..0000000000 --- a/Docs/Layers/home_location.md +++ /dev/null @@ -1,42 +0,0 @@ -home_location -=============== - - - - - -Meta layer showing the home location of the user. The home location can be set in -the [profile settings](https://www.openstreetmap.org/profile/edit) of OpenStreetMap. - -## Table of contents - -1. [home_location](#home_location) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - - -- This layer cannot be toggled in the filter view. If you import this layer in your theme, override `title` to make this - toggleable. -- Not visible in the layer selection by default. If you want to make this layer toggable, override `name` - -[Go to the source code](../assets/layers/home_location/home_location.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- user:home - =yes - -Supported attributes ----------------------- - - - -This document is autogenerated from assets/layers/home_location/home_location.json \ No newline at end of file diff --git a/Docs/Layers/hydrant.md b/Docs/Layers/hydrant.md index e9c7eb2a66..afa91e07b6 100644 --- a/Docs/Layers/hydrant.md +++ b/Docs/Layers/hydrant.md @@ -12,22 +12,9 @@ Map layer to show fire hydrants. -## Table of contents - -1. [hydrant](#hydrant) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [hydrant-color](#hydrant-color) - + [hydrant-type](#hydrant-type) - + [hydrant-state](#hydrant-state) - + [images](#images) - - - - + - This layer is shown at zoomlevel **14** and higher @@ -42,8 +29,6 @@ Map layer to show fire hydrants. - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/hydrant/hydrant.json) - Basic tags for this layer diff --git a/Docs/Layers/information_board.md b/Docs/Layers/information_board.md index 8de2ba32ea..6c29b93378 100644 --- a/Docs/Layers/information_board.md +++ b/Docs/Layers/information_board.md @@ -12,19 +12,9 @@ A layer showing touristical, road side information boards (e.g. giving informati -## Table of contents - -1. [information_board](#information_board) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - - - - + - This layer is shown at zoomlevel **12** and higher @@ -39,8 +29,6 @@ A layer showing touristical, road side information boards (e.g. giving informati - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/information_board/information_board.json) - Basic tags for this layer diff --git a/Docs/Layers/left_right_style.md b/Docs/Layers/left_right_style.md deleted file mode 100644 index 471b5c9f65..0000000000 --- a/Docs/Layers/left_right_style.md +++ /dev/null @@ -1,45 +0,0 @@ -left_right_style -================== - - - - - -Special meta-style which will show one single line, either on the left or on the right depending on the id. This is used -in the small popups with left_right roads. Cannot be included in a theme - -## Table of contents - -1. [left_right_style](#left_right_style) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - - -- This layer cannot be toggled in the filter view. If you import this layer in your theme, override `title` to make this - toggleable. -- Not visible in the layer selection by default. If you want to make this layer toggable, override `name` -- Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` - -[Go to the source code](../assets/layers/left_right_style/left_right_style.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- id - =left - |id - =right - -Supported attributes ----------------------- - - - -This document is autogenerated from assets/layers/left_right_style/left_right_style.json \ No newline at end of file diff --git a/Docs/Layers/lit_streets.md b/Docs/Layers/lit_streets.md index 158f4e997d..6568031604 100644 --- a/Docs/Layers/lit_streets.md +++ b/Docs/Layers/lit_streets.md @@ -1,62 +1,103 @@ -lit_streets + + + lit_streets ============= -## Table of contents - -1. [lit_streets](#lit_streets) - * [Themes using this layer](#themes-using-this-layer) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [lit](#lit) - - -- Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` - -#### Themes using this layer - -- [street_lighting](https://mapcomplete.osm.be/street_lighting) - -[Go to the source code](../assets/layers/lit_streets/lit_streets.json) -Basic tags for this layer + + + + + + + - This layer is shown at zoomlevel **0** and higher + - Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` + + + + +#### Themes using this layer + + + + + + - [street_lighting](https://mapcomplete.osm.be/street_lighting) + + + + + Basic tags for this layer --------------------------- Elements must have the all of following tags to be shown on this layer: -- highway!~^$ -- lit!~^no$ -- lit!~^$ -- service!~^driveway$ -Supported attributes + + - highway~^..*$ + - lit!~^no$ + - lit~^..*$ + - service!~^driveway$ + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22highway%22%5D%5B%22lit%22!~%22%5Eno%24%22%5D%5B%22lit%22%5D%5B%22service%22!~%22%5Edriveway%24%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes ---------------------- **Warning** This quick overview is incomplete + + attribute | type | values which are supported by this layer ----------- | ------ | ------------------------------------------ [](https://taginfo.openstreetmap.org/keys/lit#values) [lit](https://wiki.openstreetmap.org/wiki/Key:lit) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:lit%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:lit%3Dno) [24/7](https://wiki.openstreetmap.org/wiki/Tag:lit%3D24/7) -### lit + + + +### lit + + The question is **Is this street lit?** -- **This street is lit** corresponds with lit - =yes -- **This street is not lit** corresponds with - lit=no -- **This street is lit at night** corresponds - with lit - =sunset-sunrise_This option - cannot be chosen as answer_ -- **This street is lit 24/7** corresponds with - lit=24/7 -This document is autogenerated from assets/layers/lit_streets/lit_streets.json \ No newline at end of file + + + + - **This street is lit** corresponds with lit=yes + - **This street is not lit** corresponds with lit=no + - **This street is lit at night** corresponds with lit=sunset-sunrise_This option cannot be chosen as answer_ + - **This street is lit 24/7** corresponds with lit=24/7 + + + + +### questions + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### minimap + + + +_This tagrendering has no question and is thus read-only_ + + + +This document is autogenerated from [assets/themes/street_lighting/street_lighting.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/street_lighting/street_lighting.json) \ No newline at end of file diff --git a/Docs/Layers/map.md b/Docs/Layers/map.md index c75905e74c..d7d7ad33f2 100644 --- a/Docs/Layers/map.md +++ b/Docs/Layers/map.md @@ -12,21 +12,9 @@ A map, meant for tourists which is permanently installed in the public space -## Table of contents - -1. [map](#map) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [map-map_source](#map-map_source) - + [map-attribution](#map-attribution) - - - - + - This layer is shown at zoomlevel **12** and higher @@ -42,8 +30,6 @@ A map, meant for tourists which is permanently installed in the public space - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/map/map.json) - Basic tags for this layer diff --git a/Docs/Layers/matchpoint.md b/Docs/Layers/matchpoint.md deleted file mode 100644 index 5fd22c6ca5..0000000000 --- a/Docs/Layers/matchpoint.md +++ /dev/null @@ -1,45 +0,0 @@ -matchpoint -============ - - - - - -The default rendering for a locationInput which snaps onto another object - -## Table of contents - -1. [matchpoint](#matchpoint) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - - -- This layer cannot be toggled in the filter view. If you import this layer in your theme, override `title` to make this - toggleable. -- Not visible in the layer selection by default. If you want to make this layer toggable, override `name` - -[Go to the source code](../assets/layers/matchpoint/matchpoint.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - - - - - - - - -Supported attributes ----------------------- - - - -This document is autogenerated from assets/layers/matchpoint/matchpoint.json \ No newline at end of file diff --git a/Docs/Layers/maybe_climbing.md b/Docs/Layers/maybe_climbing.md index f3940462bc..c73eba560c 100644 --- a/Docs/Layers/maybe_climbing.md +++ b/Docs/Layers/maybe_climbing.md @@ -1,4 +1,6 @@ -maybe_climbing + + + maybe_climbing ================ @@ -7,67 +9,284 @@ maybe_climbing A climbing opportunity? -## Table of contents - -1. [maybe_climbing](#maybe_climbing) - * [Themes using this layer](#themes-using-this-layer) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [minimap](#minimap) - + [climbing-opportunity-name](#climbing-opportunity-name) - + [climbing-possible](#climbing-possible) - -#### Themes using this layer - -- [climbing](https://mapcomplete.osm.be/climbing) - -[Go to the source code](../assets/layers/maybe_climbing/maybe_climbing.json) -Basic tags for this layer + + + - This layer is shown at zoomlevel **19** and higher + - This layer will automatically load [climbing](./climbing.md) into the layout as it depends on it: A calculated tag loads features from this layer (calculatedTag[0] which calculates the value for _embedding_feature_properties) + + + + +#### Themes using this layer + + + + + + - [climbing](https://mapcomplete.osm.be/climbing) + + + + + Basic tags for this layer --------------------------- Elements must have the all of following tags to be shown on this layer: -- leisure - =sports_centre - |barrier - =wall - |barrier - =retaining_wall - |natural - =cliff - |natural - =rock - |natural - =stone -- -Supported attributes + + - leisure=sports_centre|barrier=wall|barrier=retaining_wall|natural=cliff|natural=rock|natural=stone + - + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B!%22climbing%22%5D%5B%22barrier%22%3D%22wall%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B!%22climbing%22%5D%5B%22barrier%22%3D%22retaining_wall%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B!%22climbing%22%5D%5B%22leisure%22%3D%22sports_centre%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B!%22climbing%22%5D%5B%22natural%22%3D%22cliff%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B!%22climbing%22%5D%5B%22natural%22%3D%22rock%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B!%22climbing%22%5D%5B%22natural%22%3D%22stone%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes ---------------------- -### minimap + + +**Warning** This quick overview is incomplete + + + +attribute | type | values which are supported by this layer +----------- | ------ | ------------------------------------------ +[](https://taginfo.openstreetmap.org/keys/url#values) [url](https://wiki.openstreetmap.org/wiki/Key:url) | [url](../SpecialInputElements.md#url) | +[](https://taginfo.openstreetmap.org/keys/_embedding_feature:access#values) [_embedding_feature:access](https://wiki.openstreetmap.org/wiki/Key:_embedding_feature:access) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dyes) [permit](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dpermit) [customers](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dcustomers) [members](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dmembers) [no](https://wiki.openstreetmap.org/wiki/Tag:_embedding_feature:access%3Dno) +[](https://taginfo.openstreetmap.org/keys/access#values) [access](https://wiki.openstreetmap.org/wiki/Key:access) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:access%3Dyes) [permit](https://wiki.openstreetmap.org/wiki/Tag:access%3Dpermit) [customers](https://wiki.openstreetmap.org/wiki/Tag:access%3Dcustomers) [members](https://wiki.openstreetmap.org/wiki/Tag:access%3Dmembers) [no](https://wiki.openstreetmap.org/wiki/Tag:access%3Dno) +[](https://taginfo.openstreetmap.org/keys/access:description#values) [access:description](https://wiki.openstreetmap.org/wiki/Key:access:description) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/climbing:length#values) [climbing:length](https://wiki.openstreetmap.org/wiki/Key:climbing:length) | [pnat](../SpecialInputElements.md#pnat) | +[](https://taginfo.openstreetmap.org/keys/climbing:grade:french:min#values) [climbing:grade:french:min](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:min) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/climbing:grade:french:max#values) [climbing:grade:french:max](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:max) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/climbing:boulder#values) [climbing:boulder](https://wiki.openstreetmap.org/wiki/Key:climbing:boulder) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:boulder%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:boulder%3Dno) [limited](https://wiki.openstreetmap.org/wiki/Tag:climbing:boulder%3Dlimited) +[](https://taginfo.openstreetmap.org/keys/climbing:toprope#values) [climbing:toprope](https://wiki.openstreetmap.org/wiki/Key:climbing:toprope) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:toprope%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:toprope%3Dno) +[](https://taginfo.openstreetmap.org/keys/climbing:sport#values) [climbing:sport](https://wiki.openstreetmap.org/wiki/Key:climbing:sport) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:sport%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:sport%3Dno) +[](https://taginfo.openstreetmap.org/keys/climbing:traditional#values) [climbing:traditional](https://wiki.openstreetmap.org/wiki/Key:climbing:traditional) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:traditional%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:traditional%3Dno) +[](https://taginfo.openstreetmap.org/keys/climbing:speed#values) [climbing:speed](https://wiki.openstreetmap.org/wiki/Key:climbing:speed) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:climbing:speed%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:climbing:speed%3Dno) + + + + +### minimap + + _This tagrendering has no question and is thus read-only_ -### climbing-opportunity-name + + + + +### climbing-opportunity-name + + _This tagrendering has no question and is thus read-only_ -### climbing-possible + + + + +### climbing-possible + + The question is **Is climbing possible here?** -- **Climbing is not possible here** corresponds with sport!~^climbing$_This option cannot be chosen as answer_ -- **Climbing is possible here** corresponds - with sport - =climbing -- **Climbing is not possible here** corresponds - with climbing - =no -This document is autogenerated from assets/layers/maybe_climbing/maybe_climbing.json \ No newline at end of file + + + + - **Climbing is possible here** corresponds with sport=climbing + - **Climbing is not possible here** corresponds with climbing=no + - **Climbing is not possible here** corresponds with sport!~^climbing$_This option cannot be chosen as answer_ + + + + +### Website + + + +The question is **Is there a (unofficial) website with more informations (e.g. topos)?** + +This rendering asks information about the property [url](https://wiki.openstreetmap.org/wiki/Key:url) +This is rendered with `{url}` + + + +### Access from containing feature + + + +_This tagrendering has no question and is thus read-only_ + + + + + + - **The containing feature states that this is publicly accessible
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=yes + - **The containing feature states that a permit is needed to access
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=permit + - **The containing feature states that this is only accessible to customers
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=customers + - **The containing feature states that this is only accessible to club members
{_embedding_feature:access:description}** corresponds with _embedding_feature:access=members + - **Not accessible as stated by the containing feature** corresponds with _embedding_feature:access=no + + + + +### Access + + + +The question is **Who can access here?** + + + + + + - **Publicly accessible to anyone** corresponds with access=yes + - **You need a permit to access here** corresponds with access=permit + - **Only customers** corresponds with access=customers + - **Only club members** corresponds with access=members + - **Not accessible** corresponds with access=no + + + + +### Access description (without _embedding_feature:access:description) + + + +_This tagrendering has no question and is thus read-only_ + +This rendering asks information about the property [access:description](https://wiki.openstreetmap.org/wiki/Key:access:description) +This is rendered with `{access:description}` + + + +### Avg length? + + + +The question is **What is the (average) length of the routes in meters?** + +This rendering asks information about the property [climbing:length](https://wiki.openstreetmap.org/wiki/Key:climbing:length) +This is rendered with `The routes are {canonical(climbing:length)} long on average` + + + +### Difficulty-min + + + +The question is **What is the grade of the easiest route here, according to the french classification system?** + +This rendering asks information about the property [climbing:grade:french:min](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:min) +This is rendered with `The lowest grade is {climbing:grade:french:min} according to the french/belgian system` + + + +### Difficulty-max + + + +The question is **What is the highest grade route here, according to the french classification system?** + +This rendering asks information about the property [climbing:grade:french:max](https://wiki.openstreetmap.org/wiki/Key:climbing:grade:french:max) +This is rendered with `The highest grade is {climbing:grade:french:max} according to the french/belgian system` + + + +### Boldering? + + + +The question is **Is bouldering possible here?** + + + + + + - **Bouldering is possible here** corresponds with climbing:boulder=yes + - **Bouldering is not possible here** corresponds with climbing:boulder=no + - **Bouldering is possible, allthough there are only a few routes** corresponds with climbing:boulder=limited + - **There are {climbing:boulder} boulder routes** corresponds with climbing:boulder~^..*$_This option cannot be chosen as answer_ + + + + +### Toproping? + + + +The question is **Is toprope climbing possible here?** + + + + + + - **Toprope climbing is possible here** corresponds with climbing:toprope=yes + - **Toprope climbing is not possible here** corresponds with climbing:toprope=no + - **There are {climbing:toprope} toprope routes** corresponds with climbing:toprope~^..*$_This option cannot be chosen as answer_ + + + + +### Sportclimbing? + + + +The question is **Is sport climbing possible here on fixed anchors?** + + + + + + - **Sport climbing is possible here** corresponds with climbing:sport=yes + - **Sport climbing is not possible here** corresponds with climbing:sport=no + - **There are {climbing:sport} sport climbing routes** corresponds with climbing:sport~^..*$_This option cannot be chosen as answer_ + + + + +### Traditional climbing? + + + +The question is **Is traditional climbing possible here (using own gear e.g. chocks)?** + + + + + + - **Traditional climbing is possible here** corresponds with climbing:traditional=yes + - **Traditional climbing is not possible here** corresponds with climbing:traditional=no + - **There are {climbing:traditional} traditional climbing routes** corresponds with climbing:traditional~^..*$_This option cannot be chosen as answer_ + + + + +### Speed climbing? + + + +The question is **Is there a speed climbing wall?** + + + + + + - **There is a speed climbing wall** corresponds with climbing:speed=yes + - **There is no speed climbing wall** corresponds with climbing:speed=no + - **There are {climbing:speed} speed climbing walls** corresponds with climbing:speed~^..*$_This option cannot be chosen as answer_ + + +This document is autogenerated from [assets/themes/climbing/climbing.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/climbing/climbing.json) \ No newline at end of file diff --git a/Docs/Layers/named_streets.md b/Docs/Layers/named_streets.md index 31690af773..f729fc5132 100644 --- a/Docs/Layers/named_streets.md +++ b/Docs/Layers/named_streets.md @@ -12,17 +12,9 @@ Hidden layer with all streets which have a name. Useful to detect addresses -## Table of contents - -1. [named_streets](#named_streets) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - - - + - This layer is shown at zoomlevel **18** and higher - This layer is not visible by default and must be enabled in the filter by the user. - This layer cannot be toggled in the filter view. If you import this layer in your theme, override `title` to make this toggleable. - This layer is not visible by default and the visibility cannot be toggled, effectively resulting in a fully hidden layer. This can be useful, e.g. to calculate some metatags. If you want to render this layer (e.g. for debugging), enable it by setting the URL-parameter layer-=true @@ -42,8 +34,6 @@ Hidden layer with all streets which have a name. Useful to detect addresses - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/named_streets/named_streets.json) - Basic tags for this layer diff --git a/Docs/Layers/nature_reserve.md b/Docs/Layers/nature_reserve.md index 5898a47465..2d0427d71f 100644 --- a/Docs/Layers/nature_reserve.md +++ b/Docs/Layers/nature_reserve.md @@ -12,31 +12,9 @@ A nature reserve is an area where nature can take its course -## Table of contents - -1. [nature_reserve](#nature_reserve) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [Access tag](#access-tag) - + [Operator tag](#operator-tag) - + [Name tag](#name-tag) - + [Dogs?](#dogs) - + [website](#website) - + [Curator](#curator) - + [Email](#email) - + [phone](#phone) - + [Non-editable description](#non-editable-description) - + [Editable description](#editable-description) - + [Surface area](#surface-area) - + [wikipedia](#wikipedia) - - - - + - This layer is shown at zoomlevel **12** and higher @@ -51,8 +29,6 @@ A nature reserve is an area where nature can take its course - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/nature_reserve/nature_reserve.json) - Basic tags for this layer diff --git a/Docs/Layers/nature_reserve_buurtnatuur.md b/Docs/Layers/nature_reserve_buurtnatuur.md deleted file mode 100644 index 3f2a9cf681..0000000000 --- a/Docs/Layers/nature_reserve_buurtnatuur.md +++ /dev/null @@ -1,46 +0,0 @@ -nature_reserve_buurtnatuur -============================ - - - - - -Een natuurgebied is een gebied waar actief ruimte gemaakt word voor de natuur. Typisch zijn deze in beheer van -Natuurpunt of het Agentschap Natuur en Bos of zijn deze erkend door de overheid. - -## Table of contents - -1. [nature_reserve_buurtnatuur](#nature_reserve_buurtnatuur) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [images](#images) - - -- This layer is needed as dependency for layer [parks](#parks) -- This layer is needed as dependency for layer [forest](#forest) - -[Go to the source code](../assets/layers/nature_reserve_buurtnatuur/nature_reserve_buurtnatuur.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- leisure - =nature_reserve - |boundary - =protected_area - -Supported attributes ----------------------- - -### images - -_This tagrendering has no question and is thus read-only_ - -This document is autogenerated from assets/layers/nature_reserve_buurtnatuur/nature_reserve_buurtnatuur.json \ No newline at end of file diff --git a/Docs/Layers/node.md b/Docs/Layers/node.md deleted file mode 100644 index a767e1f35e..0000000000 --- a/Docs/Layers/node.md +++ /dev/null @@ -1,60 +0,0 @@ -node -====== - -## Table of contents - -1. [node](#node) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [node-survey:date](#node-surveydate) - + [node-expected_rcn_route_relations](#node-expected_rcn_route_relations) - + [images](#images) - -[Go to the source code](../assets/layers/node/node.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- rcn_ref~^..*$ - -Supported attributes ----------------------- - - - -**Warning** This quick overview is incomplete - -attribute | type | values which are supported by this layer ------------ | ------ | ------------------------------------------ -[](https://taginfo.openstreetmap.org/keys/survey:date#values) [survey:date](https://wiki.openstreetmap.org/wiki/Key:survey:date) | [date](../SpecialInputElements.md#date) | [](https://wiki.openstreetmap.org/wiki/Tag:survey:date%3D) -[](https://taginfo.openstreetmap.org/keys/expected_rcn_route_relations#values) [expected_rcn_route_relations](https://wiki.openstreetmap.org/wiki/Key:expected_rcn_route_relations) | [int](../SpecialInputElements.md#int) | - -### node-survey:date - -The question is **When was this cycle node last surveyed?** - -This rendering asks information about the property [survey:date](https://wiki.openstreetmap.org/wiki/Key:survey:date) -This is rendered with `This cycle node was last surveyed on {survey:date}` - -- **Surveyed today!** corresponds with survey:date= - -### node-expected_rcn_route_relations - -The question is **How many other cycle nodes does this node link to?** - -This rendering asks information about the -property [expected_rcn_route_relations](https://wiki.openstreetmap.org/wiki/Key:expected_rcn_route_relations) -This is rendered with `This node links to {expected_rcn_route_relations} other cycle nodes.` - -### images - -_This tagrendering has no question and is thus read-only_ - -This document is autogenerated from assets/layers/node/node.json \ No newline at end of file diff --git a/Docs/Layers/node2node.md b/Docs/Layers/node2node.md deleted file mode 100644 index c8a7247525..0000000000 --- a/Docs/Layers/node2node.md +++ /dev/null @@ -1,58 +0,0 @@ -node2node -=========== - -## Table of contents - -1. [node2node](#node2node) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [node2node-survey:date](#node2node-surveydate) - + [export_as_gpx](#export_as_gpx) - - -- Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` - -[Go to the source code](../assets/layers/node2node/node2node.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- network - =rcn -- network:type - =node_network -- route - =bicycle - -Supported attributes ----------------------- - - - -**Warning** This quick overview is incomplete - -attribute | type | values which are supported by this layer ------------ | ------ | ------------------------------------------ -[](https://taginfo.openstreetmap.org/keys/survey:date#values) [survey:date](https://wiki.openstreetmap.org/wiki/Key:survey:date) | [date](../SpecialInputElements.md#date) | [](https://wiki.openstreetmap.org/wiki/Tag:survey:date%3D) - -### node2node-survey:date - -The question is **When was this node to node link last surveyed?** - -This rendering asks information about the property [survey:date](https://wiki.openstreetmap.org/wiki/Key:survey:date) -This is rendered with `This node to node link was last surveyed on {survey:date}` - -- **Surveyed today!** corresponds with survey:date= - -### export_as_gpx - -_This tagrendering has no question and is thus read-only_ - -This document is autogenerated from assets/layers/node2node/node2node.json \ No newline at end of file diff --git a/Docs/Layers/note_import.md b/Docs/Layers/note_import.md index 87e9cf6fcb..43ffa283bf 100644 --- a/Docs/Layers/note_import.md +++ b/Docs/Layers/note_import.md @@ -12,24 +12,9 @@ Template for note note imports. -## Table of contents - -1. [note_import](#note_import) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [conversation](#conversation) - + [Intro](#intro) - + [import](#import) - + [close_note_](#close_note_) - + [close_note_mapped](#close_note_mapped) - + [comment](#comment) - + [add_image](#add_image) - - - + - This layer is shown at zoomlevel **10** and higher - This layer is loaded from an external source, namely `https://api.openstreetmap.org/api/0.6/notes.json?closed=0&bbox={x_min},{y_min},{x_max},{y_max}` - This layer will automatically load [public_bookcase](./public_bookcase.md) into the layout as it depends on it: a tagrendering needs this layer (import) @@ -45,8 +30,6 @@ Template for note note imports. - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/note_import/note_import.json) - Basic tags for this layer diff --git a/Docs/Layers/observation_tower.md b/Docs/Layers/observation_tower.md index 39728c7da6..e018e652fd 100644 --- a/Docs/Layers/observation_tower.md +++ b/Docs/Layers/observation_tower.md @@ -12,30 +12,9 @@ Towers with a panoramic view -## Table of contents - -1. [observation_tower](#observation_tower) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [name](#name) - + [Height](#height) - + [access](#access) - + [Fee](#fee) - + [payment-options](#payment-options) - + [website](#website) - + [step_count](#step_count) - + [elevator](#elevator) - + [Operator](#operator) - + [wheelchair-access](#wheelchair-access) - + [wikipedia](#wikipedia) - - - - + - This layer is shown at zoomlevel **8** and higher @@ -50,8 +29,6 @@ Towers with a panoramic view - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/observation_tower/observation_tower.json) - Basic tags for this layer diff --git a/Docs/Layers/orchards.md b/Docs/Layers/orchards.md deleted file mode 100644 index e25d58bf1c..0000000000 --- a/Docs/Layers/orchards.md +++ /dev/null @@ -1,37 +0,0 @@ -orchards -========== - - - - - -## Table of contents - -1. [orchards](#orchards) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [images](#images) - -[Go to the source code](../assets/layers/orchards/orchards.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- landuse - =orchard - -Supported attributes ----------------------- - -### images - -_This tagrendering has no question and is thus read-only_ - -This document is autogenerated from assets/layers/orchards/orchards.json \ No newline at end of file diff --git a/Docs/Layers/osm-buildings-fixme.md b/Docs/Layers/osm-buildings-fixme.md deleted file mode 100644 index e9f6d27065..0000000000 --- a/Docs/Layers/osm-buildings-fixme.md +++ /dev/null @@ -1,143 +0,0 @@ -osm-buildings-fixme -===================== - -## Table of contents - -1. [osm-buildings-fixme](#osm-buildings-fixme) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [building type](#building-type) - + [grb-housenumber](#grb-housenumber) - + [grb-unit](#grb-unit) - + [grb-street](#grb-street) - + [grb-fixme](#grb-fixme) - + [grb-min-level](#grb-min-level) - + [fix_verdieping](#fix_verdieping) - + [all_tags](#all_tags) - -[Go to the source code](../assets/layers/osm-buildings-fixme/osm-buildings-fixme.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- building~^..*$ -- fixme~^..*$ - -Supported attributes ----------------------- - - - -**Warning** This quick overview is incomplete - -attribute | type | values which are supported by this layer ------------ | ------ | ------------------------------------------ -[](https://taginfo.openstreetmap.org/keys/building#values) [building](https://wiki.openstreetmap.org/wiki/Key:building) | [string](../SpecialInputElements.md#string) | [house](https://wiki.openstreetmap.org/wiki/Tag:building%3Dhouse) [detached](https://wiki.openstreetmap.org/wiki/Tag:building%3Ddetached) [semidetached_house](https://wiki.openstreetmap.org/wiki/Tag:building%3Dsemidetached_house) [apartments](https://wiki.openstreetmap.org/wiki/Tag:building%3Dapartments) [office](https://wiki.openstreetmap.org/wiki/Tag:building%3Doffice) [apartments](https://wiki.openstreetmap.org/wiki/Tag:building%3Dapartments) [shed](https://wiki.openstreetmap.org/wiki/Tag:building%3Dshed) [garage](https://wiki.openstreetmap.org/wiki/Tag:building%3Dgarage) [garages](https://wiki.openstreetmap.org/wiki/Tag:building%3Dgarages) [yes](https://wiki.openstreetmap.org/wiki/Tag:building%3Dyes) -[](https://taginfo.openstreetmap.org/keys/addr:housenumber#values) [addr:housenumber](https://wiki.openstreetmap.org/wiki/Key:addr:housenumber) | [string](../SpecialInputElements.md#string) | [](https://wiki.openstreetmap.org/wiki/Tag:addr:housenumber%3D) [](https://wiki.openstreetmap.org/wiki/Tag:addr:housenumber%3D) [](https://wiki.openstreetmap.org/wiki/Tag:addr:housenumber%3D) -[](https://taginfo.openstreetmap.org/keys/addr:unit#values) [addr:unit](https://wiki.openstreetmap.org/wiki/Key:addr:unit) | [string](../SpecialInputElements.md#string) | [](https://wiki.openstreetmap.org/wiki/Tag:addr:unit%3D) -[](https://taginfo.openstreetmap.org/keys/addr:street#values) [addr:street](https://wiki.openstreetmap.org/wiki/Key:addr:street) | [string](../SpecialInputElements.md#string) | -[](https://taginfo.openstreetmap.org/keys/fixme#values) [fixme](https://wiki.openstreetmap.org/wiki/Key:fixme) | [string](../SpecialInputElements.md#string) | [](https://wiki.openstreetmap.org/wiki/Tag:fixme%3D) -[](https://taginfo.openstreetmap.org/keys/building:min_level#values) [building:min_level](https://wiki.openstreetmap.org/wiki/Key:building:min_level) | [pnat](../SpecialInputElements.md#pnat) | - -### building type - -The question is **What kind of building is this?** - -This rendering asks information about the property [building](https://wiki.openstreetmap.org/wiki/Key:building) -This is rendered with `The building type is {building}` - -- **A normal house** corresponds with - building=house -- **A house detached from other building** corresponds - with building - =detached -- **A house sharing only one wall with another house** corresponds - with building - = - semidetached_house -- **An apartment building - highrise for living** corresponds - with building - =apartments -- **An office building - highrise for work** corresponds - with building - =office -- **An apartment building** corresponds with - building=apartments -- **A small shed, e.g. in a garden** corresponds - with building - =shed -- **A single garage to park a car** corresponds - with building - =garage -- **A building containing only garages; typically they are all identical** corresponds - with building - =garages -- **A building - no specification** corresponds - with building - =yes - -### grb-housenumber - -The question is **Wat is het huisnummer?** - -This rendering asks information about the -property [addr:housenumber](https://wiki.openstreetmap.org/wiki/Key:addr:housenumber) -This is rendered with `Het huisnummer is {addr:housenumber}` - -- **Geen huisnummer** corresponds - with not:addr:housenumber - =yes -- **Het huisnummer is {_grbNumber}, wat overeenkomt met het GRB** corresponds with addr:housenumber= -- **Dit gebouw heeft geen nummer, net zoals in het GRB** corresponds - with not:addr:housenumber - =yes - -### grb-unit - -The question is **Wat is de wooneenheid-aanduiding?** - -This rendering asks information about the property [addr:unit](https://wiki.openstreetmap.org/wiki/Key:addr:unit) -This is rendered with `De wooneenheid-aanduiding is {addr:unit} ` - -- **Geen wooneenheid-nummer** corresponds with - -### grb-street - -The question is **Wat is de straat?** - -This rendering asks information about the property [addr:street](https://wiki.openstreetmap.org/wiki/Key:addr:street) -This is rendered with `De straat is {addr:street}` - -### grb-fixme - -The question is **Wat zegt de fixme?** - -This rendering asks information about the property [fixme](https://wiki.openstreetmap.org/wiki/Key:fixme) -This is rendered with `De fixme is {fixme}` - -- **Geen fixme** corresponds with - -### grb-min-level - -The question is **Hoeveel verdiepingen ontbreken?** - -This rendering asks information about the -property [building:min_level](https://wiki.openstreetmap.org/wiki/Key:building:min_level) -This is rendered with `Dit gebouw begint maar op de {building:min_level} verdieping` - -### fix_verdieping - -_This tagrendering has no question and is thus read-only_ - -### all_tags - -_This tagrendering has no question and is thus read-only_ - -This document is autogenerated from assets/layers/osm-buildings-fixme/osm-buildings-fixme.json \ No newline at end of file diff --git a/Docs/Layers/osm-buildings.md b/Docs/Layers/osm-buildings.md deleted file mode 100644 index f5562c9dc4..0000000000 --- a/Docs/Layers/osm-buildings.md +++ /dev/null @@ -1,51 +0,0 @@ -osm-buildings -=============== - -## Table of contents - -1. [osm-buildings](#osm-buildings) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [apply_streetname](#apply_streetname) - - -- Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` -- This layer will automatically load [crab_address](./crab_address.md) into the layout as it depends on it: A - calculated tag loads features from this layer (calculatedTag[0] which calculates the value for _ - embedded_crab_addresses) -- This layer will automatically load [named_streets](./named_streets.md) into the layout as it depends on it: A - calculated tag loads features from this layer (calculatedTag[3] which calculates the value for _nearby_street_names) -- This layer is needed as dependency for layer [grb](#grb) -- This layer is needed as dependency for layer [grb](#grb) - -[Go to the source code](../assets/layers/osm-buildings/osm-buildings.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- building~^..*$ -- addr:housenumber~^..*$ -- - -Supported attributes ----------------------- - -### apply_streetname - -_This tagrendering has no question and is thus read-only_ - -- **No nearby street has the same name. The CRAB-name is {_name_to_apply}** corresponds - with _spelling_is_correct - =false -- **There are multiple streetnames applicable here** corresponds - with _singular_import - =false - -This document is autogenerated from assets/layers/osm-buildings/osm-buildings.json \ No newline at end of file diff --git a/Docs/Layers/parking.md b/Docs/Layers/parking.md index 97808febc0..61f6b2c501 100644 --- a/Docs/Layers/parking.md +++ b/Docs/Layers/parking.md @@ -12,19 +12,9 @@ A layer showing car parkings -## Table of contents - -1. [parking](#parking) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - - - - + - This layer is shown at zoomlevel **12** and higher @@ -39,8 +29,6 @@ A layer showing car parkings - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/parking/parking.json) - Basic tags for this layer diff --git a/Docs/Layers/parks.md b/Docs/Layers/parks.md deleted file mode 100644 index 800d653f08..0000000000 --- a/Docs/Layers/parks.md +++ /dev/null @@ -1,48 +0,0 @@ -parks -======= - - - - - -Een park is een publiek toegankelijke, groene ruimte binnen de stad. Ze is typisch ingericht voor recreatief gebruik, -met (verharde) wandelpaden, zitbanken, vuilnisbakken, een gezellig vijvertje, ... - -## Table of contents - -1. [parks](#parks) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [images](#images) - - -- This layer will automatically load [nature_reserve_buurtnatuur](./nature_reserve_buurtnatuur.md) into the layout as - it depends on it: A calculated tag loads features from this layer (calculatedTag[0] which calculates the value for _ - overlapWithUpperLayers) -- This layer is needed as dependency for layer [forest](#forest) - -[Go to the source code](../assets/layers/parks/parks.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- leisure - =park - |landuse - =village_green - -Supported attributes ----------------------- - -### images - -_This tagrendering has no question and is thus read-only_ - -This document is autogenerated from assets/layers/parks/parks.json \ No newline at end of file diff --git a/Docs/Layers/parks_and_forests_without_etymology.md b/Docs/Layers/parks_and_forests_without_etymology.md new file mode 100644 index 0000000000..f9baee3bf8 --- /dev/null +++ b/Docs/Layers/parks_and_forests_without_etymology.md @@ -0,0 +1,162 @@ + + + parks_and_forests_without_etymology +===================================== + + + + + +All objects which have an etymology known + + + + + + + - This layer is shown at zoomlevel **18** and higher + + + + +#### Themes using this layer + + + + + + - [etymology](https://mapcomplete.osm.be/etymology) + + + + + Basic tags for this layer +--------------------------- + + + +Elements must have the all of following tags to be shown on this layer: + + + + - name~^..*$ + - leisure=park|landuse=forest + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22landuse%22%3D%22forest%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22leisure%22%3D%22park%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes +---------------------- + + + +**Warning** This quick overview is incomplete + + + +attribute | type | values which are supported by this layer +----------- | ------ | ------------------------------------------ +[](https://taginfo.openstreetmap.org/keys/name:etymology:wikidata#values) [name:etymology:wikidata](https://wiki.openstreetmap.org/wiki/Key:name:etymology:wikidata) | [wikidata](../SpecialInputElements.md#wikidata) | +[](https://taginfo.openstreetmap.org/keys/name:etymology#values) [name:etymology](https://wiki.openstreetmap.org/wiki/Key:name:etymology) | [string](../SpecialInputElements.md#string) | [unknown](https://wiki.openstreetmap.org/wiki/Tag:name:etymology%3Dunknown) + + + + +### etymology-images-from-wikipedia + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### wikipedia-etymology + + + +The question is **What is the Wikidata-item that this object is named after?** + +This rendering asks information about the property [name:etymology:wikidata](https://wiki.openstreetmap.org/wiki/Key:name:etymology:wikidata) +This is rendered with `

Wikipedia article of the name giver

{wikipedia(name:etymology:wikidata):max-height:20rem}` + + + +### zoeken op inventaris onroerend erfgoed + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### simple etymology + + + +The question is **What is this object named after?
This might be written on the street name sign** + +This rendering asks information about the property [name:etymology](https://wiki.openstreetmap.org/wiki/Key:name:etymology) +This is rendered with `Named after {name:etymology}` + + + + - **The origin of this name is unknown in all literature** corresponds with name:etymology=unknown + + + + +### questions + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### street-name-sign-image + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### minimap + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### etymology_multi_apply + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### wikipedia + + + +_This tagrendering has no question and is thus read-only_ + + + +This document is autogenerated from [assets/themes/etymology/etymology.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/etymology/etymology.json) \ No newline at end of file diff --git a/Docs/Layers/pedestrian_path.md b/Docs/Layers/pedestrian_path.md index 6539d04c77..748945885d 100644 --- a/Docs/Layers/pedestrian_path.md +++ b/Docs/Layers/pedestrian_path.md @@ -12,17 +12,9 @@ Pedestrian footpaths, especially used for indoor navigation and snapping entranc -## Table of contents - -1. [pedestrian_path](#pedestrian_path) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - - - + - This layer is shown at zoomlevel **18** and higher - This layer is needed as dependency for layer [entrance](#entrance) @@ -38,8 +30,6 @@ Pedestrian footpaths, especially used for indoor navigation and snapping entranc - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/pedestrian_path/pedestrian_path.json) - Basic tags for this layer diff --git a/Docs/Layers/picnic_table.md b/Docs/Layers/picnic_table.md index 0e5b6301d9..a0cc5ece81 100644 --- a/Docs/Layers/picnic_table.md +++ b/Docs/Layers/picnic_table.md @@ -12,20 +12,9 @@ The layer showing picnic tables -## Table of contents - -1. [picnic_table](#picnic_table) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [picnic_table-material](#picnic_table-material) - - - - + - This layer is shown at zoomlevel **12** and higher @@ -41,8 +30,6 @@ The layer showing picnic tables - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/picnic_table/picnic_table.json) - Basic tags for this layer diff --git a/Docs/Layers/play_forest.md b/Docs/Layers/play_forest.md index e3dbe112c3..570732415d 100644 --- a/Docs/Layers/play_forest.md +++ b/Docs/Layers/play_forest.md @@ -12,25 +12,9 @@ Een speelbos is een vrij toegankelijke zone in een bos -## Table of contents - -1. [play_forest](#play_forest) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [play_forest-operator](#play_forest-operator) - + [play_forest-opening_hours](#play_forest-opening_hours) - + [play_forest-email](#play_forest-email) - + [play_forest-phone](#play_forest-phone) - + [questions](#questions) - + [play_forest-reviews](#play_forest-reviews) - - - - + - This layer is shown at zoomlevel **13** and higher @@ -44,8 +28,6 @@ Een speelbos is een vrij toegankelijke zone in een bos - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/play_forest/play_forest.json) - Basic tags for this layer diff --git a/Docs/Layers/playground.md b/Docs/Layers/playground.md index d12249fbb3..0a2bd9e74c 100644 --- a/Docs/Layers/playground.md +++ b/Docs/Layers/playground.md @@ -12,32 +12,9 @@ Playgrounds -## Table of contents - -1. [playground](#playground) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [playground-surface](#playground-surface) - + [playground-lit](#playground-lit) - + [playground-min_age](#playground-min_age) - + [playground-max_age](#playground-max_age) - + [playground-operator](#playground-operator) - + [playground-access](#playground-access) - + [website](#website) - + [playground-email](#playground-email) - + [playground-phone](#playground-phone) - + [Playground-wheelchair](#playground-wheelchair) - + [playground-opening_hours](#playground-opening_hours) - + [questions](#questions) - + [playground-reviews](#playground-reviews) - - - - + - This layer is shown at zoomlevel **13** and higher @@ -52,8 +29,6 @@ Playgrounds - [playgrounds](https://mapcomplete.osm.be/playgrounds) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/playground/playground.json) - Basic tags for this layer diff --git a/Docs/Layers/postal_code_boundary.md b/Docs/Layers/postal_code_boundary.md deleted file mode 100644 index d5ec722a4c..0000000000 --- a/Docs/Layers/postal_code_boundary.md +++ /dev/null @@ -1,39 +0,0 @@ -postal_code_boundary -====================== - -## Table of contents - -1. [postal_code_boundary](#postal_code_boundary) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [postal_code](#postal_code) - - -- This layer is needed as dependency for layer [town_hall](#town_hall) - -[Go to the source code](../assets/layers/postal_code_boundary/postal_code_boundary.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- boundary - =postal_code - |bounary - =administrative - &postal_code~^..*$ - -Supported attributes ----------------------- - -### postal_code - -_This tagrendering has no question and is thus read-only_ - -This document is autogenerated from assets/layers/postal_code_boundary/postal_code_boundary.json \ No newline at end of file diff --git a/Docs/Layers/postboxes.md b/Docs/Layers/postboxes.md index 3edae41ea2..68d08387f2 100644 --- a/Docs/Layers/postboxes.md +++ b/Docs/Layers/postboxes.md @@ -1,4 +1,6 @@ -postboxes + + + postboxes =========== @@ -7,43 +9,66 @@ postboxes The layer showing postboxes. -## Table of contents - -1. [postboxes](#postboxes) - * [Themes using this layer](#themes-using-this-layer) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [images](#images) - + [minimap](#minimap) - -#### Themes using this layer - -- [postboxes](https://mapcomplete.osm.be/postboxes) - -[Go to the source code](../assets/layers/postboxes/postboxes.json) -Basic tags for this layer + + + - This layer is shown at zoomlevel **12** and higher + + + + +#### Themes using this layer + + + + + + - [postboxes](https://mapcomplete.osm.be/postboxes) + + + + + Basic tags for this layer --------------------------- Elements must have the all of following tags to be shown on this layer: -- amenity - =post_box -Supported attributes + + - amenity=post_box + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22amenity%22%3D%22post_box%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes ---------------------- -### images + + + + +### images + + _This tagrendering has no question and is thus read-only_ -### minimap + + + + +### minimap + + _This tagrendering has no question and is thus read-only_ -This document is autogenerated from assets/layers/postboxes/postboxes.json \ No newline at end of file + + +This document is autogenerated from [assets/themes/postboxes/postboxes.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/postboxes/postboxes.json) \ No newline at end of file diff --git a/Docs/Layers/postoffices.md b/Docs/Layers/postoffices.md index 3bde0835ef..f11400b1de 100644 --- a/Docs/Layers/postoffices.md +++ b/Docs/Layers/postoffices.md @@ -1,70 +1,99 @@ -postoffices + + + postoffices ============= - + A layer showing post offices. -## Table of contents - -1. [postoffices](#postoffices) - * [Themes using this layer](#themes-using-this-layer) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [images](#images) - + [minimap](#minimap) - + [OH](#oh) - -#### Themes using this layer - -- [postboxes](https://mapcomplete.osm.be/postboxes) - -[Go to the source code](../assets/layers/postoffices/postoffices.json) -Basic tags for this layer + + + - This layer is shown at zoomlevel **12** and higher + + + + +#### Themes using this layer + + + + + + - [postboxes](https://mapcomplete.osm.be/postboxes) + + + + + Basic tags for this layer --------------------------- Elements must have the all of following tags to be shown on this layer: -- amenity - =post_office -Supported attributes + + - amenity=post_office + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22amenity%22%3D%22post_office%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes ---------------------- **Warning** This quick overview is incomplete + + attribute | type | values which are supported by this layer ----------- | ------ | ------------------------------------------ [](https://taginfo.openstreetmap.org/keys/opening_hours#values) [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) | [opening_hours](../SpecialInputElements.md#opening_hours) | [24/7](https://wiki.openstreetmap.org/wiki/Tag:opening_hours%3D24/7) -### images + + + +### images + + _This tagrendering has no question and is thus read-only_ -### minimap + + + + +### minimap + + _This tagrendering has no question and is thus read-only_ -### OH + + + + +### OH + + The question is **What are the opening hours for this post office?** -This rendering asks information about the -property [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) +This rendering asks information about the property [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) This is rendered with `Opening Hours: {opening_hours_table()}` -- **24/7 opened (including holidays)** corresponds - with opening_hours - =24/7 -This document is autogenerated from assets/layers/postoffices/postoffices.json \ No newline at end of file + + - **24/7 opened (including holidays)** corresponds with opening_hours=24/7 + + +This document is autogenerated from [assets/themes/postboxes/postboxes.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/postboxes/postboxes.json) \ No newline at end of file diff --git a/Docs/Layers/public_bookcase.md b/Docs/Layers/public_bookcase.md index 1355e599af..59605bd70e 100644 --- a/Docs/Layers/public_bookcase.md +++ b/Docs/Layers/public_bookcase.md @@ -12,28 +12,9 @@ A streetside cabinet with books, accessible to anyone -## Table of contents - -1. [public_bookcase](#public_bookcase) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [public_bookcase-name](#public_bookcase-name) - + [public_bookcase-capacity](#public_bookcase-capacity) - + [bookcase-booktypes](#bookcase-booktypes) - + [bookcase-is-indoors](#bookcase-is-indoors) - + [bookcase-is-accessible](#bookcase-is-accessible) - + [public_bookcase-operator](#public_bookcase-operator) - + [public_bookcase-brand](#public_bookcase-brand) - + [public_bookcase-ref](#public_bookcase-ref) - + [public_bookcase-start_date](#public_bookcase-start_date) - + [public_bookcase-website](#public_bookcase-website) - - - + - This layer is shown at zoomlevel **10** and higher - This layer is needed as dependency for layer [note_import](#note_import) @@ -49,8 +30,6 @@ A streetside cabinet with books, accessible to anyone - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/public_bookcase/public_bookcase.json) - Basic tags for this layer diff --git a/Docs/Layers/raw_inspire_polygons.md b/Docs/Layers/raw_inspire_polygons.md deleted file mode 100644 index c38230aa27..0000000000 --- a/Docs/Layers/raw_inspire_polygons.md +++ /dev/null @@ -1,39 +0,0 @@ -raw_inspire_polygons -====================== - -## Table of contents - -1. [raw_inspire_polygons](#raw_inspire_polygons) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - - -- This layer cannot be toggled in the filter view. If you import this layer in your theme, override `title` to make this - toggleable. -- Not visible in the layer selection by default. If you want to make this layer toggable, override `name` -- Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` -- This layer is loaded from an external source, namely `https://osm-uk-addresses.russss.dev/inspire/{z}/{x}/{y}.json` -- This layer will automatically load [address](./address.md) into the layout as it depends on it: A calculated tag - loads features from this layer (calculatedTag[0] which calculates the value for _has_address) -- This layer is needed as dependency for layer [to_import](#to_import) - -[Go to the source code](../assets/layers/raw_inspire_polygons/raw_inspire_polygons.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- inspireid~^..*$ - -Supported attributes ----------------------- - - - -This document is autogenerated from assets/layers/raw_inspire_polygons/raw_inspire_polygons.json \ No newline at end of file diff --git a/Docs/Layers/recycling.md b/Docs/Layers/recycling.md index 9b3326456d..c6ed6f1f2f 100644 --- a/Docs/Layers/recycling.md +++ b/Docs/Layers/recycling.md @@ -12,28 +12,9 @@ A layer with recycling containers and centres -## Table of contents - -1. [recycling](#recycling) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [recycling-type](#recycling-type) - + [recycling-centre-name](#recycling-centre-name) - + [container-location](#container-location) - + [recycling-accepts](#recycling-accepts) - + [operator](#operator) - + [website](#website) - + [email](#email) - + [phone](#phone) - + [opening_hours](#opening_hours) - - - - + - This layer is shown at zoomlevel **12** and higher @@ -48,8 +29,6 @@ A layer with recycling containers and centres - [waste](https://mapcomplete.osm.be/waste) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/recycling/recycling.json) - Basic tags for this layer diff --git a/Docs/Layers/service_ways.md b/Docs/Layers/service_ways.md deleted file mode 100644 index 189b979416..0000000000 --- a/Docs/Layers/service_ways.md +++ /dev/null @@ -1,39 +0,0 @@ -service_ways -============== - - - - - -A seperate layer with service roads, as to remove them from the intersection testing - -## Table of contents - -1. [service_ways](#service_ways) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - - -- Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` - -[Go to the source code](../assets/layers/service_ways/service_ways.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- highway - =service - -Supported attributes ----------------------- - - - -This document is autogenerated from assets/layers/service_ways/service_ways.json \ No newline at end of file diff --git a/Docs/Layers/shadow.md b/Docs/Layers/shadow.md deleted file mode 100644 index 1cd41fafe1..0000000000 --- a/Docs/Layers/shadow.md +++ /dev/null @@ -1,37 +0,0 @@ -shadow -======== - -## Table of contents - -1. [shadow](#shadow) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - - -- This layer cannot be toggled in the filter view. If you import this layer in your theme, override `title` to make this - toggleable. -- Not visible in the layer selection by default. If you want to make this layer toggable, override `name` -- Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` -- This layer is loaded from an external source, namely `https://raw.githubusercontent.com/pietervdvn/MapComplete/master/assets/themes/speelplekken/shadow.geojson` - -[Go to the source code](../assets/layers/shadow/shadow.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- shadow - =yes - -Supported attributes ----------------------- - - - -This document is autogenerated from assets/layers/shadow/shadow.json \ No newline at end of file diff --git a/Docs/Layers/shops.md b/Docs/Layers/shops.md index 79ab56905a..b00a3b1030 100644 --- a/Docs/Layers/shops.md +++ b/Docs/Layers/shops.md @@ -12,28 +12,9 @@ A shop -## Table of contents - -1. [shops](#shops) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [shops-name](#shops-name) - + [shops-shop](#shops-shop) - + [shops-phone](#shops-phone) - + [shops-website](#shops-website) - + [shops-email](#shops-email) - + [shops-opening_hours](#shops-opening_hours) - + [payment-options](#payment-options) - + [questions](#questions) - + [reviews](#reviews) - - - - + - This layer is shown at zoomlevel **16** and higher @@ -48,8 +29,6 @@ A shop - [shops](https://mapcomplete.osm.be/shops) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/shops/shops.json) - Basic tags for this layer diff --git a/Docs/Layers/sidewalks.md b/Docs/Layers/sidewalks.md deleted file mode 100644 index 42a9de872c..0000000000 --- a/Docs/Layers/sidewalks.md +++ /dev/null @@ -1,118 +0,0 @@ -sidewalks -=========== - - - - - -Layer showing sidewalks of highways - -## Table of contents - -1. [sidewalks](#sidewalks) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [streetname](#streetname) - + [left-sidewalk_minimap](#left-sidewalk_minimap) - + [left-has_sidewalk](#left-has_sidewalk) - + [left-sidewalk_width](#left-sidewalk_width) - + [questions](#questions) - + [right-sidewalk_minimap](#right-sidewalk_minimap) - + [right-has_sidewalk](#right-has_sidewalk) - + [right-sidewalk_width](#right-sidewalk_width) - + [questions](#questions) - -[Go to the source code](../assets/layers/sidewalks/sidewalks.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- highway - =residential - |highway - =unclassified - |highway - =tertiary - |highway - =secondary - -Supported attributes ----------------------- - - - -**Warning** This quick overview is incomplete - -attribute | type | values which are supported by this layer ------------ | ------ | ------------------------------------------ -[](https://taginfo.openstreetmap.org/keys/sidewalk:left#values) [sidewalk:left](https://wiki.openstreetmap.org/wiki/Key:sidewalk:left) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:sidewalk:left%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:sidewalk:left%3Dno) -[](https://taginfo.openstreetmap.org/keys/sidewalk:left:width#values) [sidewalk:left:width](https://wiki.openstreetmap.org/wiki/Key:sidewalk:left:width) | [length](../SpecialInputElements.md#length) | -[](https://taginfo.openstreetmap.org/keys/sidewalk:right#values) [sidewalk:right](https://wiki.openstreetmap.org/wiki/Key:sidewalk:right) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:sidewalk:right%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:sidewalk:right%3Dno) -[](https://taginfo.openstreetmap.org/keys/sidewalk:right:width#values) [sidewalk:right:width](https://wiki.openstreetmap.org/wiki/Key:sidewalk:right:width) | [length](../SpecialInputElements.md#length) | - -### streetname - -_This tagrendering has no question and is thus read-only_ - -### left-sidewalk_minimap - -_This tagrendering has no question and is thus read-only_ - -### left-has_sidewalk - -The question is **Is there a sidewalk on this side of the road?** - -- **Yes, there is a sidewalk on this side of the road** corresponds - with sidewalk:left - =yes -- **No, there is no seperated sidewalk to walk on** corresponds - with sidewalk:left - =no - -### left-sidewalk_width - -The question is **What is the width of the sidewalk on this side of the road?** - -This rendering asks information about the -property [sidewalk:left:width](https://wiki.openstreetmap.org/wiki/Key:sidewalk:left:width) -This is rendered with `This sidewalk is {sidewalk:left:width}m wide` - -### questions - -_This tagrendering has no question and is thus read-only_ - -### right-sidewalk_minimap - -_This tagrendering has no question and is thus read-only_ - -### right-has_sidewalk - -The question is **Is there a sidewalk on this side of the road?** - -- **Yes, there is a sidewalk on this side of the road** corresponds - with sidewalk:right - =yes -- **No, there is no seperated sidewalk to walk on** corresponds - with sidewalk:right - =no - -### right-sidewalk_width - -The question is **What is the width of the sidewalk on this side of the road?** - -This rendering asks information about the -property [sidewalk:right:width](https://wiki.openstreetmap.org/wiki/Key:sidewalk:right:width) -This is rendered with `This sidewalk is {sidewalk:right:width}m wide` - -### questions - -_This tagrendering has no question and is thus read-only_ - -This document is autogenerated from assets/layers/sidewalks/sidewalks.json \ No newline at end of file diff --git a/Docs/Layers/slow_roads.md b/Docs/Layers/slow_roads.md index 1a5b5761b6..8c9fce9b01 100644 --- a/Docs/Layers/slow_roads.md +++ b/Docs/Layers/slow_roads.md @@ -12,22 +12,9 @@ All carfree roads -## Table of contents - -1. [slow_roads](#slow_roads) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [explanation](#explanation) - + [slow_roads-surface](#slow_roads-surface) - + [slow_road_is_lit](#slow_road_is_lit) - - - - + - This layer is shown at zoomlevel **16** and higher @@ -41,8 +28,6 @@ All carfree roads - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/slow_roads/slow_roads.json) - Basic tags for this layer diff --git a/Docs/Layers/split_point.md b/Docs/Layers/split_point.md deleted file mode 100644 index 8164c272d8..0000000000 --- a/Docs/Layers/split_point.md +++ /dev/null @@ -1,36 +0,0 @@ -split_point -============= - - - - - -Layer rendering the little scissors for the minimap in the 'splitRoadWizard' - -## Table of contents - -1. [split_point](#split_point) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - -[Go to the source code](../assets/layers/split_point/split_point.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- _split_point - =yes - -Supported attributes ----------------------- - - - -This document is autogenerated from assets/layers/split_point/split_point.json \ No newline at end of file diff --git a/Docs/Layers/sport_pitch.md b/Docs/Layers/sport_pitch.md index 87355e3f22..a0fe1fa2da 100644 --- a/Docs/Layers/sport_pitch.md +++ b/Docs/Layers/sport_pitch.md @@ -12,28 +12,9 @@ A sport pitch -## Table of contents - -1. [sport_pitch](#sport_pitch) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [sport_pitch-sport](#sport_pitch-sport) - + [sport_pitch-surface](#sport_pitch-surface) - + [sport-pitch-access](#sport-pitch-access) - + [sport-pitch-reservation](#sport-pitch-reservation) - + [sport_pitch-phone](#sport_pitch-phone) - + [sport_pitch-email](#sport_pitch-email) - + [sport_pitch-opening_hours](#sport_pitch-opening_hours) - + [questions](#questions) - + [sport-pitch-reviews](#sport-pitch-reviews) - - - - + - This layer is shown at zoomlevel **12** and higher @@ -48,8 +29,6 @@ A sport pitch - [sport_pitches](https://mapcomplete.osm.be/sport_pitches) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/sport_pitch/sport_pitch.json) - Basic tags for this layer diff --git a/Docs/Layers/sport_places_without_etymology.md b/Docs/Layers/sport_places_without_etymology.md new file mode 100644 index 0000000000..d195f23e0f --- /dev/null +++ b/Docs/Layers/sport_places_without_etymology.md @@ -0,0 +1,162 @@ + + + sport_places_without_etymology +================================ + + + + + +All objects which have an etymology known + + + + + + + - This layer is shown at zoomlevel **18** and higher + + + + +#### Themes using this layer + + + + + + - [etymology](https://mapcomplete.osm.be/etymology) + + + + + Basic tags for this layer +--------------------------- + + + +Elements must have the all of following tags to be shown on this layer: + + + + - name~^..*$ + - leisure=sports_centre|leisure=stadium|leisure=swimming_pool + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22leisure%22%3D%22sports_centre%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22leisure%22%3D%22stadium%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22leisure%22%3D%22swimming_pool%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes +---------------------- + + + +**Warning** This quick overview is incomplete + + + +attribute | type | values which are supported by this layer +----------- | ------ | ------------------------------------------ +[](https://taginfo.openstreetmap.org/keys/name:etymology:wikidata#values) [name:etymology:wikidata](https://wiki.openstreetmap.org/wiki/Key:name:etymology:wikidata) | [wikidata](../SpecialInputElements.md#wikidata) | +[](https://taginfo.openstreetmap.org/keys/name:etymology#values) [name:etymology](https://wiki.openstreetmap.org/wiki/Key:name:etymology) | [string](../SpecialInputElements.md#string) | [unknown](https://wiki.openstreetmap.org/wiki/Tag:name:etymology%3Dunknown) + + + + +### etymology-images-from-wikipedia + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### wikipedia-etymology + + + +The question is **What is the Wikidata-item that this object is named after?** + +This rendering asks information about the property [name:etymology:wikidata](https://wiki.openstreetmap.org/wiki/Key:name:etymology:wikidata) +This is rendered with `

Wikipedia article of the name giver

{wikipedia(name:etymology:wikidata):max-height:20rem}` + + + +### zoeken op inventaris onroerend erfgoed + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### simple etymology + + + +The question is **What is this object named after?
This might be written on the street name sign** + +This rendering asks information about the property [name:etymology](https://wiki.openstreetmap.org/wiki/Key:name:etymology) +This is rendered with `Named after {name:etymology}` + + + + - **The origin of this name is unknown in all literature** corresponds with name:etymology=unknown + + + + +### questions + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### street-name-sign-image + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### minimap + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### etymology_multi_apply + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### wikipedia + + + +_This tagrendering has no question and is thus read-only_ + + + +This document is autogenerated from [assets/themes/etymology/etymology.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/etymology/etymology.json) \ No newline at end of file diff --git a/Docs/Layers/street_lamps.md b/Docs/Layers/street_lamps.md index 14bd158598..83f42657c0 100644 --- a/Docs/Layers/street_lamps.md +++ b/Docs/Layers/street_lamps.md @@ -12,26 +12,9 @@ A layer showing street lights -## Table of contents - -1. [street_lamps](#street_lamps) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [ref](#ref) - + [support](#support) - + [lamp_mount](#lamp_mount) - + [method](#method) - + [colour](#colour) - + [count](#count) - + [lit](#lit) - + [direction](#direction) - - - - + - This layer is shown at zoomlevel **0** and higher @@ -46,8 +29,6 @@ A layer showing street lights - [street_lighting](https://mapcomplete.osm.be/street_lighting) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/street_lamps/street_lamps.json) - Basic tags for this layer diff --git a/Docs/Layers/streets_without_etymology.md b/Docs/Layers/streets_without_etymology.md new file mode 100644 index 0000000000..2f098fc418 --- /dev/null +++ b/Docs/Layers/streets_without_etymology.md @@ -0,0 +1,163 @@ + + + streets_without_etymology +=========================== + + + + + +All objects which have an etymology known + + + + + + + - This layer is shown at zoomlevel **18** and higher + + + + +#### Themes using this layer + + + + + + - [etymology](https://mapcomplete.osm.be/etymology) + + + + + Basic tags for this layer +--------------------------- + + + +Elements must have the all of following tags to be shown on this layer: + + + + - name~^..*$ + - highway~^..*$ + - highway!~^bus_stop$ + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22name%22%5D%5B%22highway%22%5D%5B%22highway%22!~%22%5Ebus_stop%24%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes +---------------------- + + + +**Warning** This quick overview is incomplete + + + +attribute | type | values which are supported by this layer +----------- | ------ | ------------------------------------------ +[](https://taginfo.openstreetmap.org/keys/name:etymology:wikidata#values) [name:etymology:wikidata](https://wiki.openstreetmap.org/wiki/Key:name:etymology:wikidata) | [wikidata](../SpecialInputElements.md#wikidata) | +[](https://taginfo.openstreetmap.org/keys/name:etymology#values) [name:etymology](https://wiki.openstreetmap.org/wiki/Key:name:etymology) | [string](../SpecialInputElements.md#string) | [unknown](https://wiki.openstreetmap.org/wiki/Tag:name:etymology%3Dunknown) + + + + +### etymology-images-from-wikipedia + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### wikipedia-etymology + + + +The question is **What is the Wikidata-item that this object is named after?** + +This rendering asks information about the property [name:etymology:wikidata](https://wiki.openstreetmap.org/wiki/Key:name:etymology:wikidata) +This is rendered with `

Wikipedia article of the name giver

{wikipedia(name:etymology:wikidata):max-height:20rem}` + + + +### zoeken op inventaris onroerend erfgoed + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### simple etymology + + + +The question is **What is this object named after?
This might be written on the street name sign** + +This rendering asks information about the property [name:etymology](https://wiki.openstreetmap.org/wiki/Key:name:etymology) +This is rendered with `Named after {name:etymology}` + + + + - **The origin of this name is unknown in all literature** corresponds with name:etymology=unknown + + + + +### questions + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### street-name-sign-image + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### minimap + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### etymology_multi_apply + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### wikipedia + + + +_This tagrendering has no question and is thus read-only_ + + + +This document is autogenerated from [assets/themes/etymology/etymology.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/etymology/etymology.json) \ No newline at end of file diff --git a/Docs/Layers/surveillance_camera.md b/Docs/Layers/surveillance_camera.md index 428e106fbf..3790ee7f02 100644 --- a/Docs/Layers/surveillance_camera.md +++ b/Docs/Layers/surveillance_camera.md @@ -12,26 +12,9 @@ This layer shows surveillance cameras and allows a contributor to update informa -## Table of contents - -1. [surveillance_camera](#surveillance_camera) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [Camera type: fixed; panning; dome](#camera-type-fixed;-panning;-dome) - + [camera_direction](#camera_direction) - + [Operator](#operator) - + [Surveillance type: public, outdoor, indoor](#surveillance-type-public,-outdoor,-indoor) - + [is_indoor](#is_indoor) - + [Level](#level) - + [Surveillance:zone](#surveillancezone) - + [camera:mount](#cameramount) - - - + - This layer is shown at zoomlevel **12** and higher - This layer will automatically load [walls_and_buildings](./walls_and_buildings.md) into the layout as it depends on it: a preset snaps to this layer (presets[1]) @@ -47,8 +30,6 @@ This layer shows surveillance cameras and allows a contributor to update informa - [surveillance](https://mapcomplete.osm.be/surveillance) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/surveillance_camera/surveillance_camera.json) - Basic tags for this layer diff --git a/Docs/Layers/to_import.md b/Docs/Layers/to_import.md deleted file mode 100644 index ca546e45ff..0000000000 --- a/Docs/Layers/to_import.md +++ /dev/null @@ -1,73 +0,0 @@ -to_import -=========== - - - - - -Alamat - -## Table of contents - -1. [to_import](#to_import) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [uk_addresses_explanation](#uk_addresses_explanation) - + [uk_addresses_embedding_outline](#uk_addresses_embedding_outline) - + [uk_addresses_import_button](#uk_addresses_import_button) - - -- This layer is loaded from an external source, namely `https://osm-uk-addresses.russss.dev/addresses/{z}/{x}/{y}.json` -- This layer will automatically load [address](./address.md) into the layout as it depends on it: a tagrendering - needs this layer (uk_addresses_import_button) -- This layer will automatically load [address](./address.md) into the layout as it depends on it: A calculated tag - loads features from this layer (calculatedTag[0] which calculates the value for _embedding_object) -- This layer will automatically load [raw_inspire_polygons](./raw_inspire_polygons.md) into the layout as it depends - on it: A calculated tag loads features from this layer (calculatedTag[3] which calculates the value for _ - embedding_inspire_polygon_has_address) - -[Go to the source code](../assets/layers/to_import/to_import.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- inspireid~^..*$ - -Supported attributes ----------------------- - - - -**Warning** This quick overview is incomplete - -attribute | type | values which are supported by this layer ------------ | ------ | ------------------------------------------ -[](https://taginfo.openstreetmap.org/keys/_embedding_object:id#values) [_embedding_object:id](https://wiki.openstreetmap.org/wiki/Key:_embedding_object:id) | Multiple choice | [true](https://wiki.openstreetmap.org/wiki/Tag:_embedding_object:id%3Dtrue) [false](https://wiki.openstreetmap.org/wiki/Tag:_embedding_object:id%3Dfalse) - -### uk_addresses_explanation - -_This tagrendering has no question and is thus read-only_ - -### uk_addresses_embedding_outline - -_This tagrendering has no question and is thus read-only_ - -- **The INSPIRE-polygon containing this point has at least one address contained** corresponds - with _embedding_object:id - =true -- **The INSPIRE-polygon containing this point has no addresses contained** corresponds - with _embedding_object:id - =false - -### uk_addresses_import_button - -_This tagrendering has no question and is thus read-only_ - -This document is autogenerated from assets/layers/to_import/to_import.json \ No newline at end of file diff --git a/Docs/Layers/toekomstige_fietsstraat.md b/Docs/Layers/toekomstige_fietsstraat.md index d411f8e986..207964b304 100644 --- a/Docs/Layers/toekomstige_fietsstraat.md +++ b/Docs/Layers/toekomstige_fietsstraat.md @@ -1,4 +1,6 @@ -toekomstige_fietsstraat + + + toekomstige_fietsstraat ========================= @@ -7,38 +9,115 @@ toekomstige_fietsstraat This street will become a cyclestreet soon -## Table of contents - -1. [toekomstige_fietsstraat](#toekomstige_fietsstraat) - * [Themes using this layer](#themes-using-this-layer) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [images](#images) - -#### Themes using this layer - -- [cyclestreets](https://mapcomplete.osm.be/cyclestreets) - -[Go to the source code](../assets/layers/toekomstige_fietsstraat/toekomstige_fietsstraat.json) -Basic tags for this layer + + + - This layer is shown at zoomlevel **9** and higher + + + + +#### Themes using this layer + + + + + + - [cyclestreets](https://mapcomplete.osm.be/cyclestreets) + + + + + Basic tags for this layer --------------------------- Elements must have the all of following tags to be shown on this layer: -- proposed:cyclestreet - =yes -Supported attributes + + - proposed:cyclestreet=yes + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22proposed%3Acyclestreet%22%3D%22yes%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes ---------------------- -### images + + +**Warning** This quick overview is incomplete + + + +attribute | type | values which are supported by this layer +----------- | ------ | ------------------------------------------ +[](https://taginfo.openstreetmap.org/keys/cyclestreet#values) [cyclestreet](https://wiki.openstreetmap.org/wiki/Key:cyclestreet) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:cyclestreet%3Dyes) [yes](https://wiki.openstreetmap.org/wiki/Tag:cyclestreet%3Dyes) [](https://wiki.openstreetmap.org/wiki/Tag:cyclestreet%3D) [](https://wiki.openstreetmap.org/wiki/Tag:cyclestreet%3D) +[](https://taginfo.openstreetmap.org/keys/cyclestreet:start_date#values) [cyclestreet:start_date](https://wiki.openstreetmap.org/wiki/Key:cyclestreet:start_date) | [date](../SpecialInputElements.md#date) | + + + + +### images + + _This tagrendering has no question and is thus read-only_ -This document is autogenerated from assets/layers/toekomstige_fietsstraat/toekomstige_fietsstraat.json \ No newline at end of file + + + + +### is_cyclestreet + + + +The question is **Is the street {name} a cyclestreet?** + + + + + + - **This street is a cyclestreet (and has a speed limit of 30 km/h)** corresponds with cyclestreet=yes&maxspeed=30&overtaking:motor_vehicle=no + - **This street is a cyclestreet** corresponds with cyclestreet=yes + - **This street will become a cyclstreet soon** corresponds with proposed:cyclestreet=yes + - **This street is not a cyclestreet** corresponds with + + + + +### future_cyclestreet + + + +The question is **When will this street become a cyclestreet?** + +This rendering asks information about the property [cyclestreet:start_date](https://wiki.openstreetmap.org/wiki/Key:cyclestreet:start_date) +This is rendered with `This street will become a cyclestreet at {cyclestreet:start_date}` + + + +### questions + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### minimap + + + +_This tagrendering has no question and is thus read-only_ + + + +This document is autogenerated from [assets/themes/cyclestreets/cyclestreets.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/cyclestreets/cyclestreets.json) \ No newline at end of file diff --git a/Docs/Layers/toilet.md b/Docs/Layers/toilet.md index ed17f345ab..eef814a450 100644 --- a/Docs/Layers/toilet.md +++ b/Docs/Layers/toilet.md @@ -12,32 +12,9 @@ A layer showing (public) toilets -## Table of contents - -1. [toilet](#toilet) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [toilet-access](#toilet-access) - + [toilets-fee](#toilets-fee) - + [toilet-charge](#toilet-charge) - + [payment-options](#payment-options) - + [Opening-hours](#opening-hours) - + [toilets-wheelchair](#toilets-wheelchair) - + [toilets-type](#toilets-type) - + [toilets-changing-table](#toilets-changing-table) - + [toilet-changing_table:location](#toilet-changing_tablelocation) - + [toilet-handwashing](#toilet-handwashing) - + [toilet-has-paper](#toilet-has-paper) - + [level](#level) - + [description](#description) - - - - + - This layer is shown at zoomlevel **12** and higher @@ -53,8 +30,6 @@ A layer showing (public) toilets - [toilets](https://mapcomplete.osm.be/toilets) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/toilet/toilet.json) - Basic tags for this layer diff --git a/Docs/Layers/toursistic_places_without_etymology.md b/Docs/Layers/toursistic_places_without_etymology.md new file mode 100644 index 0000000000..bbc3402fc5 --- /dev/null +++ b/Docs/Layers/toursistic_places_without_etymology.md @@ -0,0 +1,162 @@ + + + toursistic_places_without_etymology +===================================== + + + + + +All objects which have an etymology known + + + + + + + - This layer is shown at zoomlevel **18** and higher + + + + +#### Themes using this layer + + + + + + - [etymology](https://mapcomplete.osm.be/etymology) + + + + + Basic tags for this layer +--------------------------- + + + +Elements must have the all of following tags to be shown on this layer: + + + + - name~^..*$ + - tourism=aquarium|tourism=museum|tourism=theme_park|tourism=zoo + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22tourism%22%3D%22aquarium%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22tourism%22%3D%22museum%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22tourism%22%3D%22theme_park%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A%20%20%20%20nwr%5B%22tourism%22%3D%22zoo%22%5D%5B%22name%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes +---------------------- + + + +**Warning** This quick overview is incomplete + + + +attribute | type | values which are supported by this layer +----------- | ------ | ------------------------------------------ +[](https://taginfo.openstreetmap.org/keys/name:etymology:wikidata#values) [name:etymology:wikidata](https://wiki.openstreetmap.org/wiki/Key:name:etymology:wikidata) | [wikidata](../SpecialInputElements.md#wikidata) | +[](https://taginfo.openstreetmap.org/keys/name:etymology#values) [name:etymology](https://wiki.openstreetmap.org/wiki/Key:name:etymology) | [string](../SpecialInputElements.md#string) | [unknown](https://wiki.openstreetmap.org/wiki/Tag:name:etymology%3Dunknown) + + + + +### etymology-images-from-wikipedia + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### wikipedia-etymology + + + +The question is **What is the Wikidata-item that this object is named after?** + +This rendering asks information about the property [name:etymology:wikidata](https://wiki.openstreetmap.org/wiki/Key:name:etymology:wikidata) +This is rendered with `

Wikipedia article of the name giver

{wikipedia(name:etymology:wikidata):max-height:20rem}` + + + +### zoeken op inventaris onroerend erfgoed + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### simple etymology + + + +The question is **What is this object named after?
This might be written on the street name sign** + +This rendering asks information about the property [name:etymology](https://wiki.openstreetmap.org/wiki/Key:name:etymology) +This is rendered with `Named after {name:etymology}` + + + + - **The origin of this name is unknown in all literature** corresponds with name:etymology=unknown + + + + +### questions + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### street-name-sign-image + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### minimap + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### etymology_multi_apply + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### wikipedia + + + +_This tagrendering has no question and is thus read-only_ + + + +This document is autogenerated from [assets/themes/etymology/etymology.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/etymology/etymology.json) \ No newline at end of file diff --git a/Docs/Layers/town_hall.md b/Docs/Layers/town_hall.md deleted file mode 100644 index 54230f32a6..0000000000 --- a/Docs/Layers/town_hall.md +++ /dev/null @@ -1,41 +0,0 @@ -town_hall -=========== - - - - - -## Table of contents - -1. [town_hall](#town_hall) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - - -- This layer will automatically load [postal_code_boundary](./postal_code_boundary.md) into the layout as it depends - on it: A calculated tag loads features from this layer (calculatedTag[0] which calculates the value for _ - postal_code_properties) - -[Go to the source code](../assets/layers/town_hall/town_hall.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- amenity - =townhall - |building - =church - -Supported attributes ----------------------- - - - -This document is autogenerated from assets/layers/town_hall/town_hall.json \ No newline at end of file diff --git a/Docs/Layers/trail.md b/Docs/Layers/trail.md index 6d37dd4b2a..e73b829440 100644 --- a/Docs/Layers/trail.md +++ b/Docs/Layers/trail.md @@ -12,25 +12,9 @@ Aangeduide wandeltochten -## Table of contents - -1. [trail](#trail) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [trail-length](#trail-length) - + [Name](#name) - + [Operator tag](#operator-tag) - + [Color](#color) - + [Wheelchair access](#wheelchair-access) - + [pushchair access](#pushchair-access) - - - - + - This layer is shown at zoomlevel **12** and higher @@ -44,8 +28,6 @@ Aangeduide wandeltochten - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/trail/trail.json) - Basic tags for this layer diff --git a/Docs/Layers/tree_node.md b/Docs/Layers/tree_node.md index 459e75a4e8..a182942ac9 100644 --- a/Docs/Layers/tree_node.md +++ b/Docs/Layers/tree_node.md @@ -12,27 +12,9 @@ A layer showing trees -## Table of contents - -1. [tree_node](#tree_node) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [tree-height](#tree-height) - + [tree-leaf_type](#tree-leaf_type) - + [tree-denotation](#tree-denotation) - + [tree-decidouous](#tree-decidouous) - + [tree_node-name](#tree_node-name) - + [tree-heritage](#tree-heritage) - + [tree_node-ref:OnroerendErfgoed](#tree_node-refonroerenderfgoed) - + [tree_node-wikidata](#tree_node-wikidata) - - - - + - This layer is shown at zoomlevel **16** and higher @@ -47,8 +29,6 @@ A layer showing trees - [trees](https://mapcomplete.osm.be/trees) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/tree_node/tree_node.json) - Basic tags for this layer diff --git a/Docs/Layers/type_node.md b/Docs/Layers/type_node.md deleted file mode 100644 index d584c121f5..0000000000 --- a/Docs/Layers/type_node.md +++ /dev/null @@ -1,42 +0,0 @@ -type_node -=========== - - - - - -This is a priviliged meta_layer which exports _every_ point in OSM. This only works if zoomed below the point that the -full tile is loaded (and not loaded via Overpass). Note that this point will also contain a property `parent_ways` which -contains all the ways this node is part of as a list. This is mainly used for extremely specialized themes, which do -advanced conflations. Expert use only. - -## Table of contents - -1. [type_node](#type_node) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - - -- Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` -- This layer is needed as dependency for layer [grb](#grb) - -[Go to the source code](../assets/layers/type_node/type_node.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- id~^node\/.*$ - -Supported attributes ----------------------- - - - -This document is autogenerated from assets/layers/type_node/type_node.json \ No newline at end of file diff --git a/Docs/Layers/viewpoint.md b/Docs/Layers/viewpoint.md index 1eef4684b9..b2bac8d415 100644 --- a/Docs/Layers/viewpoint.md +++ b/Docs/Layers/viewpoint.md @@ -12,20 +12,9 @@ A nice viewpoint or nice view. Ideal to add an image if no other category fits -## Table of contents - -1. [viewpoint](#viewpoint) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [viewpoint-description](#viewpoint-description) - - - - + - This layer is shown at zoomlevel **14** and higher @@ -39,8 +28,6 @@ A nice viewpoint or nice view. Ideal to add an image if no other category fits - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/viewpoint/viewpoint.json) - Basic tags for this layer diff --git a/Docs/Layers/village_green.md b/Docs/Layers/village_green.md index 626b753d6c..f38e8d236d 100644 --- a/Docs/Layers/village_green.md +++ b/Docs/Layers/village_green.md @@ -12,21 +12,9 @@ A layer showing village-green (which are communal green areas, but not quite par -## Table of contents - -1. [village_green](#village_green) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [village_green-explanation](#village_green-explanation) - + [village_green-reviews](#village_green-reviews) - - - - + - This layer is shown at zoomlevel **0** and higher @@ -40,8 +28,6 @@ A layer showing village-green (which are communal green areas, but not quite par - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/village_green/village_green.json) - Basic tags for this layer diff --git a/Docs/Layers/visitor_information_centre.md b/Docs/Layers/visitor_information_centre.md index 513aa11463..932e14c08d 100644 --- a/Docs/Layers/visitor_information_centre.md +++ b/Docs/Layers/visitor_information_centre.md @@ -12,18 +12,9 @@ A visitor center offers information about a specific attraction or place of inte -## Table of contents - -1. [visitor_information_centre](#visitor_information_centre) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - - - - + - This layer is shown at zoomlevel **12** and higher @@ -37,8 +28,6 @@ A visitor center offers information about a specific attraction or place of inte - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/visitor_information_centre/visitor_information_centre.json) - Basic tags for this layer diff --git a/Docs/Layers/walking_routes.md b/Docs/Layers/walking_routes.md deleted file mode 100644 index 81cf103077..0000000000 --- a/Docs/Layers/walking_routes.md +++ /dev/null @@ -1,111 +0,0 @@ -walking_routes -================ - - - - - -Walking routes by 'provincie Antwerpen' - -## Table of contents - -1. [walking_routes](#walking_routes) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [walk-length](#walk-length) - + [walk-type](#walk-type) - + [walk-description](#walk-description) - + [walk-operator](#walk-operator) - + [walk-operator-email](#walk-operator-email) - + [questions](#questions) - + [reviews](#reviews) - - -- Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` -- This layer is loaded from an external source, namely `https://raw.githubusercontent.com/pietervdvn/MapComplete-data/main/speelplekken_cache/speelplekken_{layer}_{z}_{x}_{y}.geojson` - -[Go to the source code](../assets/layers/walking_routes/walking_routes.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- type - =route -- route - =foot -- operator~^[pP]rovincie Antwerpen$ - -Supported attributes ----------------------- - - - -**Warning** This quick overview is incomplete - -attribute | type | values which are supported by this layer ------------ | ------ | ------------------------------------------ -[](https://taginfo.openstreetmap.org/keys/route#values) [route](https://wiki.openstreetmap.org/wiki/Key:route) | Multiple choice | [iwn](https://wiki.openstreetmap.org/wiki/Tag:route%3Diwn) [nwn](https://wiki.openstreetmap.org/wiki/Tag:route%3Dnwn) [rwn](https://wiki.openstreetmap.org/wiki/Tag:route%3Drwn) [lwn](https://wiki.openstreetmap.org/wiki/Tag:route%3Dlwn) -[](https://taginfo.openstreetmap.org/keys/description#values) [description](https://wiki.openstreetmap.org/wiki/Key:description) | [text](../SpecialInputElements.md#text) | -[](https://taginfo.openstreetmap.org/keys/operator#values) [operator](https://wiki.openstreetmap.org/wiki/Key:operator) | [string](../SpecialInputElements.md#string) | -[](https://taginfo.openstreetmap.org/keys/operator:email#values) [operator:email](https://wiki.openstreetmap.org/wiki/Key:operator:email) | [email](../SpecialInputElements.md#email) | - -### walk-length - -_This tagrendering has no question and is thus read-only_ - -### walk-type - -_This tagrendering has no question and is thus read-only_ - -- **Dit is een internationale wandelroute** corresponds - with route - =iwn -- **Dit is een nationale wandelroute** corresponds - with route - =nwn -- **Dit is een regionale wandelroute** corresponds - with route - =rwn -- **Dit is een lokale wandelroute** corresponds - with route - =lwn - -### walk-description - -The question is **Geef een korte beschrijving van de wandeling (max 255 tekens)** - -This rendering asks information about the property [description](https://wiki.openstreetmap.org/wiki/Key:description) -This is rendered with `

Korte beschrijving:

{description}` - -### walk-operator - -The question is **Wie beheert deze wandeling en plaatst dus de signalisatiebordjes?** - -This rendering asks information about the property [operator](https://wiki.openstreetmap.org/wiki/Key:operator) -This is rendered with `Signalisatie geplaatst door {operator}` - -### walk-operator-email - -The question is **Naar wie kan men emailen bij problemen rond signalisatie?** - -This rendering asks information about the -property [operator:email](https://wiki.openstreetmap.org/wiki/Key:operator:email) -This is rendered -with `Bij problemen met signalisatie kan men emailen naar {operator:email}` - -### questions - -_This tagrendering has no question and is thus read-only_ - -### reviews - -_This tagrendering has no question and is thus read-only_ - -This document is autogenerated from assets/layers/walking_routes/walking_routes.json \ No newline at end of file diff --git a/Docs/Layers/walls_and_buildings.md b/Docs/Layers/walls_and_buildings.md index 9d4ed1e8b6..bb24335506 100644 --- a/Docs/Layers/walls_and_buildings.md +++ b/Docs/Layers/walls_and_buildings.md @@ -12,17 +12,9 @@ Special builtin layer providing all walls and buildings. This layer is useful in -## Table of contents - -1. [walls_and_buildings](#walls_and_buildings) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - - - + - This layer is shown at zoomlevel **18** and higher - This layer is not visible by default and must be enabled in the filter by the user. - Not visible in the layer selection by default. If you want to make this layer toggable, override `name` - Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` @@ -45,8 +37,6 @@ Special builtin layer providing all walls and buildings. This layer is useful in - [surveillance](https://mapcomplete.osm.be/surveillance) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/walls_and_buildings/walls_and_buildings.json) - Basic tags for this layer diff --git a/Docs/Layers/waste_basket.md b/Docs/Layers/waste_basket.md index 300dea778f..a8386f4194 100644 --- a/Docs/Layers/waste_basket.md +++ b/Docs/Layers/waste_basket.md @@ -12,20 +12,9 @@ This is a public waste basket, thrash can, where you can throw away your thrash. -## Table of contents - -1. [waste_basket](#waste_basket) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [waste-basket-waste-types](#waste-basket-waste-types) - + [dispensing_dog_bags](#dispensing_dog_bags) - - - - + - This layer is shown at zoomlevel **17** and higher @@ -41,8 +30,6 @@ This is a public waste basket, thrash can, where you can throw away your thrash. - [waste_basket](https://mapcomplete.osm.be/waste_basket) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/waste_basket/waste_basket.json) - Basic tags for this layer diff --git a/Docs/Layers/waste_disposal.md b/Docs/Layers/waste_disposal.md index 1af2b86e4b..e045ca33f0 100644 --- a/Docs/Layers/waste_disposal.md +++ b/Docs/Layers/waste_disposal.md @@ -12,20 +12,9 @@ Waste Disposal Bin, medium to large bin for disposal of (household) waste -## Table of contents - -1. [waste_disposal](#waste_disposal) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [access](#access) - + [disposal-location](#disposal-location) - - - - + - This layer is shown at zoomlevel **18** and higher @@ -40,8 +29,6 @@ Waste Disposal Bin, medium to large bin for disposal of (household) waste - [waste](https://mapcomplete.osm.be/waste) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/waste_disposal/waste_disposal.json) - Basic tags for this layer diff --git a/Docs/Layers/watermill.md b/Docs/Layers/watermill.md index f3ad0ce21f..6d1e624eb9 100644 --- a/Docs/Layers/watermill.md +++ b/Docs/Layers/watermill.md @@ -12,21 +12,9 @@ Watermolens -## Table of contents - -1. [watermill](#watermill) - * [Themes using this layer](#themes-using-this-layer) - - [Basic tags for this layer](#basic-tags-for-this-layer) - - [Supported attributes](#supported-attributes) - + [images](#images) - + [Access tag](#access-tag) - + [Operator tag](#operator-tag) - - - - + - This layer is shown at zoomlevel **12** and higher @@ -40,8 +28,6 @@ Watermolens - [personal](https://mapcomplete.osm.be/personal) -[Go to the source code](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/watermill/watermill.json) - Basic tags for this layer diff --git a/Docs/Layers/windturbine.md b/Docs/Layers/windturbine.md index f8873bf9ef..110fe27418 100644 --- a/Docs/Layers/windturbine.md +++ b/Docs/Layers/windturbine.md @@ -1,96 +1,150 @@ -windturbine + + + windturbine ============= -## Table of contents - -1. [windturbine](#windturbine) - * [Themes using this layer](#themes-using-this-layer) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - + [turbine-output](#turbine-output) - + [turbine-operator](#turbine-operator) - + [turbine-height](#turbine-height) - + [turbine-diameter](#turbine-diameter) - + [turbine-start-date](#turbine-start-date) - + [images](#images) - -#### Themes using this layer - -- [openwindpowermap](https://mapcomplete.osm.be/openwindpowermap) - -[Go to the source code](../assets/layers/windturbine/windturbine.json) -Basic tags for this layer + + + - This layer is shown at zoomlevel **10** and higher + + + + +#### Themes using this layer + + + + + + - [openwindpowermap](https://mapcomplete.osm.be/openwindpowermap) + + + + + Basic tags for this layer --------------------------- Elements must have the all of following tags to be shown on this layer: -- generator:source - =wind -Supported attributes + + - generator:source=wind + + +[Execute on overpass](http://overpass-turbo.eu/?Q=%5Bout%3Ajson%5D%5Btimeout%3A90%5D%3B(%20%20%20%20nwr%5B%22generator%3Asource%22%3D%22wind%22%5D(%7B%7Bbbox%7D%7D)%3B%0A)%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B) + + + + Supported attributes ---------------------- **Warning** This quick overview is incomplete + + attribute | type | values which are supported by this layer ----------- | ------ | ------------------------------------------ -[](https://taginfo.openstreetmap.org/keys/generator:output:electricity#values) [generator:output:electricity](https://wiki.openstreetmap.org/wiki/Key:generator:output:electricity) | [pfloat](../SpecialInputElements.md#pfloat) | -[](https://taginfo.openstreetmap.org/keys/operator#values) [operator](https://wiki.openstreetmap.org/wiki/Key:operator) | [string](../SpecialInputElements.md#string) | -[](https://taginfo.openstreetmap.org/keys/height#values) [height](https://wiki.openstreetmap.org/wiki/Key:height) | [pfloat](../SpecialInputElements.md#pfloat) | -[](https://taginfo.openstreetmap.org/keys/rotor:diameter#values) [rotor:diameter](https://wiki.openstreetmap.org/wiki/Key:rotor:diameter) | [float](../SpecialInputElements.md#float) | -[](https://taginfo.openstreetmap.org/keys/start_date#values) [start_date](https://wiki.openstreetmap.org/wiki/Key:start_date) | [date](../SpecialInputElements.md#date) | +[](https://taginfo.openstreetmap.org/keys/generator:output:electricity#values) [generator:output:electricity](https://wiki.openstreetmap.org/wiki/Key:generator:output:electricity) | [pfloat](../SpecialInputElements.md#pfloat) | +[](https://taginfo.openstreetmap.org/keys/operator#values) [operator](https://wiki.openstreetmap.org/wiki/Key:operator) | [string](../SpecialInputElements.md#string) | +[](https://taginfo.openstreetmap.org/keys/height#values) [height](https://wiki.openstreetmap.org/wiki/Key:height) | [pfloat](../SpecialInputElements.md#pfloat) | +[](https://taginfo.openstreetmap.org/keys/rotor:diameter#values) [rotor:diameter](https://wiki.openstreetmap.org/wiki/Key:rotor:diameter) | [float](../SpecialInputElements.md#float) | +[](https://taginfo.openstreetmap.org/keys/start_date#values) [start_date](https://wiki.openstreetmap.org/wiki/Key:start_date) | [date](../SpecialInputElements.md#date) | + + + + +### turbine-output + -### turbine-output The question is **What is the power output of this wind turbine? (e.g. 2.3 MW)** -This rendering asks information about the -property [generator:output:electricity](https://wiki.openstreetmap.org/wiki/Key:generator:output:electricity) +This rendering asks information about the property [generator:output:electricity](https://wiki.openstreetmap.org/wiki/Key:generator:output:electricity) This is rendered with `The power output of this wind turbine is {generator:output:electricity}.` -### turbine-operator + + +### turbine-operator + + The question is **Who operates this wind turbine?** -This rendering asks information about the property [operator](https://wiki.openstreetmap.org/wiki/Key:operator) +This rendering asks information about the property [operator](https://wiki.openstreetmap.org/wiki/Key:operator) This is rendered with `This wind turbine is operated by {operator}.` -### turbine-height + + +### turbine-height + + The question is **What is the total height of this wind turbine (including rotor radius), in metres?** -This rendering asks information about the property [height](https://wiki.openstreetmap.org/wiki/Key:height) +This rendering asks information about the property [height](https://wiki.openstreetmap.org/wiki/Key:height) This is rendered with `The total height (including rotor radius) of this wind turbine is {height} metres.` -### turbine-diameter + + +### turbine-diameter + + The question is **What is the rotor diameter of this wind turbine, in metres?** -This rendering asks information about the -property [rotor:diameter](https://wiki.openstreetmap.org/wiki/Key:rotor:diameter) +This rendering asks information about the property [rotor:diameter](https://wiki.openstreetmap.org/wiki/Key:rotor:diameter) This is rendered with `The rotor diameter of this wind turbine is {rotor:diameter} metres.` -### turbine-start-date + + +### turbine-start-date + + The question is **When did this wind turbine go into operation?** -This rendering asks information about the property [start_date](https://wiki.openstreetmap.org/wiki/Key:start_date) +This rendering asks information about the property [start_date](https://wiki.openstreetmap.org/wiki/Key:start_date) This is rendered with `This wind turbine went into operation on/in {start_date}.` -### images + + +### images + + _This tagrendering has no question and is thus read-only_ -This document is autogenerated from assets/layers/windturbine/windturbine.json \ No newline at end of file + + + + +### questions + + + +_This tagrendering has no question and is thus read-only_ + + + + + +### minimap + + + +_This tagrendering has no question and is thus read-only_ + + + +This document is autogenerated from [assets/themes/openwindpowermap/openwindpowermap.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/openwindpowermap/openwindpowermap.json) \ No newline at end of file diff --git a/Docs/Layers/wrong_postal_code.md b/Docs/Layers/wrong_postal_code.md deleted file mode 100644 index 572aaedfb8..0000000000 --- a/Docs/Layers/wrong_postal_code.md +++ /dev/null @@ -1,34 +0,0 @@ -wrong_postal_code -=================== - -## Table of contents - -1. [wrong_postal_code](#wrong_postal_code) - -- [Basic tags for this layer](#basic-tags-for-this-layer) -- [Supported attributes](#supported-attributes) - - -- Not visible in the layer selection by default. If you want to make this layer toggable, override `name` -- Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings` - -[Go to the source code](../assets/layers/wrong_postal_code/wrong_postal_code.json) - - - -Basic tags for this layer ---------------------------- - - - -Elements must have the all of following tags to be shown on this layer: - -- boundary~^..*$ -- addr:postcode~^..*$ - -Supported attributes ----------------------- - - - -This document is autogenerated from assets/layers/wrong_postal_code/wrong_postal_code.json \ No newline at end of file diff --git a/Models/ThemeConfig/LayerConfig.ts b/Models/ThemeConfig/LayerConfig.ts index 05e2e418d2..6608ecfe76 100644 --- a/Models/ThemeConfig/LayerConfig.ts +++ b/Models/ThemeConfig/LayerConfig.ts @@ -335,6 +335,8 @@ export default class LayerConfig extends WithContextLoader { neededLayer: string; }[], addedByDefault = false, canBeIncluded = true): BaseUIElement { const extraProps = [] + + extraProps.push("This layer is shown at zoomlevel **"+this.minzoom+"** and higher") if (canBeIncluded) { if (addedByDefault) { @@ -439,9 +441,6 @@ export default class LayerConfig extends WithContextLoader { new List(extraProps), ...usingLayer, - new Link("Go to the source code", - `https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/${this.id}/${this.id}.json`), - new Title("Basic tags for this layer", 2), "Elements must have the all of following tags to be shown on this layer:", new List(neededTags.map(t => t.asHumanString(true, false, {}))), diff --git a/assets/themes/etymology.json b/assets/themes/etymology/etymology.json similarity index 100% rename from assets/themes/etymology.json rename to assets/themes/etymology/etymology.json diff --git a/scripts/generateDocs.ts b/scripts/generateDocs.ts index 4d43d5c027..de9a995c96 100644 --- a/scripts/generateDocs.ts +++ b/scripts/generateDocs.ts @@ -1,7 +1,7 @@ import Combine from "../UI/Base/Combine"; import BaseUIElement from "../UI/BaseUIElement"; import Translations from "../UI/i18n/Translations"; -import {existsSync, writeFileSync} from "fs"; +import {existsSync, mkdir, mkdirSync, writeFileSync} from "fs"; import {AllKnownLayouts} from "../Customizations/AllKnownLayouts"; import TableOfContents from "../UI/Base/TableOfContents"; import SimpleMetaTaggers, {SimpleMetaTagger} from "../Logic/SimpleMetaTagger"; @@ -18,7 +18,9 @@ import ScriptUtils from "./ScriptUtils"; import List from "../UI/Base/List"; import SharedTagRenderings from "../Customizations/SharedTagRenderings"; -function WriteFile(filename, html: BaseUIElement, autogenSource: string[]): void { +function WriteFile(filename, html: BaseUIElement, autogenSource: string[], options?: { + noTableOfContents: boolean +}): void { for (const source of autogenSource) { @@ -30,7 +32,7 @@ function WriteFile(filename, html: BaseUIElement, autogenSource: string[]): void } } - if (html instanceof Combine) { + if (html instanceof Combine && !(options?.noTableOfContents)) { const toc = new TableOfContents(html); const els = html.getElements(); html = new Combine( @@ -51,9 +53,16 @@ function WriteFile(filename, html: BaseUIElement, autogenSource: string[]): void } console.log("Starting documentation generation...") -AllKnownLayouts.GenOverviewsForSingleLayer((layer, element) => { +AllKnownLayouts.GenOverviewsForSingleLayer((layer, element, inlineSource) => { console.log("Exporting ", layer.id) - WriteFile("./Docs/Layers/" + layer.id + ".md", element, [`assets/layers/${layer.id}/${layer.id}.json`]) + if(!existsSync("./Docs/Layers")){ + mkdirSync("./Docs/Layers") + } + let source: string = `assets/layers/${layer.id}/${layer.id}.json` + if(inlineSource !== undefined){ + source = `assets/themes/${inlineSource}/${inlineSource}.json` + } + WriteFile("./Docs/Layers/" + layer.id + ".md", element, [source], {noTableOfContents: true}) }) WriteFile("./Docs/SpecialRenderings.md", SpecialVisualizations.HelpMessage(), ["UI/SpecialVisualizations.ts"]) From a9aff5e16ea26b7706eea11e88ca5531f98ed95f Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 6 Apr 2022 17:28:51 +0200 Subject: [PATCH 26/37] Add _context key to themes for translations, all strings can now be translated --- Models/ThemeConfig/Conversion/PrepareTheme.ts | 77 ++++++++++++++++++- Models/ThemeConfig/LayerConfig.ts | 1 + UI/i18n/Translation.ts | 9 ++- UI/i18n/Translations.ts | 2 +- Utils.ts | 31 +++++--- .../mapcomplete-changes.json | 4 - .../toerisme_vlaanderen.json | 2 +- 7 files changed, 105 insertions(+), 21 deletions(-) diff --git a/Models/ThemeConfig/Conversion/PrepareTheme.ts b/Models/ThemeConfig/Conversion/PrepareTheme.ts index b563a232a8..be7af4abd5 100644 --- a/Models/ThemeConfig/Conversion/PrepareTheme.ts +++ b/Models/ThemeConfig/Conversion/PrepareTheme.ts @@ -9,6 +9,7 @@ import LayerConfig from "../LayerConfig"; import {TagRenderingConfigJson} from "../Json/TagRenderingConfigJson"; import {SubstitutedTranslation} from "../../../UI/SubstitutedTranslation"; import DependencyCalculator from "../DependencyCalculator"; +import Translations from "../../../UI/i18n/Translations"; class SubstituteLayer extends Conversion<(string | LayerConfigJson), LayerConfigJson[]> { private readonly _state: DesugaringContext; @@ -279,6 +280,72 @@ export class AddMiniMap extends DesugaringStep { } } +class AddContextToTransltionsInLayout extends DesugaringStep { + + constructor() { + super("Adds context to translations, including the prefix 'themes:json.id'; this is to make sure terms in an 'overrides' or inline layer are linkable too",["_context"], "AddContextToTranlationsInLayout"); + } + + convert(json: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors?: string[]; warnings?: string[]; information?: string[] } { + const conversion = new AddContextToTranslations("themes:") + return conversion.convert(json, json.id); + } + +} + +class AddContextToTranslations extends DesugaringStep { + private readonly _prefix: string; + + constructor(prefix = "") { + super("Adds a '_context' to every object that is probably a translation", ["_context"], "AddContextToTranslation"); + this._prefix = prefix; + } + + /** + * const theme = { + * layers: [ + * { + * builtin: ["abc"], + * override: { + * title:{ + * en: "Some title" + * } + * } + * } + * ] + * } + * const rewritten = new AddContextToTranslations("prefix:").convert(theme, "context").result + * const expected = { + * layers: [ + * { + * builtin: ["abc"], + * override: { + * title:{ + * _context: "prefix:context.layers.0.override.title" + * en: "Some title" + * } + * } + * } + * ] + * } + * rewritten // => expected + */ + convert(json: T, context: string): { result: T; errors?: string[]; warnings?: string[]; information?: string[] } { + + const result = Utils.WalkJson(json, (leaf, path) => { + if(typeof leaf === "object"){ + return {...leaf, _context: this._prefix + context+"."+ path.join(".")} + }else{ + return leaf + } + }, obj => obj !== undefined && obj !== null && Translations.isProbablyATranslation(obj)) + + return { + result + }; + } + +} class ApplyOverrideAll extends DesugaringStep { @@ -327,8 +394,13 @@ class AddDependencyLayersToTheme extends DesugaringStep { const dependencies: { neededLayer: string, reason: string, context?: string, neededBy: string }[] = [] for (const layerConfig of alreadyLoaded) { - const layerDeps = DependencyCalculator.getLayerDependencies(new LayerConfig(layerConfig)) - dependencies.push(...layerDeps) + try{ + const layerDeps = DependencyCalculator.getLayerDependencies(new LayerConfig(layerConfig)) + dependencies.push(...layerDeps) + }catch(e){ + console.error(e) + throw "Detecting layer dependencies for "+layerConfig.id+" failed due to "+e + } } for (const dependency of dependencies) { @@ -454,6 +526,7 @@ export class PrepareTheme extends Fuse { constructor(state: DesugaringContext) { super( "Fully prepares and expands a theme", + new AddContextToTransltionsInLayout(), new PreparePersonalTheme(state), new WarnForUnsubstitutedLayersInTheme(), new On("layers", new Concat(new SubstituteLayer(state))), diff --git a/Models/ThemeConfig/LayerConfig.ts b/Models/ThemeConfig/LayerConfig.ts index 6608ecfe76..ce2e56f051 100644 --- a/Models/ThemeConfig/LayerConfig.ts +++ b/Models/ThemeConfig/LayerConfig.ts @@ -27,6 +27,7 @@ import FilterConfigJson from "./Json/FilterConfigJson"; import {And} from "../../Logic/Tags/And"; import {Overpass} from "../../Logic/Osm/Overpass"; import Constants from "../Constants"; +import undefinedError = Mocha.utils.undefinedError; export default class LayerConfig extends WithContextLoader { diff --git a/UI/i18n/Translation.ts b/UI/i18n/Translation.ts index 8e3af95f02..f0504ada66 100644 --- a/UI/i18n/Translation.ts +++ b/UI/i18n/Translation.ts @@ -15,11 +15,15 @@ export class Translation extends BaseUIElement { constructor(translations: object, context?: string) { super() - this.context = context; if (translations === undefined) { console.error("Translation without content at "+context) throw `Translation without content (${context})` } + this.context = translations["_context"] ?? context; + if(translations["_context"] !== undefined){ + translations = {...translations} + delete translations["_context"] + } if (typeof translations === "string") { translations = {"*": translations}; } @@ -28,6 +32,9 @@ export class Translation extends BaseUIElement { if (!translations.hasOwnProperty(translationsKey)) { continue } + if(translationsKey === "_context"){ + continue + } count++; if (typeof (translations[translationsKey]) != "string") { console.error("Non-string object in translation: ", translations[translationsKey]) diff --git a/UI/i18n/Translations.ts b/UI/i18n/Translations.ts index 4f23c89082..482cc7eeb4 100644 --- a/UI/i18n/Translations.ts +++ b/UI/i18n/Translations.ts @@ -107,7 +107,7 @@ export default class Translations { return false } // is a weird key found? - if(Object.keys(transl).some(key => !this.knownLanguages.has(key))){ + if(Object.keys(transl).some(key => key !== '_context' && !this.knownLanguages.has(key))){ return false } diff --git a/Utils.ts b/Utils.ts index 9770e3b3f4..7ee06e1744 100644 --- a/Utils.ts +++ b/Utils.ts @@ -515,41 +515,46 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be } /** - * Apply a function on every leaf of the JSON; used to rewrite parts of the JSON + * Apply a function on every leaf of the JSON; used to rewrite parts of the JSON. + * Returns a modified copy of the original object. + * + * Hangs if the object contains a loop */ - static WalkJson(json: any, f: (v: number | string | boolean | undefined) => any, isLeaf: (object) => boolean = undefined) { + static WalkJson(json: any, f: (v: object | number | string | boolean | undefined, path: string[]) => any, isLeaf: (object) => boolean = undefined, path: string[] = []) { if (json === undefined) { - return f(undefined) + return f(undefined, path) } const jtp = typeof json if (isLeaf !== undefined) { if (jtp === "object") { if (isLeaf(json)) { - return f(json) + return f(json, path) } } else { return json } } else if (jtp === "boolean" || jtp === "string" || jtp === "number") { - return f(json) + return f(json, path) } if (Array.isArray(json)) { - return json.map(sub => { - return Utils.WalkJson(sub, f, isLeaf); + return json.map((sub,i) => { + return Utils.WalkJson(sub, f, isLeaf, [...path,""+i]); }) } const cp = {...json} for (const key in json) { - cp[key] = Utils.WalkJson(json[key], f, isLeaf) + cp[key] = Utils.WalkJson(json[key], f, isLeaf, [...path, key]) } return cp } /** - * Walks an object recursively. Will hang on objects with loops + * Walks an object recursively, will execute the 'collect'-callback on every leaf. + * + * Will hang on objects with loops */ - static WalkObject(json: any, collect: (v: number | string | boolean | undefined, path: string[]) => any, isLeaf: (object) => boolean = undefined, path = []) { + static WalkObject(json: any, collect: (v: number | string | boolean | undefined, path: string[]) => any, isLeaf: (object) => boolean = undefined, path = []): void { if (json === undefined) { return; } @@ -563,12 +568,14 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be return collect(json, path) } } else if (jtp === "boolean" || jtp === "string" || jtp === "number") { - return collect(json, path) + collect(json, path) + return } if (Array.isArray(json)) { - return json.map((sub, i) => { + json.map((sub, i) => { return Utils.WalkObject(sub, collect, isLeaf, [...path, i]); }) + return } for (const key in json) { diff --git a/assets/themes/mapcomplete-changes/mapcomplete-changes.json b/assets/themes/mapcomplete-changes/mapcomplete-changes.json index b03b39e7ad..da73732b30 100644 --- a/assets/themes/mapcomplete-changes/mapcomplete-changes.json +++ b/assets/themes/mapcomplete-changes/mapcomplete-changes.json @@ -231,10 +231,6 @@ "if": "theme=openwindpowermap", "then": "./assets/themes/openwindpowermap/logo.svg" }, - { - "if": "theme=parking-lanes", - "then": "./assets/svg/bug.svg" - }, { "if": "theme=parkings", "then": "./assets/themes/parkings/parkings.svg" diff --git a/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json b/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json index 169d814350..fa0f7383fb 100644 --- a/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json +++ b/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json @@ -50,7 +50,7 @@ ] } }, - "=filter": null, + "filter": null, "=mapRendering": [ { "location": [ From e6f05c8cb530c8ce4b2e5f4d63588e99f34debc1 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Wed, 6 Apr 2022 17:35:47 +0200 Subject: [PATCH 27/37] Clarify contribution policy: no editor-specific files --- CONTRIBUTING.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d514b13b08..cc6fe3a8df 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,3 +53,10 @@ To do this: Alternatively, if you don't have any unmerged changes, you can remove your local copy and clone `pietervdvn/MapComplete` again to start fresh. + +What not to contribute +---------------------- + +I'm currently _not_ accepting files for integration with some editor. There are hundreds of editors out there, if every single one of them needs a file in the repo, this ends up as a mess. +Furthermore, MapComplete doesn't want to encourage or discourage some editors. +At last, these files are hard to maintain and are hard to detect if they have fallen out of use. From 5a94e9d239ca7d87f1fe1650a35ebe2edfad3e49 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 6 Apr 2022 19:16:55 +0200 Subject: [PATCH 28/37] Improvements to the climbing theme --- Models/Denomination.ts | 19 +++++-- UI/Popup/FeatureInfoBox.ts | 6 ++- UI/SubstitutedTranslation.ts | 2 +- UI/i18n/Translation.ts | 1 - assets/themes/climbing/climbing.json | 76 +++++++++++++++------------- css/index-tailwind-output.css | 8 +-- 6 files changed, 65 insertions(+), 47 deletions(-) diff --git a/Models/Denomination.ts b/Models/Denomination.ts index f3722b661e..45b17f2a7b 100644 --- a/Models/Denomination.ts +++ b/Models/Denomination.ts @@ -73,12 +73,25 @@ export class Denomination { * en: "meter" * } * }, "test") - * unit.canonicalValue("42m") // =>"42 m" + * unit.canonicalValue("42m") // =>"42 m" * unit.canonicalValue("42") // =>"42 m" * unit.canonicalValue("42 m") // =>"42 m" * unit.canonicalValue("42 meter") // =>"42 m" * * + * // Should be trimmed if canonical is empty + * const unit = new Denomination({ + * canonicalDenomination: "", + * alternativeDenomination: ["meter","m], + * 'default': true, + * human: { + * en: "meter" + * } + * }, "test") + * unit.canonicalValue("42m") // =>"42" + * unit.canonicalValue("42") // =>"42" + * unit.canonicalValue("42 m") // =>"42" + * unit.canonicalValue("42 meter") // =>"42" */ public canonicalValue(value: string, actAsDefault?: boolean) : string { if (value === undefined) { @@ -89,9 +102,9 @@ export class Denomination { return null; } if (stripped === "1" && this._canonicalSingular !== undefined) { - return "1 " + this._canonicalSingular + return ("1 " + this._canonicalSingular).trim() } - return stripped + " " + this.canonical; + return (stripped + " " + this.canonical).trim(); } /** diff --git a/UI/Popup/FeatureInfoBox.ts b/UI/Popup/FeatureInfoBox.ts index 55f1a0b671..43c56778a8 100644 --- a/UI/Popup/FeatureInfoBox.ts +++ b/UI/Popup/FeatureInfoBox.ts @@ -64,8 +64,10 @@ export default class FeatureInfoBox extends ScrollableFullScreen { const title = new TagRenderingAnswer(tags, layerConfig.title ?? new TagRenderingConfig("POI"), state) .SetClass("break-words font-bold sm:p-0.5 md:p-1 sm:p-1.5 md:p-2 text-2xl"); const titleIcons = new Combine( - layerConfig.titleIcons.map(icon => new TagRenderingAnswer(tags, icon, state, - "block w-8 h-8 max-h-8 align-baseline box-content sm:p-0.5 w-10",) + layerConfig.titleIcons.map(icon => { + return new TagRenderingAnswer(tags, icon, state, + "block h-8 max-h-8 align-baseline box-content sm:p-0.5").SetClass("flex"); + } )) .SetClass("flex flex-row flex-wrap pt-0.5 sm:pt-1 items-center mr-2") diff --git a/UI/SubstitutedTranslation.ts b/UI/SubstitutedTranslation.ts index bccb6e4e2c..856ff2482e 100644 --- a/UI/SubstitutedTranslation.ts +++ b/UI/SubstitutedTranslation.ts @@ -35,7 +35,7 @@ export class SubstitutedTranslation extends VariableUiElement { ) }) - const linkToWeblate = new LinkToWeblate(translation.context, translation.translations) + const linkToWeblate = translation !== undefined ? new LinkToWeblate(translation.context, translation.translations) : undefined; super( Locale.language.map(language => { diff --git a/UI/i18n/Translation.ts b/UI/i18n/Translation.ts index f0504ada66..e9c8157081 100644 --- a/UI/i18n/Translation.ts +++ b/UI/i18n/Translation.ts @@ -131,7 +131,6 @@ export class Translation extends BaseUIElement { const wrapper = document.createElement("span") wrapper.appendChild(el) - wrapper.classList.add("flex") Locale.showLinkToWeblate.addCallbackAndRun(doShow => { if (!doShow) { diff --git a/assets/themes/climbing/climbing.json b/assets/themes/climbing/climbing.json index f48ce9bfa5..cc5af9e786 100644 --- a/assets/themes/climbing/climbing.json +++ b/assets/themes/climbing/climbing.json @@ -143,10 +143,6 @@ }, "id": "climbing_club-name" }, - { - "id": "minimap", - "render": "{minimap(18): height: 5rem; overflow: hidden; border-radius:3rem; }" - }, "website", "email", "phone", @@ -287,11 +283,6 @@ }, "tagRenderings": [ "images", - "questions", - { - "id": "minimap", - "render": "{minimap(18): height: 5rem; overflow: hidden; border-radius:3rem; }" - }, { "render": { "en": "{name}", @@ -320,8 +311,7 @@ "website", "phone", "email", - "opening_hours", - "reviews" + "opening_hours" ], "mapRendering": [ { @@ -397,11 +387,6 @@ }, "tagRenderings": [ "images", - "questions", - { - "id": "minimap", - "render": "{minimap(18): height: 5rem; overflow: hidden; border-radius:3rem; }" - }, { "render": { "en": "{name}", @@ -555,8 +540,7 @@ "key": "_embedding_features_with_rock:rock" }, "id": "Rock type" - }, - "reviews" + } ], "presets": [ { @@ -704,7 +688,6 @@ }, "tagRenderings": [ "images", - "questions", { "id": "minimap", "render": "{minimap(18, id, _contained_climbing_route_ids): height: 9rem; overflow: hidden; border-radius:3rem; }" @@ -846,8 +829,7 @@ ] }, "id": "Rock type (crag/rock/cliff only)" - }, - "reviews" + } ], "presets": [ { @@ -955,10 +937,6 @@ "it": "Un’opportunità di arrampicata?" }, "tagRenderings": [ - { - "id": "minimap", - "render": "{minimap(18): height: 5rem; overflow: hidden; border-radius:3rem; }" - }, { "id": "climbing-opportunity-name", "render": { @@ -1053,26 +1031,50 @@ } ], "overrideAll": { - "titleIcons": [ + "+titleIcons": [ { - "render": "
{climbing:length}m
", - "freeform": { - "key": "climbing:length" - } + "render": "
{climbing:length}m
", + "condition": "climbing:length~*" }, { - "render": "
{climbing:bolted}
", - "freeform": { - "key": "climbing:bolted" - }, "mappings": [ + { + "if": "climbing:bolts~*", + "then": "
{climbing:bolts}
" + }, { "if": "climbing:bolted=yes", "then": "" } ] }, - "defaults" + { + "mappings": [ + { + "if": "climbing:grade:french~3.*", + "then": "
{climbing:grade:french}
" + }, + { + "if": "climbing:grade:french~4.*", + "then": "
{climbing:grade:french}
" + },{ + "if": "climbing:grade:french~5.*", + "then": "
{climbing:grade:french}
" + }, + { + "if": "climbing:grade:french~6.*", + "then": "
{climbing:grade:french}
" + }, + { + "if": "climbing:grade:french~7.*", + "then": "
{climbing:grade:french}
" + }, + { + "if": "climbing:grade:french~*", + "then": "
{climbing:grade:french}
" + } + ] + } ], "+calculatedTags": [ "_embedding_feature_properties=feat.overlapWith('climbing').map(f => f.feat.properties).filter(p => p !== undefined).map(p => {return{access: p.access, id: p.id, name: p.name, climbing: p.climbing, 'access:description': p['access:description']}})", @@ -1690,7 +1692,9 @@ "hideInAnswer": true } ] - } + }, + "questions", + "reviews" ] } } \ No newline at end of file diff --git a/css/index-tailwind-output.css b/css/index-tailwind-output.css index b0527f3239..a41659488f 100644 --- a/css/index-tailwind-output.css +++ b/css/index-tailwind-output.css @@ -1523,10 +1523,6 @@ video { padding-left: 1rem; } -.pl-1 { - padding-left: 0.25rem; -} - .pl-2 { padding-left: 0.5rem; } @@ -1543,6 +1539,10 @@ video { padding-bottom: 0.25rem; } +.pl-1 { + padding-left: 0.25rem; +} + .pr-1 { padding-right: 0.25rem; } From 717f283d942b63bd6758ac5891fbb2cd9c81522b Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 6 Apr 2022 19:17:21 +0200 Subject: [PATCH 29/37] Translation reset --- langs/layers/en.json | 16 ++++++++++++++++ langs/themes/nl.json | 3 --- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/langs/layers/en.json b/langs/layers/en.json index ddeee9e6f5..bef77444dc 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -4409,6 +4409,22 @@ } }, "description": "A shop", + "filter": { + "0": { + "options": { + "0": { + "question": "Only show shops selling {search}" + } + } + }, + "1": { + "options": { + "0": { + "question": "Only show shops with name {search}" + } + } + } + }, "name": "Shop", "presets": { "0": { diff --git a/langs/themes/nl.json b/langs/themes/nl.json index 6d0cbe4236..e793889d5e 100644 --- a/langs/themes/nl.json +++ b/langs/themes/nl.json @@ -860,9 +860,6 @@ "hailhydrant": { "title": "Brandkranen, brandblussers, brandweerposten en ambulanceposten" }, - "mapcomplete-changes": { - "title": "Wijzigingen gemaakt met MapComplete" - }, "maps": { "description": "Op deze kaart kan je alle kaarten zien die OpenStreetMap kent.

Ontbreekt er een kaart, dan kan je die kaart hier ook gemakelijk aan deze kaart toevoegen.", "shortDescription": "Een kaart met alle kaarten die OpenStreetMap kent", From b65ca55b7b2d0860ffd0838f0ecb8179689a64b6 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Thu, 7 Apr 2022 02:55:24 +0200 Subject: [PATCH 30/37] Fix tests --- Models/Denomination.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Models/Denomination.ts b/Models/Denomination.ts index 45b17f2a7b..45f2e5be26 100644 --- a/Models/Denomination.ts +++ b/Models/Denomination.ts @@ -82,7 +82,7 @@ export class Denomination { * // Should be trimmed if canonical is empty * const unit = new Denomination({ * canonicalDenomination: "", - * alternativeDenomination: ["meter","m], + * alternativeDenomination: ["meter","m"], * 'default': true, * human: { * en: "meter" From 6e3dd6a8d58958570e6fba4b080ee78fd7e4ab98 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Thu, 7 Apr 2022 03:14:21 +0200 Subject: [PATCH 31/37] Translation sync --- assets/layers/shops/shops.json | 44 +++++++++++++++---------- assets/themes/climbing/climbing.json | 49 ++++++++++++++-------------- 2 files changed, 51 insertions(+), 42 deletions(-) diff --git a/assets/layers/shops/shops.json b/assets/layers/shops/shops.json index 9f5a32dce7..401fd0c01e 100644 --- a/assets/layers/shops/shops.json +++ b/assets/layers/shops/shops.json @@ -412,29 +412,37 @@ "filter": [ { "id": "shop-type", - "options": [{ - "fields": [{ - "name": "search", - "type": "string" - }], - "osmTags": "shop~^.*{search}.*$", - "question": { - "en": "Only show shops selling {search}" + "options": [ + { + "fields": [ + { + "name": "search", + "type": "string" + } + ], + "osmTags": "shop~^.*{search}.*$", + "question": { + "en": "Only show shops selling {search}" + } } - } ] }, { "id": "shop-name", - "options": [{ - "fields": [{ - "name": "search", - "type": "string" - }], - "osmTags": "name~^.*{search}.*$", - "question": { - "en": "Only show shops with name {search}" + "options": [ + { + "fields": [ + { + "name": "search", + "type": "string" + } + ], + "osmTags": "name~^.*{search}.*$", + "question": { + "en": "Only show shops with name {search}" + } } - }]} + ] + } ] } \ No newline at end of file diff --git a/assets/themes/climbing/climbing.json b/assets/themes/climbing/climbing.json index cc5af9e786..9607011536 100644 --- a/assets/themes/climbing/climbing.json +++ b/assets/themes/climbing/climbing.json @@ -1049,30 +1049,31 @@ ] }, { - "mappings": [ - { - "if": "climbing:grade:french~3.*", - "then": "
{climbing:grade:french}
" - }, - { - "if": "climbing:grade:french~4.*", - "then": "
{climbing:grade:french}
" - },{ - "if": "climbing:grade:french~5.*", - "then": "
{climbing:grade:french}
" - }, - { - "if": "climbing:grade:french~6.*", - "then": "
{climbing:grade:french}
" - }, - { - "if": "climbing:grade:french~7.*", - "then": "
{climbing:grade:french}
" - }, - { - "if": "climbing:grade:french~*", - "then": "
{climbing:grade:french}
" - } + "mappings": [ + { + "if": "climbing:grade:french~3.*", + "then": "
{climbing:grade:french}
" + }, + { + "if": "climbing:grade:french~4.*", + "then": "
{climbing:grade:french}
" + }, + { + "if": "climbing:grade:french~5.*", + "then": "
{climbing:grade:french}
" + }, + { + "if": "climbing:grade:french~6.*", + "then": "
{climbing:grade:french}
" + }, + { + "if": "climbing:grade:french~7.*", + "then": "
{climbing:grade:french}
" + }, + { + "if": "climbing:grade:french~*", + "then": "
{climbing:grade:french}
" + } ] } ], From edb5b06f123eca4a5a2ed774245d47631aee204f Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 8 Apr 2022 01:55:42 +0200 Subject: [PATCH 32/37] Improve layer docs generation --- Models/ThemeConfig/TagRenderingConfig.ts | 12 +++++++++++- UI/Base/FixedUiElement.ts | 3 +++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Models/ThemeConfig/TagRenderingConfig.ts b/Models/ThemeConfig/TagRenderingConfig.ts index b1fcc78aa3..6af7592cd8 100644 --- a/Models/ThemeConfig/TagRenderingConfig.ts +++ b/Models/ThemeConfig/TagRenderingConfig.ts @@ -12,6 +12,7 @@ import Title from "../../UI/Base/Title"; import Link from "../../UI/Base/Link"; import List from "../../UI/Base/List"; import {QuestionableTagRenderingConfigJson} from "./Json/QuestionableTagRenderingConfigJson"; +import {FixedUiElement} from "../../UI/Base/FixedUiElement"; /*** * The parsed version of TagRenderingConfigJSON @@ -533,12 +534,21 @@ export default class TagRenderingConfig { ) ) } + + let condition : BaseUIElement = undefined + if(this.condition !== undefined && !this.condition?.matchesProperties({})){ + condition = new Combine(["Only visible if", + new FixedUiElement( this.condition.asHumanString(false, false, {}) + ).SetClass("code") + , "is shown"]) + } return new Combine([ new Title(this.id, 3), this.question !== undefined ? "The question is **" + this.question.txt + "**" : "_This tagrendering has no question and is thus read-only_", new Combine(withRender), - mappings + mappings, + condition ]).SetClass("flex-col"); } } \ No newline at end of file diff --git a/UI/Base/FixedUiElement.ts b/UI/Base/FixedUiElement.ts index 4600d26ff6..1b2c7c4d3c 100644 --- a/UI/Base/FixedUiElement.ts +++ b/UI/Base/FixedUiElement.ts @@ -13,6 +13,9 @@ export class FixedUiElement extends BaseUIElement { } AsMarkdown(): string { + if(this.HasClass("code")){ + return "`"+this.content+"`" + } return this.content; } From c3f3f69c3bf836447608f69466d83ab9c531446b Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 8 Apr 2022 02:09:46 +0200 Subject: [PATCH 33/37] Small improvements to the GRB theme --- assets/themes/grb_import/grb.json | 33 ++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/assets/themes/grb_import/grb.json b/assets/themes/grb_import/grb.json index 4eb84c7175..699a3e9c7c 100644 --- a/assets/themes/grb_import/grb.json +++ b/assets/themes/grb_import/grb.json @@ -374,7 +374,13 @@ "tagRenderings+": [ { "id": "render_embedded", - "render": "Dit CRAB-adres ligt in OSM-gebouw {_embedding_id}" + "render": "Dit CRAB-adres ligt in OSM-gebouw {_embedding_id}", + "mappings": [{ + "if": "_embedding_id=", + "then": { + "nl": "Geen omliggend OSM-gebouw gevonden" + } + }] }, { "id": "embedded_address", @@ -409,17 +415,30 @@ }, { "id": "import-button", - "render": "{import_button(address, addr:street=$STRAATNM; addr:housenumber=$_HNRLABEL,Voeg dit adres als een nieuw adrespunt toe,,osm-buildings,5)}", + "render": { + "special": { + "type": "import_button", + "targetLayer": "address", + "tags": "addr:street=$STRAATNM; addr:housenumber=$_HNRLABEL", + "text": { + "nl": "Voeg dit adres als een nieuw adrespunt toe" + }, + "snap_onto_layers": "osm-buildings" + } + }, + "mappings": [ + { + "if": "_embedding_id=", + "then": { + "nl": "Geen omliggend OSM-gebouw gevonden. Een omliggend gebouw is nodig om dit punt als adres punt toe te voegen.
Importeer eerst de gebouwen. Vernieuw dan de pagina om losse adressen toe te voegen
" + } + } + ], "condition": { - "and": [ - "_embedding_id!=", - { "or": [ "_embedding_street!:={STRAATNM}", "_embedding_nr!:={_HNRLABEL}" ] - } - ] } } ] From 9238f0f381d733ba6c952ba2d43eb2a071df02db Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 8 Apr 2022 04:18:53 +0200 Subject: [PATCH 34/37] Simplify handling of id rewrites by centralizing them to the changesethandler (which improves testability too), fixes a part of #564 --- Logic/ElementStorage.ts | 23 +++++ Logic/Osm/Actions/ChangeDescription.ts | 104 +++++++++++++++++++++++ Logic/Osm/Actions/CreateNewNodeAction.ts | 16 ---- Logic/Osm/Changes.ts | 33 ++++--- Logic/Osm/ChangesetHandler.ts | 88 +++++++++++-------- Logic/Tags/TagUtils.ts | 62 ++++++++------ Models/Constants.ts | 2 +- 7 files changed, 232 insertions(+), 96 deletions(-) diff --git a/Logic/ElementStorage.ts b/Logic/ElementStorage.ts index b64ac18efc..1ab5dc9bc1 100644 --- a/Logic/ElementStorage.ts +++ b/Logic/ElementStorage.ts @@ -49,6 +49,29 @@ export class ElementStorage { return this._elements.has(id); } + addAlias(oldId: string, newId: string){ + if (newId === undefined) { + // We removed the node/way/relation with type 'type' and id 'oldId' on openstreetmap! + const element = this.getEventSourceById(oldId); + element.data._deleted = "yes" + element.ping(); + return; + } + + if (oldId == newId) { + return undefined; + } + const element = this.getEventSourceById( oldId); + if (element === undefined) { + // Element to rewrite not found, probably a node or relation that is not rendered + return undefined + } + element.data.id = newId; + this.addElementById(newId, element); + this.ContainingFeatures.set(newId, this.ContainingFeatures.get( oldId)) + element.ping(); + } + private addOrGetById(elementId: string, newProperties: any): UIEventSource { if (!this._elements.has(elementId)) { const eventSource = new UIEventSource(newProperties, "tags of " + elementId); diff --git a/Logic/Osm/Actions/ChangeDescription.ts b/Logic/Osm/Actions/ChangeDescription.ts index 42df3f4a04..1346e62011 100644 --- a/Logic/Osm/Actions/ChangeDescription.ts +++ b/Logic/Osm/Actions/ChangeDescription.ts @@ -71,6 +71,110 @@ export interface ChangeDescription { export class ChangeDescriptionTools { + /** + * Rewrites all the ids in a changeDescription + * + * // should rewrite the id of the changed object + * const change = { + * id: -1234, + * type: "node", + * meta:{ + * theme:"test", + * changeType: "answer" + * }, + * tags:[ + * { + * k: "key", + * v: "value" + * } + * ] + * } + * } + * const mapping = new Map([["node/-1234", "node/42"]]) + * const rewritten = ChangeDescriptionTools.rewriteIds(change, mapping) + * rewritten.id // => 42 + * + * // should rewrite ids in nodes of a way + * const change = { + * type: "way", + * id: 789, + * changes: { + * nodes: [-1, -2, -3, 68453], + * coordinates: [] + * }, + * meta:{ + * theme:"test", + * changeType: "create" + * } + * } + * const mapping = new Map([["node/-1", "node/42"],["node/-2", "node/43"],["node/-3", "node/44"]]) + * const rewritten = ChangeDescriptionTools.rewriteIds(change, mapping) + * rewritten.id // => 789 + * rewritten.changes["nodes"] // => [42,43,44, 68453] + * + * // should rewrite ids in relationship members + * const change = { + * type: "way", + * id: 789, + * changes: { + * members: [{type: "way", ref: -1, role: "outer"},{type: "way", ref: 48, role: "outer"}], + * }, + * meta:{ + * theme:"test", + * changeType: "create" + * } + * } + * const mapping = new Map([["way/-1", "way/42"],["node/-2", "node/43"],["node/-3", "node/44"]]) + * const rewritten = ChangeDescriptionTools.rewriteIds(change, mapping) + * rewritten.id // => 789 + * rewritten.changes["members"] // => [{type: "way", ref: 42, role: "outer"},{type: "way", ref: 48, role: "outer"}] + * + */ + public static rewriteIds(change: ChangeDescription, mappings: Map): ChangeDescription { + const key = change.type + "/" + change.id + + const wayHasChangedNode = ((change.changes ?? {})["nodes"] ?? []).some(id => mappings.has("node/" + id)); + const relationHasChangedMembers = ((change.changes ?? {})["members"] ?? []) + .some((obj:{type: string, ref: number}) => mappings.has(obj.type+"/" + obj.ref)); + + const hasSomeChange = mappings.has(key) + || wayHasChangedNode || relationHasChangedMembers + if(hasSomeChange){ + change = {...change} + } + + if (mappings.has(key)) { + const [_, newId] = mappings.get(key).split("/") + change.id = Number.parseInt(newId) + } + if(wayHasChangedNode){ + change.changes = {...change.changes} + change.changes["nodes"] = change.changes["nodes"].map(id => { + const key = "node/"+id + if(!mappings.has(key)){ + return id + } + const [_, newId] = mappings.get(key).split("/") + return Number.parseInt(newId) + }) + } + if(relationHasChangedMembers){ + change.changes = {...change.changes} + change.changes["members"] = change.changes["members"].map( + (obj:{type: string, ref: number}) => { + const key = obj.type+"/"+obj.ref; + if(!mappings.has(key)){ + return obj + } + const [_, newId] = mappings.get(key).split("/") + return {...obj, ref: Number.parseInt(newId)} + } + ) + } + + return change + } + public static getGeojsonGeometry(change: ChangeDescription): any { switch (change.type) { case "node": diff --git a/Logic/Osm/Actions/CreateNewNodeAction.ts b/Logic/Osm/Actions/CreateNewNodeAction.ts index 844463ec11..7a545c7e01 100644 --- a/Logic/Osm/Actions/CreateNewNodeAction.ts +++ b/Logic/Osm/Actions/CreateNewNodeAction.ts @@ -51,22 +51,6 @@ export default class CreateNewNodeAction extends OsmCreateAction { } } - public static registerIdRewrites(mappings: Map) { - const toAdd: [string, number][] = [] - - this.previouslyCreatedPoints.forEach((oldId, key) => { - if (!mappings.has("node/" + oldId)) { - return; - } - - const newId = Number(mappings.get("node/" + oldId).substr("node/".length)) - toAdd.push([key, newId]) - }) - for (const [key, newId] of toAdd) { - CreateNewNodeAction.previouslyCreatedPoints.set(key, newId) - } - } - async CreateChangeDescriptions(changes: Changes): Promise { if (this._reusePreviouslyCreatedPoint) { diff --git a/Logic/Osm/Changes.ts b/Logic/Osm/Changes.ts index 362d12853b..17b93b9ae9 100644 --- a/Logic/Osm/Changes.ts +++ b/Logic/Osm/Changes.ts @@ -2,7 +2,7 @@ import {OsmNode, OsmObject, OsmRelation, OsmWay} from "./OsmObject"; import {UIEventSource} from "../UIEventSource"; import Constants from "../../Models/Constants"; import OsmChangeAction from "./Actions/OsmChangeAction"; -import {ChangeDescription} from "./Actions/ChangeDescription"; +import {ChangeDescription, ChangeDescriptionTools} from "./Actions/ChangeDescription"; import {Utils} from "../../Utils"; import {LocalStorageSource} from "../Web/LocalStorageSource"; import SimpleMetaTagger from "../SimpleMetaTagger"; @@ -142,11 +142,7 @@ export class Changes { this.allChanges.data.push(...changes) this.allChanges.ping() } - - public registerIdRewrites(mappings: Map): void { - CreateNewNodeAction.registerIdRewrites(mappings) - } - + private calculateDistanceToChanges(change: OsmChangeAction, changeDescriptions: ChangeDescription[]) { const locations = this.historicalUserLocations?.features?.data @@ -226,17 +222,6 @@ export class Changes { } console.log("Got the fresh objects!", osmObjects, "pending: ", pending) - const changes: { - newObjects: OsmObject[], - modifiedObjects: OsmObject[] - deletedObjects: OsmObject[] - } = self.CreateChangesetObjects(pending, osmObjects) - if (changes.newObjects.length + changes.deletedObjects.length + changes.modifiedObjects.length === 0) { - console.log("No changes to be made") - return true - } - - const perType = Array.from( Utils.Hist(pending.filter(descr => descr.meta.changeType !== undefined && descr.meta.changeType !== null) .map(descr => descr.meta.changeType)), ([key, count]) => ( @@ -303,7 +288,19 @@ export class Changes { ] await this._changesetHandler.UploadChangeset( - (csId) => Changes.createChangesetFor("" + csId, changes), + (csId, remappings) =>{ + if(remappings.size > 0){ + console.log("Rewriting pending changes from", pending, "with", remappings) + pending = pending.map(ch => ChangeDescriptionTools.rewriteIds(ch, remappings)) + console.log("Result is", pending) + } + const changes: { + newObjects: OsmObject[], + modifiedObjects: OsmObject[] + deletedObjects: OsmObject[] + } = self.CreateChangesetObjects(pending, osmObjects) + return Changes.createChangesetFor("" + csId, changes) + }, metatags, openChangeset ) diff --git a/Logic/Osm/ChangesetHandler.ts b/Logic/Osm/ChangesetHandler.ts index d96ec14b9c..13723c4491 100644 --- a/Logic/Osm/ChangesetHandler.ts +++ b/Logic/Osm/ChangesetHandler.ts @@ -23,6 +23,14 @@ export class ChangesetHandler { private readonly auth: any; private readonly backend: string; + + /** + * Contains previously rewritten IDs + * @private + */ + private readonly _remappings = new Map() + + /** * Use 'osmConnection.CreateChangesetHandler' instead * @param dryRun @@ -50,6 +58,7 @@ export class ChangesetHandler { } + /** * Creates a new list which contains every key at most once * @@ -104,7 +113,7 @@ export class ChangesetHandler { * */ public async UploadChangeset( - generateChangeXML: (csid: number) => string, + generateChangeXML: (csid: number, remappings: Map) => string, extraMetaTags: ChangesetTag[], openChangeset: UIEventSource): Promise { @@ -120,7 +129,7 @@ export class ChangesetHandler { this.userDetails.ping(); } if (this._dryRun.data) { - const changesetXML = generateChangeXML(123456); + const changesetXML = generateChangeXML(123456, this._remappings); console.log("Metatags are", extraMetaTags) console.log(changesetXML); return; @@ -131,7 +140,7 @@ export class ChangesetHandler { try { const csId = await this.OpenChangeset(extraMetaTags) openChangeset.setData(csId); - const changeset = generateChangeXML(csId); + const changeset = generateChangeXML(csId, this._remappings); console.trace("Opened a new changeset (openChangeset.data is undefined):", changeset); const changes = await this.UploadChange(csId, changeset) const hasSpecialMotivationChanges = ChangesetHandler.rewriteMetaTags(extraMetaTags, changes) @@ -162,7 +171,7 @@ export class ChangesetHandler { const rewritings = await this.UploadChange( csId, - generateChangeXML(csId)) + generateChangeXML(csId, this._remappings)) const rewrittenTags = this.RewriteTagsOf(extraMetaTags, rewritings, oldChangesetMeta) await this.UpdateTags(csId, rewrittenTags) @@ -239,57 +248,67 @@ export class ChangesetHandler { } - private handleIdRewrite(node: any, type: string): [string, string] { + /** + * Updates the id in the AllElements store, returns the new ID + * @param node: the XML-element, e.g. + * @param type + * @private + */ + private static parseIdRewrite(node: any, type: string): [string, string] { const oldId = parseInt(node.attributes.old_id.value); if (node.attributes.new_id === undefined) { - // We just removed this point! - const element = this.allElements.getEventSourceById("node/" + oldId); - element.data._deleted = "yes" - element.ping(); - return; + return [type+"/"+oldId, undefined]; } const newId = parseInt(node.attributes.new_id.value); + // The actual mapping const result: [string, string] = [type + "/" + oldId, type + "/" + newId] - if (!(oldId !== undefined && newId !== undefined && - !isNaN(oldId) && !isNaN(newId))) { + if(oldId === newId){ return undefined; } - if (oldId == newId) { - return undefined; - } - const element = this.allElements.getEventSourceById("node/" + oldId); - if (element === undefined) { - // Element to rewrite not found, probably a node or relation that is not rendered - return undefined - } - element.data.id = type + "/" + newId; - this.allElements.addElementById(type + "/" + newId, element); - this.allElements.ContainingFeatures.set(type + "/" + newId, this.allElements.ContainingFeatures.get(type + "/" + oldId)) - element.ping(); return result; } + /** + * Given a diff-result XML of the form + * + * + * + * , + * will: + * + * - create a mapping `{'node/-1' --> "node/9650458521", 'way/-2' --> "way/9650458521"} + * - Call this.changes.registerIdRewrites + * - Call handleIdRewrites as needed + * @param response + * @private + */ private parseUploadChangesetResponse(response: XMLDocument): Map { const nodes = response.getElementsByTagName("node"); - const mappings = new Map() + const mappings : [string, string][]= [] for (const node of Array.from(nodes)) { - const mapping = this.handleIdRewrite(node, "node") + const mapping = ChangesetHandler.parseIdRewrite(node, "node") if (mapping !== undefined) { - mappings.set(mapping[0], mapping[1]) + mappings.push(mapping) } } const ways = response.getElementsByTagName("way"); for (const way of Array.from(ways)) { - const mapping = this.handleIdRewrite(way, "way") + const mapping = ChangesetHandler.parseIdRewrite(way, "way") if (mapping !== undefined) { - mappings.set(mapping[0], mapping[1]) + mappings.push(mapping) } } - this.changes.registerIdRewrites(mappings) - return mappings + for (const mapping of mappings) { + const [oldId, newId] = mapping + this.allElements.addAlias(oldId, newId); + if(newId !== undefined) { + this._remappings.set(mapping[0], mapping[1]) + } + } + return new Map(mappings) } @@ -335,7 +354,6 @@ export class ChangesetHandler { tags: ChangesetTag[]) { tags = ChangesetHandler.removeDuplicateMetaTags(tags) - console.trace("Updating tags of " + csId) const self = this; return new Promise(function (resolve, reject) { @@ -351,7 +369,7 @@ export class ChangesetHandler { ``].join("") }, function (err, response) { if (response === undefined) { - console.log("err", err); + console.error("Updating the tags of changeset "+csId+" failed:", err); reject(err) } else { resolve(response); @@ -397,7 +415,7 @@ export class ChangesetHandler { ``].join("") }, function (err, response) { if (response === undefined) { - console.log("err", err); + console.error("Opening a changeset failed:", err); reject(err) } else { resolve(Number(response)); @@ -421,7 +439,7 @@ export class ChangesetHandler { content: changesetXML }, function (err, response) { if (response == null) { - console.log("err", err); + console.error("Uploading an actual change failed", err); reject(err); } const changes = self.parseUploadChangesetResponse(response); diff --git a/Logic/Tags/TagUtils.ts b/Logic/Tags/TagUtils.ts index a496580ffe..9ff07534f6 100644 --- a/Logic/Tags/TagUtils.ts +++ b/Logic/Tags/TagUtils.ts @@ -11,7 +11,7 @@ import {isRegExp} from "util"; import * as key_counts from "../../assets/key_totals.json" export class TagUtils { - private static keyCounts : {keys: any, tags: any} = key_counts["default"] ?? key_counts + private static keyCounts: { keys: any, tags: any } = key_counts["default"] ?? key_counts private static comparators : [string, (a: number, b: number) => boolean][] = [ @@ -169,23 +169,23 @@ export class TagUtils { /** * Returns wether or not a keys is (probably) a valid key. - * + * * // should accept common keys * TagUtils.isValidKey("name") // => true * TagUtils.isValidKey("image:0") // => true * TagUtils.isValidKey("alt_name") // => true - * + * * // should refuse short keys * TagUtils.isValidKey("x") // => false * TagUtils.isValidKey("xy") // => false - * + * * // should refuse a string with >255 characters * let a255 = "" * for(let i = 0; i < 255; i++) { a255 += "a"; } * a255.length // => 255 * TagUtils.isValidKey(a255) // => true * TagUtils.isValidKey("a"+a255) // => false - * + * * // Should refuse unexpected characters * TagUtils.isValidKey("with space") // => false * TagUtils.isValidKey("some$type") // => false @@ -194,10 +194,10 @@ export class TagUtils { public static isValidKey(key: string): boolean { return key.match(/^[a-z][a-z0-9:_]{2,253}[a-z0-9]$/) !== null } - + /** * Parses a tag configuration (a json) into a TagsFilter - * + * * TagUtils.Tag("key=value") // => new Tag("key", "value") * TagUtils.Tag("key=") // => new Tag("key", "") * TagUtils.Tag("key!=") // => new RegexTag("key", "^..*$") @@ -210,6 +210,9 @@ export class TagUtils { * TagUtils.Tag("xyz!~\\[\\]") // => new RegexTag("xyz", /^\[\]$/, true) * TagUtils.Tag("tags~(^|.*;)amenity=public_bookcase($|;.*)") // => new RegexTag("tags", /(^|.*;)amenity=public_bookcase($|;.*)/) * TagUtils.Tag("service:bicycle:.*~~*") // => new RegexTag(/^service:bicycle:.*$/, /^..*$/) + * + * TagUtils.Tag("xyz<5").matchesProperties({xyz: 4}) // => true + * TagUtils.Tag("xyz<5").matchesProperties({xyz: 5}) // => false */ public static Tag(json: AndOrTagConfigJson | string, context: string = ""): TagsFilter { try { @@ -224,7 +227,7 @@ export class TagUtils { * INLINE sort of the given list */ public static sortFilters(filters: TagsFilter [], usePopularity: boolean): void { - filters.sort((a,b) => TagUtils.order(a, b, usePopularity)) + filters.sort((a, b) => TagUtils.order(a, b, usePopularity)) } public static toString(f: TagsFilter, toplevel = true): string { @@ -236,10 +239,10 @@ export class TagUtils { } else { r = f.asHumanString(false, false, {}) } - if(toplevel){ + if (toplevel) { r = r.trim() } - + return r } @@ -260,8 +263,8 @@ export class TagUtils { } throw "At " + context + ": unrecognized tag" } - - + + const tag = json as string; for (const [operator, comparator] of TagUtils.comparators) { if (tag.indexOf(operator) >= 0) { @@ -272,12 +275,19 @@ export class TagUtils { val = new Date(split[1].trim()).getTime() } - const f = (value: string | undefined) => { + const f = (value: string | number | undefined) => { if (value === undefined) { return false; } - let b = Number(value?.trim()) - if (isNaN(b)) { + let b: number + if (typeof value === "number") { + b = value + } else if (typeof b === "string") { + b = Number(value?.trim()) + } else { + b = Number(value) + } + if (isNaN(b) && typeof value === "string") { b = Utils.ParseDate(value).getTime() if (isNaN(b)) { return false @@ -306,8 +316,8 @@ export class TagUtils { split[1] = "..*" } return new RegexTag( - new RegExp("^"+split[0]+"$"), - new RegExp("^"+ split[1]+"$") + new RegExp("^" + split[0] + "$"), + new RegExp("^" + split[1] + "$") ); } if (tag.indexOf("!:=") >= 0) { @@ -371,32 +381,32 @@ export class TagUtils { } private static GetCount(key: string, value?: string) { - if(key === undefined) { + if (key === undefined) { return undefined } const tag = TagUtils.keyCounts.tags[key] - if(tag !== undefined && tag[value] !== undefined) { + if (tag !== undefined && tag[value] !== undefined) { return tag[value] } return TagUtils.keyCounts.keys[key] } - + private static order(a: TagsFilter, b: TagsFilter, usePopularity: boolean): number { const rta = a instanceof RegexTag const rtb = b instanceof RegexTag - if(rta !== rtb) { + if (rta !== rtb) { // Regex tags should always go at the end: these use a lot of computation at the overpass side, avoiding it is better - if(rta) { + if (rta) { return 1 // b < a - }else { + } else { return -1 } } if (a["key"] !== undefined && b["key"] !== undefined) { - if(usePopularity) { + if (usePopularity) { const countA = TagUtils.GetCount(a["key"], a["value"]) const countB = TagUtils.GetCount(b["key"], b["value"]) - if(countA !== undefined && countB !== undefined) { + if (countA !== undefined && countB !== undefined) { return countA - countB } } @@ -420,5 +430,5 @@ export class TagUtils { } return " (" + joined + ") " } - + } \ No newline at end of file diff --git a/Models/Constants.ts b/Models/Constants.ts index 568f92fdd6..acd68fc7e2 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import {Utils} from "../Utils"; export default class Constants { - public static vNumber = "0.18.0-alpha-2"; + public static vNumber = "0.18.0-alpha-3"; public static ImgurApiKey = '7070e7167f0a25a' public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85" From 55dd4c58eed5305fd2eacc02d2cbf6d2af74673b Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 8 Apr 2022 04:36:00 +0200 Subject: [PATCH 35/37] Some linting issues --- UI/AllThemesGui.ts | 2 +- all_themes_index.ts | 2 +- index.ts | 4 +--- package.json | 2 +- test.ts | 6 ++---- 5 files changed, 6 insertions(+), 10 deletions(-) diff --git a/UI/AllThemesGui.ts b/UI/AllThemesGui.ts index eb5e738f1d..cca64fd567 100644 --- a/UI/AllThemesGui.ts +++ b/UI/AllThemesGui.ts @@ -14,7 +14,7 @@ import {VariableUiElement} from "./Base/VariableUIElement"; import Svg from "../Svg"; export default class AllThemesGui { - constructor() { + setup() { try { new FixedUiElement("").AttachTo("centermessage") diff --git a/all_themes_index.ts b/all_themes_index.ts index 12abde8c54..058a2c3e58 100644 --- a/all_themes_index.ts +++ b/all_themes_index.ts @@ -19,4 +19,4 @@ if (layout !== "") { Utils.DisableLongPresses() document.getElementById("decoration-desktop").remove(); -new AllThemesGui(); \ No newline at end of file +new AllThemesGui().setup(); \ No newline at end of file diff --git a/index.ts b/index.ts index 58a0e54b79..ac75022617 100644 --- a/index.ts +++ b/index.ts @@ -26,7 +26,7 @@ class Init { if (layoutToUse === undefined) { // No layout found - new AllThemesGui() + new AllThemesGui().setup() return; } @@ -37,8 +37,6 @@ class Init { // @ts-ignore window.mapcomplete_state = State.state; new DefaultGUI(State.state, guiState) - - } } diff --git a/package.json b/package.json index df8aa0767c..038b46def1 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "gittag": "ts-node scripts/printVersion.ts | bash", "lint": "tslint --project . -c tslint.json '**.ts' ", "clean:tests": "(find . -type f -name \"*.doctest.ts\" | xargs rm)", - "clean": "rm -rf .cache/ && (find *.html | grep -v \"\\(404\\|index\\|land\\|test\\|preferences\\|customGenerator\\|professional\\|automaton\\|import_helper\\|import_viewer\\|theme\\).html\" | xargs rm) && (ls | grep \"^index_[a-zA-Z_]\\+\\.ts$\" | xargs rm) && (ls | grep \".*.webmanifest$\" | xargs rm)", + "clean": "rm -rf .cache/ && (find *.html | grep -v \"\\(404\\|index\\|land\\|test\\|preferences\\|customGenerator\\|professional\\|automaton\\|import_helper\\|import_viewer\\|theme\\).html\" | xargs rm) && (ls | grep \"^index_[a-zA-Z_-]\\+\\.ts$\" | xargs rm) && (ls | grep \".*.webmanifest$\" | xargs rm)", "generate:dependency-graph": "node_modules/.bin/depcruise --exclude \"^node_modules\" --output-type dot Logic/State/MapState.ts > dependencies.dot && dot dependencies.dot -T svg -o dependencies.svg && rm dependencies.dot", "script": "ts-node" }, diff --git a/test.ts b/test.ts index fdd7f691e8..9a6b02f972 100644 --- a/test.ts +++ b/test.ts @@ -13,8 +13,7 @@ new Combine( try { inp = ValidatedTextField.ForType(key).ConstructInputElement({ feedback, - country: () => "be", - + country: () => "be" }); } catch (e) { console.error(e) @@ -29,5 +28,4 @@ new Combine( ]); } ) -).AttachTo("maindiv") - +).AttachTo("maindiv") \ No newline at end of file From 2f2e58faff87302633721efa4b09f18ab5979d2e Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 8 Apr 2022 17:59:14 +0200 Subject: [PATCH 36/37] Update doctestts, add lint config --- UI/DefaultGUI.ts | 25 ++++++++-------- index.ts | 2 +- package-lock.json | 26 ++++++++++++----- package.json | 4 +-- tslint.json | 72 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 108 insertions(+), 21 deletions(-) create mode 100644 tslint.json diff --git a/UI/DefaultGUI.ts b/UI/DefaultGUI.ts index 3d0e2cacdd..095040c634 100644 --- a/UI/DefaultGUI.ts +++ b/UI/DefaultGUI.ts @@ -33,27 +33,30 @@ import ExtraLinkButton from "./BigComponents/ExtraLinkButton"; * Adds a welcome pane, contorl buttons, ... etc to index.html */ export default class DefaultGUI { - private readonly _guiState: DefaultGuiState; + private readonly guiState: DefaultGuiState; private readonly state: FeaturePipelineState; constructor(state: FeaturePipelineState, guiState: DefaultGuiState) { this.state = state; - this._guiState = guiState; + this.guiState = guiState; - if (state.layoutToUse.customCss !== undefined) { - Utils.LoadCustomCss(state.layoutToUse.customCss); + } + + public setup(){ + if (this.state.layoutToUse.customCss !== undefined) { + Utils.LoadCustomCss(this.state.layoutToUse.customCss); } this.SetupUIElements(); this.SetupMap() - if (state.layoutToUse.customCss !== undefined && window.location.pathname.indexOf("index") >= 0) { - Utils.LoadCustomCss(state.layoutToUse.customCss) + if (this.state.layoutToUse.customCss !== undefined && window.location.pathname.indexOf("index") >= 0) { + Utils.LoadCustomCss(this.state.layoutToUse.customCss) } } - + public setupClickDialogOnMap(filterViewIsOpened: UIEventSource, state: FeaturePipelineState) { const hasPresets = state.layoutToUse.layers.some(layer => layer.presets.length > 0); @@ -125,7 +128,7 @@ export default class DefaultGUI { private SetupMap() { const state = this.state; - const guiState = this._guiState; + const guiState = this.guiState; // Attach the map state.mainMapObject.SetClass("w-full h-full") @@ -155,7 +158,7 @@ export default class DefaultGUI { private SetupUIElements() { const state = this.state; - const guiState = this._guiState; + const guiState = this.guiState; const self = this new Combine([ @@ -210,8 +213,8 @@ export default class DefaultGUI { } private InitWelcomeMessage(): BaseUIElement { - const isOpened = this._guiState.welcomeMessageIsOpened - const fullOptions = new FullWelcomePaneWithTabs(isOpened, this._guiState.welcomeMessageOpenedTab, this.state); + const isOpened = this.guiState.welcomeMessageIsOpened + const fullOptions = new FullWelcomePaneWithTabs(isOpened, this.guiState.welcomeMessageOpenedTab, this.state); // ?-Button on Desktop, opens panel with close-X. const help = new MapControlButton(Svg.help_svg()); diff --git a/index.ts b/index.ts index ac75022617..355eb5e930 100644 --- a/index.ts +++ b/index.ts @@ -36,7 +36,7 @@ class Init { // This 'leaks' the global state via the window object, useful for debugging // @ts-ignore window.mapcomplete_state = State.state; - new DefaultGUI(State.state, guiState) + new DefaultGUI(State.state, guiState).setup() } } diff --git a/package-lock.json b/package-lock.json index 75394936b1..34bf3624d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "@types/wikidata-sdk": "^6.1.0", "@types/xml2js": "^0.4.9", "country-language": "^0.1.7", - "doctest-ts-improved": "^0.8.5", + "doctest-ts-improved": "^0.8.6", "email-validator": "^2.0.4", "escape-html": "^1.0.3", "geojson2svg": "^1.3.1", @@ -6024,14 +6024,15 @@ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, "node_modules/doctest-ts-improved": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/doctest-ts-improved/-/doctest-ts-improved-0.8.5.tgz", - "integrity": "sha512-4zU8fQV263CU3jAi+K7xohhT9b2ZDGw20M4O7AgzW1IoKklmNkSlHMoKZX6gqN1DAouo08R+MD5aSgACG5ILRw==", + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/doctest-ts-improved/-/doctest-ts-improved-0.8.6.tgz", + "integrity": "sha512-J7fXMJ29ve6DUsUHKEO5bOwGmYjhNZd88L7NMVDKIiLIiUCJ9zkR2k7IZOGjMC0RXw/q788REawcMUgIj+7Muw==", "dependencies": { "@types/chai": "^4.3.0", "chai": "^4.3.6", "global": "^4.3.2", "mocha": "^9.2.2", + "process-yargs-parser": "^2.1.0", "typescript": "^4.6.2" }, "bin": { @@ -12326,6 +12327,11 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "node_modules/process-yargs-parser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/process-yargs-parser/-/process-yargs-parser-2.1.0.tgz", + "integrity": "sha512-tzMsZn3lKksICtEhICR/k+Qv1UmQNVtzm0FaL10OiGJtw0ixgw0woNefcREDc6ZjqXOKBSruRagyULuwZ4FK4Q==" + }, "node_modules/prompt-sync": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/prompt-sync/-/prompt-sync-4.2.0.tgz", @@ -21413,14 +21419,15 @@ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, "doctest-ts-improved": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/doctest-ts-improved/-/doctest-ts-improved-0.8.5.tgz", - "integrity": "sha512-4zU8fQV263CU3jAi+K7xohhT9b2ZDGw20M4O7AgzW1IoKklmNkSlHMoKZX6gqN1DAouo08R+MD5aSgACG5ILRw==", + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/doctest-ts-improved/-/doctest-ts-improved-0.8.6.tgz", + "integrity": "sha512-J7fXMJ29ve6DUsUHKEO5bOwGmYjhNZd88L7NMVDKIiLIiUCJ9zkR2k7IZOGjMC0RXw/q788REawcMUgIj+7Muw==", "requires": { "@types/chai": "^4.3.0", "chai": "^4.3.6", "global": "^4.3.2", "mocha": "^9.2.2", + "process-yargs-parser": "^2.1.0", "typescript": "^4.6.2" }, "dependencies": { @@ -26306,6 +26313,11 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "process-yargs-parser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/process-yargs-parser/-/process-yargs-parser-2.1.0.tgz", + "integrity": "sha512-tzMsZn3lKksICtEhICR/k+Qv1UmQNVtzm0FaL10OiGJtw0ixgw0woNefcREDc6ZjqXOKBSruRagyULuwZ4FK4Q==" + }, "prompt-sync": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/prompt-sync/-/prompt-sync-4.2.0.tgz", diff --git a/package.json b/package.json index 038b46def1..8a84395bcf 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "strttest": "export NODE_OPTIONS=--max_old_space_size=8364 && parcel serve test.html", "watch:css": "tailwindcss -i index.css -o css/index-tailwind-output.css --watch", "generate:css": "tailwindcss -i index.css -o css/index-tailwind-output.css", - "generate:doctests": "doctest-ts-improved .", + "generate:doctests": "doctest-ts-improved . --ignore .*.spec.ts --ignore .*ConfigJson.ts", "test:run-only": "mocha --require ts-node/register --require test/testhooks.ts \"./**/*.doctest.ts\" \"test/*\" \"test/**/*.ts\"", "test": "(npm run generate:doctests 2>&1 | grep -v \"No doctests found in\") && npm run test:run-only && npm run clean:tests", "init": "npm ci && npm run generate && npm run generate:editor-layer-index && npm run generate:layouts && npm run clean", @@ -72,7 +72,7 @@ "@types/wikidata-sdk": "^6.1.0", "@types/xml2js": "^0.4.9", "country-language": "^0.1.7", - "doctest-ts-improved": "^0.8.5", + "doctest-ts-improved": "^0.8.6", "email-validator": "^2.0.4", "escape-html": "^1.0.3", "geojson2svg": "^1.3.1", diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000000..0cd44d3838 --- /dev/null +++ b/tslint.json @@ -0,0 +1,72 @@ +{ + "rules": { + "class-name": false, + "comment-format": [ + true + ], + "curly": false, + "eofline": false, + "forin": false, + "indent": [ + true, + "spaces" + ], + "label-position": true, + "max-line-length": false, + "member-access": false, + "member-ordering": [ + true, + "static-after-instance", + "variables-before-functions" + ], + "no-arg": true, + "no-bitwise": false, + "no-console": false, + "no-construct": true, + "no-debugger": true, + "no-duplicate-variable": true, + "no-empty": false, + "no-eval": true, + "no-inferrable-types": true, + "no-shadowed-variable": true, + "no-string-literal": false, + "no-switch-case-fall-through": true, + "no-trailing-whitespace": true, + "no-unused-expression": true, + "no-use-before-declare": false, + "no-var-keyword": true, + "object-literal-sort-keys": false, + "one-line": [ + true, + "check-open-brace", + "check-catch", + "check-else", + "check-whitespace" + ], + "quotemark": false, + "radix": true, + "semicolon": [ + "always" + ], + "triple-equals": [], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + } + ], + "variable-name": false, + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ] + } +} From 7e2f8b84e8ee64d35fe17beb6a6fe64c7a5dd2c3 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 8 Apr 2022 17:59:39 +0200 Subject: [PATCH 37/37] Bump version number --- Models/Constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Models/Constants.ts b/Models/Constants.ts index acd68fc7e2..117f31cd01 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import {Utils} from "../Utils"; export default class Constants { - public static vNumber = "0.18.0-alpha-3"; + public static vNumber = "0.18.0"; public static ImgurApiKey = '7070e7167f0a25a' public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85"